[Pkg-samba-maint] r3288 - in trunk/openchange: . doc doc/doxygen doc/man/man1 libexchange2ical libmapi libmapi/conf libmapi/socket libmapi++ libmapi++/src libmapi++/tests libmapiadmin libocpf mapiproxy mapiproxy/libmapiproxy mapiproxy/libmapistore mapiproxy/libmapistore/backends mapiproxy/modules mapiproxy/servers/default/emsmdb mapiproxy/servers/default/nspi python/openchange qt qt/demo qt/lib script setup/AD swig/perl swig/perl/tests torture utils utils/backup utils/mapitest utils/mapitest/modules

jelmer at alioth.debian.org jelmer at alioth.debian.org
Thu Feb 11 11:16:28 UTC 2010


Author: jelmer
Date: 2010-02-11 11:16:26 +0000 (Thu, 11 Feb 2010)
New Revision: 3288

Added:
   trunk/openchange/ChangeLog
   trunk/openchange/libexchange2ical/
   trunk/openchange/libexchange2ical/exchange2ical.c
   trunk/openchange/libexchange2ical/exchange2ical.h
   trunk/openchange/libexchange2ical/exchange2ical_component.c
   trunk/openchange/libexchange2ical/exchange2ical_property.c
   trunk/openchange/libexchange2ical/exchange2ical_utils.c
   trunk/openchange/libexchange2ical/ical2exchange.c
   trunk/openchange/libexchange2ical/ical2exchange_property.c
   trunk/openchange/libexchange2ical/libexchange2ical.c
   trunk/openchange/libexchange2ical/libexchange2ical.h
   trunk/openchange/libexchange2ical/libical2exchange.c
   trunk/openchange/libmapi++.pc.in
   trunk/openchange/libmapi++/src/
   trunk/openchange/libmapi++/src/attachment.cpp
   trunk/openchange/libmapi++/src/folder.cpp
   trunk/openchange/libmapi++/src/mapi_exception.cpp
   trunk/openchange/libmapi++/src/message.cpp
   trunk/openchange/libmapi++/src/object.cpp
   trunk/openchange/libmapi++/src/session.cpp
   trunk/openchange/libmapi++/tests/exception_test.cpp
   trunk/openchange/libmapi/conf/codepage-lcid
   trunk/openchange/qt/
   trunk/openchange/qt/demo/
   trunk/openchange/qt/demo/demoapp.cpp
   trunk/openchange/qt/demo/demoapp.h
   trunk/openchange/qt/demo/main.cpp
   trunk/openchange/qt/lib/
   trunk/openchange/qt/lib/foldermodel.cpp
   trunk/openchange/qt/lib/foldermodel.h
   trunk/openchange/qt/lib/messagesmodel.cpp
   trunk/openchange/qt/lib/messagesmodel.h
   trunk/openchange/script/smoketest.sh
   trunk/openchange/utils/exchange2ical_tool.c
   trunk/openchange/utils/mapitest/modules/module_mapidump.c
Removed:
   trunk/openchange/ChangeLog
   trunk/openchange/libmapi++/impl/
   trunk/openchange/libmapi/dlinklist.h
   trunk/openchange/libmapi/tests/
   trunk/openchange/libmapi/utf8_convert.l
   trunk/openchange/libmapi/util/
   trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif
Modified:
   trunk/openchange/Mainpage.doxy
   trunk/openchange/Makefile
   trunk/openchange/README
   trunk/openchange/VERSION
   trunk/openchange/config.mk.in
   trunk/openchange/configure.ac
   trunk/openchange/doc/doxygen/libmapi-examples.doxy
   trunk/openchange/doc/howto.txt
   trunk/openchange/doc/man/man1/exchange2ical.1
   trunk/openchange/doc/man/man1/exchange2mbox.1
   trunk/openchange/doc/man/man1/mapiprofile.1
   trunk/openchange/doc/man/man1/openchangeclient.1
   trunk/openchange/doc/man/man1/openchangepfadmin.1
   trunk/openchange/exchange.idl
   trunk/openchange/libmapi++/attachment.h
   trunk/openchange/libmapi++/folder.h
   trunk/openchange/libmapi++/mapi_exception.h
   trunk/openchange/libmapi++/message.h
   trunk/openchange/libmapi++/message_store.h
   trunk/openchange/libmapi++/object.h
   trunk/openchange/libmapi++/profile.h
   trunk/openchange/libmapi++/property_container.h
   trunk/openchange/libmapi++/session.h
   trunk/openchange/libmapi/Doxyfile.in
   trunk/openchange/libmapi/FXICS.c
   trunk/openchange/libmapi/IABContainer.c
   trunk/openchange/libmapi/IMAPIContainer.c
   trunk/openchange/libmapi/IMAPIFolder.c
   trunk/openchange/libmapi/IMAPIProp.c
   trunk/openchange/libmapi/IMAPISession.c
   trunk/openchange/libmapi/IMAPISupport.c
   trunk/openchange/libmapi/IMAPITable.c
   trunk/openchange/libmapi/IMSProvider.c
   trunk/openchange/libmapi/IMessage.c
   trunk/openchange/libmapi/IMsgStore.c
   trunk/openchange/libmapi/IProfAdmin.c
   trunk/openchange/libmapi/IStoreFolder.c
   trunk/openchange/libmapi/IStream.c
   trunk/openchange/libmapi/IUnknown.c
   trunk/openchange/libmapi/IXPLogon.c
   trunk/openchange/libmapi/cdo_mapi.c
   trunk/openchange/libmapi/conf/build.sh
   trunk/openchange/libmapi/conf/mapi-codes
   trunk/openchange/libmapi/conf/mapi-named-properties
   trunk/openchange/libmapi/conf/mapi-properties
   trunk/openchange/libmapi/conf/mparse.pl
   trunk/openchange/libmapi/emsmdb.c
   trunk/openchange/libmapi/emsmdb.h
   trunk/openchange/libmapi/freebusy.c
   trunk/openchange/libmapi/libmapi.h
   trunk/openchange/libmapi/mapi_notification.h
   trunk/openchange/libmapi/mapi_object.h
   trunk/openchange/libmapi/mapi_profile.h
   trunk/openchange/libmapi/mapidefs.h
   trunk/openchange/libmapi/mapidump.c
   trunk/openchange/libmapi/nspi.c
   trunk/openchange/libmapi/nspi.h
   trunk/openchange/libmapi/property.c
   trunk/openchange/libmapi/simple_mapi.c
   trunk/openchange/libmapi/socket/interface.c
   trunk/openchange/libmapi/socket/netif.c
   trunk/openchange/libmapi/utils.c
   trunk/openchange/libmapi/x500.c
   trunk/openchange/libmapiadmin.pc.in
   trunk/openchange/libmapiadmin/mapiadmin_user.c
   trunk/openchange/libocpf.pc.in
   trunk/openchange/libocpf/Doxyfile.in
   trunk/openchange/libocpf/ocpf_public.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c
   trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
   trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h
   trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c
   trunk/openchange/mapiproxy/modules/mpm_cache.h
   trunk/openchange/mapiproxy/modules/mpm_dummy.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
   trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c
   trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
   trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h
   trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c
   trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c
   trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c
   trunk/openchange/ndr_mapi.c
   trunk/openchange/property.idl
   trunk/openchange/python/openchange/__init__.py
   trunk/openchange/python/openchange/provision.py
   trunk/openchange/script/mkrelease.sh
   trunk/openchange/script/samba4_ver.sh
   trunk/openchange/setup/AD/oc_provision_configuration.ldif
   trunk/openchange/setup/AD/oc_provision_schema.ldif
   trunk/openchange/setup/AD/oc_provision_schema_modify.ldif
   trunk/openchange/swig/perl/mapi.i
   trunk/openchange/swig/perl/tests/fetchmail.pl
   trunk/openchange/torture/exchange_createuser.c
   trunk/openchange/torture/mapi_fetchmail.c
   trunk/openchange/torture/mapi_newmail.c
   trunk/openchange/torture/nspi_profile.c
   trunk/openchange/torture/openchange.c
   trunk/openchange/utils/backup/openchangebackup.h
   trunk/openchange/utils/exchange2mbox.c
   trunk/openchange/utils/mapiprofile.c
   trunk/openchange/utils/mapitest/mapitest.h
   trunk/openchange/utils/mapitest/mapitest_common.c
   trunk/openchange/utils/mapitest/mapitest_print.c
   trunk/openchange/utils/mapitest/mapitest_stat.c
   trunk/openchange/utils/mapitest/mapitest_suite.c
   trunk/openchange/utils/mapitest/module.c
   trunk/openchange/utils/mapitest/modules/mapitest.doxy
   trunk/openchange/utils/mapitest/modules/module_lcid.c
   trunk/openchange/utils/mapitest/modules/module_noserver.c
   trunk/openchange/utils/mapitest/modules/module_nspi.c
   trunk/openchange/utils/mapitest/modules/module_oxcfold.c
   trunk/openchange/utils/mapitest/modules/module_oxcfxics.c
   trunk/openchange/utils/mapitest/modules/module_oxcmsg.c
   trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
   trunk/openchange/utils/mapitest/modules/module_oxcstor.c
   trunk/openchange/utils/mapitest/modules/module_oxctable.c
   trunk/openchange/utils/mapitest/modules/module_oxomsg.c
   trunk/openchange/utils/openchange-tools.c
   trunk/openchange/utils/openchange-tools.h
   trunk/openchange/utils/openchangeclient.c
   trunk/openchange/utils/openchangeclient.h
   trunk/openchange/utils/openchangepfadmin.c
Log:
Merge trunk.

Deleted: trunk/openchange/ChangeLog
===================================================================
--- trunk/openchange/ChangeLog	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/ChangeLog	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,4985 +0,0 @@
-2009-09-20
-    bradh
-	[r1521]
-		Modify mapi_object_set_logon_id() to be able to report errors.
-		
-		Original patch by Erik Hovland, I made some changes.
-
-2009-09-19
-    bradh
-	[r1519]
-		Implement RopReloadCachedInformation (0x10).
-		
-		Minor change to IDL (previously implemented), and adds
-		implementaiton and mapitest code.
-		
-		Also editorial comment fix in some related mapitest stuff.
-		
-		Resolves ticket #186
-	[r1518]
-		Implement GetValidAttachments ROP (0x52).
-		
-		Includes IDL, implementation and mapitest.
-		
-		mapitest also checks DeleteAttach behaviour, which I don't think we previously
-		covered anywhere. 
-		
-		Also includes a comment fix in the mapitest code.
-
-2009-09-16
-    bradh
-	[r1516]
-		Whitespace cleanup.
-		
-		Patch by Erik Hovland <erik at hovland.org>
-
-2009-09-14
-    bradh
-	[r1514]
-		Update the properties list.
-		
-		Patch from Girish Venkatachalam <girish at gayatri-hitech.com>
-
-2009-09-12
-    bradh
-	[r1512]
-		Update API to use MAPITAGS enum.
-	[r1511]
-		Update to match API change.
-	[r1510]
-		Use appropriate enum here.
-	[r1509]
-		Use enum for OpenEmbeddedMessage call.
-	[r1508]
-		Use enums where appropriate.
-	[r1507]
-		Update users of FindRow to use enums.
-	[r1506]
-		We are supposed to be returning a MAPISTATUS, so switch to using 
-		the OPENCHANGE_RETVAL_ERR macro here.
-	[r1505]
-		Use appropriate enums instead of int types.
-	[r1504]
-		Use enums instead of ints / hardcoded values.
-	[r1503]
-		Use enum types where appropriate.
-		
-		Fixes warnings from Intel C compiler.
-	[r1502]
-		Return a suitable MAPISTATUS if we can't talloc sufficient memory here.
-		
-		Fixes warning from Intel compiler.
-
-2009-09-11
-    bradh
-	[r1500]
-		Only pass "-Wmissing-prototypes -Wstrict-prototypes" to CFLAGS,
-		not to CXXFLAGS as well.
-		
-		Avoids g++ warnings.
-	[r1499]
-		Use enumerated type instead of integer.
-	[r1498]
-		Remove unreachable code.
-	[r1497]
-		Add "static" to avoid the need for additional declarations.
-		
-		Avoids noise from the intel c compiler.
-	[r1496]
-		Namespace variable in macro, so we don't get noise about shadowing a
-		declaration of "i"
-	[r1495]
-		Help icc find comparison_fn_t.
-	[r1494]
-		Match up data types in argument and format string.
-	[r1493]
-		Remove unused variable, and change a name to avoid a "shadowed declaration" 
-		warning.
-
-2009-09-10
-    bradh
-	[r1491]
-		Portability fixes for Intel C Compiler.
-		
-		Set CFLAGS early, otherwise AC_PROG_CC will set
-		CFLAGS to "-O2 -g", which later has -O3 appended, which
-		icc complains about.
-		
-		Check if we're really icc, and if so, turn off some warnings.
-		Also turn off the "FORTIFY_SOURCE" define which causes problems
-		with missing builtins.
-		
-		The warnings can (and should) be turned back on later, after we
-		fix the current issues.
-
-2009-09-02
-    bradh
-	[r1489]
-		Correct diagnostics messages.
-
-2009-08-29
-    bradh
-	[r1487]
-		Remove explicit -Wstrict-aliasing=3 from command line.
-		
-		This is implied by gcc -Wall option, and icc produces nuisance warnings
-		with it enabled (related to the -W option, not the code being compiled).
-	[r1486]
-		Fix some memory leaks and a bug in mapiprofile.
-		
-		I introduced the bug in r1467, there could be others that are similar.
-
-2009-08-24
-    bradh
-	[r1484]
-		Minor rewording of description
-	[r1483]
-		Minor cleanups.
-
-2009-08-18
-    bradh
-	[r1477]
-		Move initialisation up, to make sure everything is valid in the failure paths
-		
-		Patch by Erik Hovland. Thanks once again.
-		
-		This closes out ticket #178.
-	[r1476]
-		Remove unreachable code.
-		
-		Patch by Erik Hovland. Thanks again.
-		
-		This is the second part of ticket #177. This completes the checkin of that ticket.
-	[r1475]
-		Remove unreachable code.
-		
-		Patch by Erik Hovland. Thanks very much.
-		
-		This is the first part of ticket #177.
-
-2009-08-17
-    bradh
-	[r1473]
-		Ensure that we check the result of the operation we just performed.
-		
-		Patch by Erik Hovland. Thanks very much for continuing to provide these.
-		
-		This is the third part of the patch in ticket #177. The first two parts are yet to be addressed.
-	[r1472]
-		Make sure that return values are checked and report that given status if there is an error. 
-		
-		Patch from Erik Hovland, with minor additional changes. Thanks again for the patch.
-		
-		Resolves #176.
-	[r1471]
-		More cleanups of memory leaks for setting up database and an associated failure case.
-	[r1468]
-		fix leak in openchangeclient
-		
-		(as seen with valgrind of "openchangeclient -m")
-	[r1467]
-		Fix memory leak in mapiprofile utility
-
-2009-08-14
-    bradh
-	[r1465]
-		Ensure that when we pass --profile to mapitest, that profile
-		gets used instead of the default.
-		
-		Also fix a small memory leak when using --profile, and add some
-		extra comments.
-	[r1464]
-		Fix error handling case.
-		
-		Patch from Erik Hovland - thanks very much.
-		
-		Resolves ticket #175.
-
-2009-08-13
-    bradh
-	[r1461]
-		Remove unused enum values.
-	[r1460]
-		Remove unused code - no simple tests.
-
-2009-08-09
-    bradh
-	[r1454]
-		Update the script version of samba4 to alpha8.
-
-2009-08-05
-    jelmer
-	[r1450]
-		Add tevent to dependencies.
-
-2009-08-03
-    bradh
-	[r1448]
-		Remove unused headers.
-		
-		Patch by Erik Hovland - thanks very much,
-		
-		Resolves ticket #164.
-	[r1447]
-		Apply patch from Erik Hovland, from ticket #162.
-		
-		From the original patch:
-		"The problem is that when you do stat first w/ a file string anyone can
-		exploit the time in between to do whatever they want with the file that
-		the string is a name for. Instead, try to open straight away. Then fstat
-		w/ the file descriptor."
-		
-		I think the patch is fine, although I didn't run the torture test.
-
-2009-08-02
-    bradh
-	[r1444]
-		Avoid duplicate call to mapi_object_get_logon_id
-		
-		Based on a patch proposed by Erik Hovland, but adapted to follow the
-		pattern used in OpenStream().
-		
-		Resolves issue #163.
-	[r1443]
-		Applied modified version of patch from Erik Hovland to address unused variables.
-		
-		See http://trac.openchange.org/attachment/ticket/160/unused-values for
-		the rationale.
-		
-		This resolves #160.
-		
-		My version removes variables (rather than commenting them out) since we don't need
-		them now. I also updated the documentation for options that are no longer available
-		
-		The origin of the unused PR_FOLDER_CHILD_COUNT is a bit strange. It was introduced
-		in r808 (to resolve #103), and looks like it might have been used for debugging - no
-		impact on the code. I pulled out the whole lot.
-		
-		Tested with openchangeclient --fetchmail --folder="Sent Mail" and mapitest.
-	[r1442]
-		Use array form of delete (error identified with libmapixx-attach test, using valgrind).
-	[r1441]
-		Fix potentially unused variable.
-		
-		Tested with mapitest (even though nothing should have been affected) and
-		with libmapixx-test and libmapixx-attach under valgrind.
-		
-		Patch is remaining part of http://trac.openchange.org/ticket/153
-		
-		Thanks to Erik Hovland for the patch.
-
-2009-07-29
-    bradh
-	[r1433]
-		Remove dead / unused code.
-		
-		See http://trac.openchange.org/ticket/152#comment:1 for rationale.
-		
-		Original patch by Erik Hovland - thanks again.
-	[r1432]
-		Update test case to reflect new behaviour
-
-2009-07-18
-    jelmer
-	[r1423]
-		Link libmapistore against tdb.
-	[r1422]
-		Update copies of config.guess and config.sub.
-	[r1421]
-		Link libmapiproxy against tdb.
-	[r1420]
-		Declare a SOVERSION for libmapistore.
-	[r1419]
-		Use LDFLAGS when linking exchange2ical.
-	[r1418]
-		Create symlink for libmapistore.
-	[r1417]
-		Link libmapi against tevent since it uses tevent_context_init, link ndr_exchange.po into libmapiserver since it uses some ndr_push_* symbols.
-	[r1416]
-		Fix typo in variable name.
-
-2009-06-21
-    jelmer
-	[r1365]
-		Fix typo in Python variable name.
-	[r1364]
-		Keep separate flags for libraries around in config.mk.
-	[r1362]
-		Link libmapiserver against all libraries.
-
-2009-06-18
-    jkerihuel
-	[r1357]
-		Add some PidTag* mapping involved with Recipients and RecipientRow
-
-2009-05-28
-    jkerihuel
-	[r1350]
-		Patch from Erik Hovland <erik at hovland.org>:
-		
-		Initializes variables to make sure they aren't used uninitialized.
-		
-		Ref ticket #153
-	[r1349]
-		- Add sanity check on mapitest_common creation routines within
-		  mapitest modules
-		
-		- Apply patch from Erik Hovland <erik at hovland.org>: check return
-		  types.
-	[r1348]
-		Patch From Erik Hovland <erik at hovland.org>
-		
-		In torture_rpc_mapi_sendattach a call is made to the system function
-		read at line 199. The return value of read is assigned to read_size,
-		which happens to be of unsigned type. So if read returns -1 (which it
-		can) it will not be noticed. The patch changes the type to ssize_t
-		(signed) and checks for -1 as well as zero to break out of the loop.
-		
-		Ref ticket #156
-	[r1347]
-		Patch from Erik Hovland <erik at hovland.org>
-		
-		1. In mapiproxy, the directory handle dir will be leaked after it is
-		done being used.
-		2. exchange2mbox main() should use exit at line 785 just like all of
-		the other error paths so that we don't leak anything
-		
-		ref. ticket #157
-	[r1346]
-		Patch from Erik Hovland <erik at hovland.org>
-		
-		Adds a #include config.h to suppress compiler warnings for vasprintf
-	[r1345]
-		Patch from Erik Hovland <erik at hovland.org>:
-		
-		Make sure pointers are valid before dereferencing
-		1. lpProps 'might' be null
-		2. Add folder to variables checked before moving on.
-		4. Check nprop->guid before giving to strcmp, two times
-		6. Check definition before handing to strlen (which will dereference
-		it) Reworked this one to include talloc_free
-		7. Check MessageClass? before handing to strncasecmp
-		8. Check backend, return if null.
-		10. Don't print out anything if lpProp is null
-		11. Check attach_size before dereferencing
-
-2009-05-25
-    jkerihuel
-	[r1343]
-		Fix pull structure for QueryRows reply when no RowData is available
-
-2009-05-07
-    jkerihuel
-	[r1341]
-		- Add preliminary IDL support for Exchange 2003/2007 EMSMDB RPC calls:
-		  * EcDoConnectEx
-		  * EcDoRpcExt2
-		
-		- Add LZxpress and XorMagic support to EcDoRpcExt2 request/reply
-		  blob. However it doesn't yet support Chained calls.
-		
-		- Add AuxInfo/AUX_HEADER structures and IDL
-		
-		- Refactor mapi_request and mapi_response: move obfuscate_data calls
-		  up to the EcDoRpc layer
-
-2009-04-27
-    jkerihuel
-	[r1339]
-		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
-		
-		call ProcessNotification() after each successful 
-		emsmdb_transaction() in all the libmapi calls.
-	[r1338]
-		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
-		
-		Mapi notifications can occurs inside any emsmdb_transaction; currently
-		only the notification send by the server inside the
-		emsmdb_transaction_null() in MonitorNotification() are
-		parsed/processed/delivered to the appropriate callback.
-		
-		To be able to process all the received notifications, the notification
-		structure must comprise the private data to be passed to the
-		notification callback, since in the average mapi call this data is not
-		available. This patch modifies the Subscribe() call and the 
-		mapi_notification structure, adding the private_data parameter (also the 
-		related Subscribe() calls are update)  and add a libmapi call 
-		(DispatchNotifications) to force the notification dispatching in
-		a [quite] non blocking way
-
-2009-04-26
-    jkerihuel
-	[r1336]
-		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
-		
-		ProcessNotification() is ignoring the handle value contained into the
-		processed notifications. This means that if many Subscribe() calls are
-		performed on different folders but with the same flags, all the
-		registered callback are [incorrectly] signaled with each received
-		notification.
-		
-		The attached patch match the handler contained into the notification
-		message against the notification object handle to avoid such
-		replication.
-
-2009-04-23
-    jkerihuel
-	[r1331]
-		Make sure delayed authenication is not called when server mode is enabled
-    bradh
-	[r1333]
-		Update property list to reflect current OAB props.
-		
-		This deletes a few incompatible properties. Cannot determine the history of the PR_MAILBEAT_ props.
-	[r1332]
-		Fix display of Folder ID values (one is filled with ., the other is prefixed with .16 instead of being filled.
-		
-		Also remove duplicate close() of file descriptor.
-	[r1330]
-		Typo fix.
-
-2009-04-22
-    bradh
-	[r1328]
-		Warning fix.
-
-2009-04-21
-    bradh
-	[r1326]
-		Implement RopTransportNewMail (0x51).
-		
-		Includes IDL, libmapi implementation, and basic mapitest coverage.
-		
-		Also fix a few doxygen / formatting things.
-
-2009-04-19
-    jkerihuel
-	[r1324]
-		- Add Redirect buffer support for OpenMsgStore and OpenPublicFolder.
-		This commit fixes the ecWrongServer (0x478) error users encounter
-		while running openchange based software in a clustered Exchange 
-		environment.
-
-2009-04-18
-    bradh
-	[r1322]
-		Implement RopCloneStream (0x3b) and RopWriteAndCommitStream (0x90).
-		
-		Includes IDL, implementation and mapitest tests.
-
-2009-04-17
-    bradh
-	[r1320]
-		Fix Search notifications.
-		
-		MS concurred that the docs are wrong.
-		
-		Patch by Paolo Abeni - thanks very much for the
-		investigation and the patch.
-	[r1319]
-		Update GetStoreState documentation.
-	[r1318]
-		Implement RopSetPropertiesNoReplicate (0x79).
-		
-		IDL was already done. mapitest for DeletePropertiesNoReplicate was
-		reused / updated.
-
-2009-04-16
-    bradh
-	[r1316]
-		Implement (IDL, libmapi, mapitest) RopHardDeleteMessagesAndSubfolders (0x92)
-		
-		Also fix some bugs in mapitest common code, and an incorrect sanity check in CreateFolder().
-
-2009-04-15
-    bradh
-	[r1314]
-		Implement RopHardDeleteMessages (0x91). 
-		
-		Includes IDL, implementation and mapitest.
-    jelmer
-	[r1313]
-		Ignore generated property file.
-
-2009-04-13
-    bradh
-	[r1311]
-		Add PT_ACTIONS to list of data types.
-		
-		Not fully/correctly handled yet.
-
-2009-04-12
-    jkerihuel
-	[r1309]
-		- Add dcerpc_mapiproxy:delegated_auth option 
-		This option delays mapiproxy-remote server authentication when
-		the client sends the first request on a given pipe. This is
-		mandatory in order to have delegated credentials to work.
-		
-		- Factor remote connection into mapiproxy_op_connect
-
-2009-04-11
-    bradh
-	[r1307]
-		Add session state to the notification.
-		Patch by Paolo Abeni - thanks for the investigation and fix.
-		
-		Also remove a stray debug message.
-	[r1306]
-		Add a new mapitest suite for OXCNOTIF (Core Notifications).
-		
-		Add a test to the OXCNOTIF suite based on test case provided by Paolo Abeni.
-
-2009-04-10
-    bradh
-	[r1304]
-		Update IDL for ModifyRules (0x41) and add IDL for 
-		UpdateDeferredActionMessages (0x57).
-		
-		This is a checkpoint commit, pending further investigation
-		into how we handle PtypRestriction and PtypRuleAction.
-
-2009-04-08
-    bradh
-	[r1302]
-		Mapitest cleanups - remove GetLastError(), and other minor edits.
-	[r1301]
-		Implement LockRegionStream and UnlockRegionStream ROPs.
-		
-		These appear to be a relatively recent addition to the 
-		documentation, possibly only used in Exchange 2007 / Outlook
-		2007.
-		
-		This is complete except for testing of whether the locking
-		actually works.
-
-2009-04-06
-    jkerihuel
-	[r1299]
-		Use parent folder full replica ID: 2 bytes instead of 1 byte
-	[r1297]
-		- Add Implementation for Logon redirect response buffer in OpenChange IDL
-		- Update libmapiserver size calculation routine for Logon call to handle this case
-
-2009-03-30
-    jkerihuel
-	[r1293]
-		Add session and logon_id to the list of parameters to copy between objects.
-		This patch fixes a problem in openchangeclient when using the --folder parameter.
-    bradh
-	[r1294]
-		Remove code relating to free'ing the bookmark returned
-		by SetCollapseState. Initial investigations with MS
-		lead me to believe that you can't free that resource.
-		
-		May be more work in this area as investigation continues.
-
-2009-03-25
-    jkerihuel
-	[r1291]
-		Fix memory leaks for functions relying on pull_emsmdb_property
-
-2009-03-16
-    jkerihuel
-	[r1289]
-		Fix emsabp valgrind errors
-
-2009-03-12
-    jkerihuel
-	[r1287]
-		Make it possible to specify a version number for release different
-		from major/minor from configure.ac
-
-2009-03-11
-    jkerihuel
-	[r1285]
-		Make it possible to open and control up to 255 mailboxes within a 
-		single MAPI session.
-		
-		It implements an internal management of a logon_id array at session
-		level + enable transparent transport/copy of current logon_id value
-		among MAPI calls + finally transparently free the logon_id value when
-		the store object (PF or mailbox) is being released.
-	[r1284]
-		- Retrieve recipients from OpenEmbeddedMessage reply
-		- Test the implementation in mapitest
-		- Avoid potential memory leak: steal context for returned ulPropTags.
-
-2009-03-08
-    jkerihuel
-	[r1282]
-		Be more tolerant with Logon request flags
-	[r1281]
-		Set retval to MAPI_E_INVALID_BOOKMARK rather than returning.
-		This case still needs to be fixed though.
-	[r1280]
-		Delete debug message
-	[r1279]
-		Create a default GetProps reply on error
-
-2009-03-06
-    jkerihuel
-	[r1277]
-		Fix retval problem in libmapi/nspi.c for GetIDsFromNames.
-		Function returns MAPI_E_SUCCESS, but errno is set to 0x0000000b.
-		Set errno to retval to work around this problem.
-		
-		
-		NSPI-GETIDSFROMNAMES
-	[r1276]
-		OXCPRPT-NAME-ID mapitest now passes: The QueryNamedProperties ecMemory retval
-		has been worked-around by setting QueryFlags to NoStrings to limite the results
-		scope. This means the MNID_STRING case is not fully checked anymore. We should maybe
-		add additional tests to do full coverage.
-	[r1275]
-		Fix GetNamesFromIDs IDL and implementation.
-		
-		Note: We should probably update the function prototype
-		so it takes a mapi_SPropTagArray rather than a single property.
-    bradh
-	[r1274]
-		Protect against bad results from GetGALTable().
-		
-		Resolves ticket #142
-
-2009-03-04
-    jkerihuel
-	[r1272]
-		Patch from Paolo Abeni: Add sanity check to Subscribe
-		and prevent applications from crashing if notify context 
-		is uninitialized.
-
-2009-03-03
-    jkerihuel
-	[r1270]
-		Ensure NSPI server functions have a valid dcesrv_handle
-	[r1269]
-		Add quick/additional configuration information on how to setup openchange server
-	[r1268]
-		This commit adds a retval check on private data retrieval function and prevents QueryPosition from causing a 
-		segfault when parent object is meant to come from GetContentsTable.
-	[r1267]
-		- Fix NspiGetMatches server reply when specified username is invalid and
-		search fails.
-		- Make use of talloc hierarchy for NspiGetProps properties fetch + fix
-		a talloc_free bug leading to segfault on failure.
-	[r1265]
-		Prevent from registering same mapistore backend multiple times
-    bradh
-	[r1266]
-		Howto updates.
-
-2009-03-02
-    jkerihuel
-	[r1261]
-		Add skeleton for GetRulesTable 
-	[r1258]
-		- return MAPI_E_SUCCESS when QueryRows reply count is 0
-		- Move Reminders from IPM Subtree to Mailbox root
-	[r1257]
-		- Add QueryPosition implementation
-		- Move from offset to numerator/denominator couple for table objects
-		
-		Outlook now opens properly using openchange server and display the
-		mailbox folder list with icons ;-)
-	[r1256]
-		- Add skeletons for Restrict, SortTable, FindRow calls
-		- Introduce emsmdb provider table object
-		- Add preliminary table implementation for system/special folders
-		- Add preliminary implementation of GetHierarchyTable, SetColumns and QueryRows
-		- Improve creation of GetProps reply blob for Mailbox folder
-		- Fix bug in EcRRegisterPushNotification when associated handle is invalid
-		- Remove some usage of ldb_filter and use format string instead 
-		- Update libmapiserver sanity checks and look for error_code != MAPI_E_SUCCESS
-		  so openchange server is able to return failed replies to MAPI clients
-		- Introduce flaggedPropertyRows in libmapiserver_push_property (needed by QueryRows)
-		
-		This commit makes openchange server work with "openchangeclient --mailbox" ;-)
-		
-		Still preliminary but anyway worthwhile enough to be mentioned ...
-	[r1255]
-		- Add a function to count subfolders of a container
-		- Add a function to wrap MAPI tables over openchangedb
-		- Factorize code used to fetch property values from LDB records
-	[r1254]
-		- Add default properties to folder records while provisioning mailbox
-		- Add few more mapping for PR_* to PidTag
-		- Add a new MAPI property to the list
-	[r1253]
-		Avoid openchangeclient --mailbox to segfault when run vs openchange server
-    bradh
-	[r1263]
-		Remove some ldb_filters, and just use varargs into ldb_search
-	[r1262]
-		warning fix for 64-bit arch.
-	[r1260]
-		Revert previous commit.
-	[r1259]
-		Experimental commit to fix build problems resulting
-		from property changes.
-
-2009-03-01
-    jkerihuel
-	[r1251]
-		- Add PidTagDisplayName property to Mailbox object
-		- Add PidTagParentFolderId to all system/special folders
-	[r1250]
-		- handles array depends if a valid mapi_repl exists. This commit
-		  fixes the destructor semantics.
-		- Fix a mapitest segfault encountered while run vs openchange server
-		- Return 1 in SRowSet_propcpy if an error was encountered.
-	[r1249]
-		Fix libmapi stack segfault when MAPI calls returns 
-		with error_code different from MAPI_E_SUCCESS.
-	[r1248]
-		Do not process NSPI request if we can't find the handle
-	[r1247]
-		Remove unnecessary ldb_filter parameter and replace it
-		with ldb_search format string.
-
-2009-02-28
-    jkerihuel
-	[r1245]
-		- GetPropertyIdsFromNames skeleton added
-	[r1244]
-		- Fix how Release replies are handled in mapi_repl[] array
-		- Remove Release size calculation
-		- Fix QueryRows size in libmapiserver
-		- Add a dummy/skeleton GetPropertiesSpecific function for mapistore objects.
-		- GetHierarchyTable skeleton added
-		- SetProperties skeleton added
-		- CreateMessage skeleton added
-		- SaveChangesMessage skeleton added
-		 
-
-2009-02-27
-    jkerihuel
-	[r1241]
-		Set mapi_response to NULL upon init ... just to get sure
-	[r1240]
-		Fix MAPIUninitialize segfault
-    bradh
-	[r1242]
-		Warning fix.
-
-2009-02-26
-    jkerihuel
-	[r1238]
-		- Add skeleton for GetContentsTable Rop
-		- Add skeleton for some [MS-OXCTABL] Rops: SetColumns, SortTable, QueryRows, SeekRows
-		- Add libmapiserver size calculation functions for all the above
-		- Ensure we only set objects parameter if it exists
-		- Return when dcesrv handle is not available
-	[r1236]
-		Merge s4-alpha7 branch back into trunk
-
-2009-02-25
-    jkerihuel
-	[r1227]
-		- Add several PidTag to openchange.ldb folders
-		- Add provisioning convenient function which adds attribute/value pair
-		to a given folder record
-		- Replace existing special folders reference within Inbox with PidTagIpm* tags
-		- Add new PidTag values to mapi-properties
-		- Add a function to libmapiproxy to build a folder EntryID as described in MS-OXODATA
-		- Add a function which builds special properties for openchangedb folders
-		- Add PT_BOOLEAN case to openchangedb folder get property function
-		- Keep a reference to the mailbox username within emsmdb provider context
-		- Create and return a handle in RegisterNotification
-		 
-	[r1226]
-		Improve PT_I8 dump
-	[r1225]
-		Wrong MessageClass size calculation fixed 
-    jelmer
-	[r1229]
-		Remove duplicate _GNU_SOURCE definition (already specified by Makefile)
-	[r1228]
-		Ignore new binary and trial output.
-
-2009-02-24
-    jkerihuel
-	[r1223]
-		- Fix systemfolder value for System/Special folders
-		- Add GetProps support to System/Special folders
-	[r1222]
-		Add auto-generated parser to the ignore list
-	[r1221]
-		- Add auto-generated parser for MAPI property to PidTag mapping
-		- Add some PidTag values
-		- Add a lookup and get property functions on system folders
-	[r1220]
-		- tuple SystemIdx in the dictionnary to workaround the ordering problem
-		- Add ParentFolderId attribute to System Folders
-	[r1217]
-		- Add creation of "Special folders" to mailbox provisioning
-		- Rename fid attribute to PidTagFolderId
-		- Rename name attribute to PidTagDisplayName
-		- Rename ExplicitContainerClass to PidTagContainerClass
-	[r1216]
-		Fix GlobalCount increment
-	[r1215]
-		Fix mailbox provisioning
-    bradh
-	[r1219]
-		Add test for FILETIME structure.
-	[r1218]
-		Update docs for mapiproxy entry.
-    jelmer
-	[r1214]
-		Fix handling of fids.
-2009-02-23
-    jkerihuel
-	[r1208]
-		- Fix openchangedb mailbox hierarchy and introduces subfolders
-		as described in [MS-OXOFOLDS] specifications.
-		- Update openchangedb API to reflect this change.
-	[r1207]
-		Rename private mailbox folder "non_ipm_subtree" to "mailbox_root"
-		to fit with MS-OXOFOLDS specifications.
-	[r1206]
-		- Add provisioning code for GetReceiveFolder defaults
-		- Check if mapistore content repository already exists for the user
-		- Make mailbox creation verbose
-    jelmer
-	[r1213]
-		Fix parentfolder reference.
-	[r1212]
-		Fix syntax error.
-	[r1211]
-		Use recursive call to create folders.
-	[r1210]
-		Simplify list iteration, PEP8, avoid using string exceptions.
-
-2009-02-22
-    jkerihuel
-	[r1204]
-		Fix 'dereferencing type-punned pointer' warnings
-	[r1203]
-		- Add strict-aliasing compiler flags
-		- Fix format string warnings on ubuntu buildbot
-	[r1202]
-		- Add _FORTIFY_SOURCE=2 to the compiler CFLAGS
-		- Fix warnings introduced by -D_FORTIFY_SOURCE
-    bradh
-	[r1201]
-		I might have been a bit hasty with that last commit...
-		
-		Need sqlite3.
-	[r1200]
-		Try harder to find sqlite3.
-		
-		Seems to be in sqlite.pc on Ubuntu.
-	[r1198]
-		Fix warning on 64-bit arch.
-2009-02-21
-    jkerihuel
-	[r1197]
-		- Add RopGetReceiveFolder (0x27) implementation
-		The function respects should respect the semantics and behavior
-		as described in MS-OXCSTOR specifications. However the python's
-		code modification required: add ExplicitMessageClass attributes
-		to folder records is not yet effective.
-		
-		- Add GetReceiveFolder size calculation function to libmapiserver
-		- Add a function to openchangedb API to retrieve the FID/ExplicitMessageClass
-		couple for a given SystemFolder within user's mailbox.
-	[r1196]
-		- Provision scripts: create a mapistore default storage space within ${private}/mapistore/${username}
-		- Provision scripts: add default sqlite:// mapistore URI for system folders
-		- Add mapistore context initialization when calling OpenFolder on SystemFolder
-		- Add mapistore context release for folders in emsmdbp object destructor
-	[r1195]
-		Factorize emsmdbp objects
-		Add emsmdbp_object generic talloc destructor
-    bradh
-	[r1194]
-		Add test for PT_MV_LONG.
-	[r1193]
-		Add tests for PT_I8 and PT_BINARY
-	[r1192]
-		Fix warning about no newline at end of file.
-		
-		Remove most recently added tests from "to be done" list.
-	[r1191]
-		Add a couple more mapi_SPropValue tests.
-
-2009-02-19
-    jkerihuel
-	[r1189]
-		- Initialize mapistore within emsmdb provider context
-		- Add destructors for MAPI handles and mapistore contexts
-		- Remove emsmdbp_ctx memory context structure member and
-		allocate directly with emsmdbp_ctx
-	[r1188]
-		I don't see any good reason why we would pad MAPI replies with some bytes. 
-		I guess it comes from some prehistoric openchange code.
-	[r1187]
-		Fix systemfolder assignment depending on IsSystemFolder value
-	[r1186]
-		- Initialize OpenFolder server reply
-	[r1185]
-		- Wrap TDB connections to mapistore (code from samba4) so
-		multiple instances can open read/write to the same TDB database
-		- Remove static id_mapping_context (replaced with tdb_wrap calls)
-		- Update mapistore linkage rules so mapistore can be used with exchange_emsmdb server
-		- Link mapistore with exchange_emsmdb
-	[r1183]
-		Fix aclocal warning for AC_DEFINE comparison_fn_t
-	[r1182]
-		Remove useless GetProfilePtr from IProfAdmin interface
-		Closes trac ticket #131
-	[r1181]
-		Add missing script - prevent configure from generating warning vs missing file.
-	[r1180]
-		Remove stamp-h1 file during distclean and add it
-		to the ignore list.
-	[r1179]
-		- Add server-side GetReceiveFolder (0x27) skeleton
-	[r1178]
-		Work around the comparison_fn_t redefinition problem
-		between libocpf and ndr.h
-	[r1177]
-		FreeBSD doesn't have time.h daylight global variable
-    bradh
-	[r1184]
-		start testing mapi_SPropValue_array.
-		This also tests some underlying functions.
-
-2009-02-18
-    jkerihuel
-	[r1175]
-		Add comparison_fn_t support to ndr.h
-		This was the latest change require to make openchange compiles under FreeBSD
-		
-		= samba4/openchange FreeBSD support completed =
-
-2009-02-17
-    jkerihuel
-	[r1173]
-		Remove duplicated post_install call
-	[r1172]
-		Add a post_install operation on FreeBSD
-		Make sure pidl is installed properly.
-	[r1171]
-		Patch samba4 tarball so it compiles properly on FreeBSD 7.0
-		Note: this is a dirty hack which needs to be removed in the future
-	[r1170]
-		Install Samba4 correctly although user's PKG_CONFIG_PATH env variable
-		may not be adjusted properly.
-	[r1169]
-		Avoid download samba4 release tarball if already available
-		in current directory.
-	[r1168]
-		- Add test for comparison_fn_t in configure.ac
-		- libocpf auto-generated files include stdlib.h and prevent from
-		having the proper comparison_fn_t typedef. This commit works around this
-		problem and define comparison_fn_t within a private header.
-	[r1165]
-		getline is a stdio GNU_SOURCE extension not available under FreeBSD.
-		Use fgetln instead when it is compiled on this OS.
-	[r1164]
-		FreeBSD doesn't define sighandler_t but sig_t
-	[r1163]
-		Replace open() call with O_DIRECTORY flag (Linux specific) with opendir
-	[r1162]
-		- Add non-default search path /usr/local/{include,lib} to
-		CFLAGS and LDFLAGS when compiling OpenChange under FreeBSD
-		- Make use of LDFLAGS while compiling openchange tools
-    bradh
-	[r1167]
-		A few improvements for property handling.
-		
-		Also add unit tests to verify behaviour is correct.
-		
-		The implementation for the FlatUID (GUID) structure appears broken. Perhaps I'm not using it correctly.
-	[r1166]
-		Microsoft confirmed the LCID is wrong in the spec, and will be updated in the next rev.
-
-2009-02-16
-    jkerihuel
-	[r1160]
-		Check for Flex version < 2.5.35
-		Make sure users can define the FLEX environment variable
-	[r1159]
-		Add automake scripts for AC_CANONICAL_HOST support
-		Needed for FreeBSD OS detection in configure.ac
-
-2009-02-14
-    bradh
-	[r1153]
-		Fix warnings from lexer output.
-	[r1152]
-		Fixes for warnings on 64-bit architectures.
-	[r1151]
-		Fix warning on 64-bit architecture.
-    jelmer
-	[r1157]
-		Add some more tests for openchange.mailbox.
-	[r1156]
-		Fix creation of new mailbox after provision.
-	[r1155]
-		Always use the same URL when connecting to openchangedb.
-	[r1154]
-		Fix arguments to openchangedb_provision.
-
-2009-02-13
-    jkerihuel
-	[r1149]
-		Fix libmapi 64-bit machine cast warnings mentioned in Brad's devel email
-    bradh
-	[r1148]
-		Warning fix for 64-bit arch.
-
-2009-02-12
-    jkerihuel
-	[r1146]
-		Add doxygen definition for RopRelease
-	[r1145]
-		- Add server-side skeleton implementation for RopOpenFolder and RopRegisterNotification
-		- Add preliminary size calculation functions in libmapiserver for the 2 calls above
-		- Fix size bug for serialized requests
-		- Add skeleton case for RopGetPropertiesSpecific on SystemFolders
-		- Make sure the GetProps reply blob is initialized whatever happen
-		- Add a skeleton emsmdbp folder object init function
-
-2009-02-11
-    jkerihuel
-	[r1143]
-		Remove debug strings for GetPropertiesSpecific Rop
-	[r1142]
-		Enable verbose output in server mode - useful during development
-	[r1141]
-		Implement preliminary server-side RopGetPropertiesSpecific call for mailbox object.
-	[r1140]
-		- Fix GetProps blob for PT_BINARY: use SBinary_short instead of Binary_r
-		- Fix GetProps size: subcontext is not added to the fixed size calculation
-	[r1133]
-		- GetPropsSpecific size calculation function added to libmapiserver
-		- Function to create a GetProps reply property blob added to libmapiserver
-    jelmer
-	[r1139]
-		Add tests for provisioning.
-	[r1138]
-		Several cleanups in python code, add tests for schema use.
-	[r1137]
-		Don't clear PYTHONPATH override.
-	[r1136]
-		Remove unused imports, add extra tests.
-	[r1135]
-		Use member variable for Ldb, rather than subclassing.
-	[r1134]
-		Remove print statements to avoid cluttering test output.
-	[r1130]
-		Add simple and incomplete testcase for OpenChangeDB.
-	[r1129]
-		Move wipe of data to mailbox.py, simplify arguments to add_root_mailbox.
-	[r1128]
-		Move adding a server to mailbox.py.
-	[r1127]
-		Move ldif from oc_provision_openchange.ldif into Python.
-	[r1126]
-		Stop providing setup_path to OpenChangeDB, as it's no longer used.
-	[r1125]
-		Avoid using separate LDIF file when creating folder mailboxes.
-	[r1124]
-		Avoid using separate LDIF file when creating mailboxes.
-	[r1123]
-		Avoid passing full names object.
-	[r1122]
-		Add check-python target.
-
-2009-02-10
-    jelmer
-	[r1120]
-		fix openchange_newuser.
-	[r1119]
-		Use SamDB for actual SAM databases, Ldb otherwise.
-	[r1118]
-		Remove unused parameters, don't make parameters optional if they are mandatory.
-	[r1117]
-		remove unused parameters.
-	[r1116]
-		make mailbox object-oriented, remove creds/lp parameters.
-	[r1115]
-		Fix OpenChangeDB syntax.
-
-2009-02-09
-    jkerihuel
-	[r1113]
-		- Add a systemfolder member to the MAPI handle structure to make a difference
-		  between objects managed by mapistore and those stored within openchange.ldb 
-		  (root mailbox folders).
-		
-		- Add opaque functions to set/get private_data and systemfolder to the MAPI 
-		  handles API.
-	[r1112]
-		Minor doxygen fix/improvement
-	[r1109]
-		Add libmapistore object files to the ignore list
-	[r1108]
-		- Add a very preliminary and light libmapistore implementation.
-		mapistore only supplies init/release and add/del backend contexts.
-		This commit also includes a sqlite3 backend skeleton (open/close sqlite db)
-		- A temporary mapistore testing tool has been added locally for implementation checks.
-    jelmer
-	[r1111]
-		Use convenience function for connecting to openchange.ldb.
-	[r1110]
-		Use standard LDB functions - openchange.ldb is not a SAM database.
-
-2009-02-08
-    bradh
-	[r1106]
-		Implement support the SUMMARY language tag.
-	[r1105]
-		Initial checking of libical based exchange2ical code.
-		
-		This has a long way to go, so think of this as more of a checkpoint
-		than a release.
-		
-		See http://sourceforge.net/projects/freeassociation/ for the library, or
-		see if your distro has a package.
-	[r1104]
-		Reduce warnings.
-	[r1103]
-		Add missing parameter to API documentation.
-		
-		Resolves ticket #130.
-	[r1102]
-		API documentation fixes for OpenEmbeddedMessage()
-	[r1101]
-		Implement OpenEmbeddedMessage ROP (0x46).
-		
-		Resolves Ticket #93
-	[r1100]
-		Factor out message creation and message fill actions.
-		
-		Also remove GetLastError() where appropriate.
-	[r1099]
-		Add some API documentation.
-
-2009-02-07
-    jkerihuel
-	[r1097]
-		Update openchangepfadmin description
-		Fix tool relying on libmapiadmin
-    bradh
-	[r1096]
-		Minor code tweak.
-		
-		Fix ticket #132.
-	[r1095]
-		Add more explanation for README
-	[r1094]
-		Reimplement RTF decompression.
-		
-		Add unit tests from MS-OXRTFCP.
-	[r1093]
-		Fix warnings in example code
-	[r1092]
-		Add description for libmapiadmin
-	[r1091]
-		Add description for libmapi / libmapi++
-	[r1090]
-		Start on the directory descriptions.
-	[r1089]
-		doc/ pointers
-2009-02-06
-    bradh
-	[r1088]
-		Add overview. Extracted from API docs.
-	[r1087]
-		Additional docs.
-	[r1084]
-		Outline of README file.
-		
-		(also using this to test buildbot without changing real code)
-2009-02-05
-    jkerihuel
-	[r1081]
-		Add Version field - avoid breaking pkg-config --list-all
-	[r1080]
-		Fix warnings (gcc 4.2.4)
-    jelmer
-	[r1083]
-		Use variable for package version rather than hardcoding it.
-
-2009-02-04
-    jkerihuel
-	[r1078]
-		Fix pc file libs
-
-2009-02-03
-    jkerihuel
-	[r1070]
-		- Add an implementation of the MAPI handles management API. The API
-		  internally uses an in-memory TDB database to keep object hierarchy
-		  and a doubled chained list to associate private data to handles.
-		
-		The API currently provides add, search and delete facilities. Note
-		that while untested, the delete operation is designed to recursively
-		delete children of the 'meant to be deleted' handle.
-		
-		Finally the API doesn't remove TDB records but mark them as free so
-		they can be reused across MAPI session and prevent from handle counter
-		growing indefinitely.
-		
-		- Add a preliminary implementation of the Release call
-		- Add Release size calculation to libmapiserver
-		- Update EMSMDB provider to use MAPI handles API
-    bradh
-	[r1075]
-		Minor api documentation fix.
-	[r1074]
-		Minor API docs fix.
-	[r1073]
-		Minor API docs fix.
-	[r1072]
-		Minor API docs tweak.
-	[r1071]
-		Token commit of tiny API docs fix.
-    jelmer
-	[r1076]
-		Look for GNU make harder (gmake on BSDs).
-
-2009-02-02
-    jkerihuel
-	[r1068]
-		- Add preliminary EMSMDB provider implementation for RopLogon (0xFE)
-		- Add common routines for OpenChange LDB context init and search
-		  within libmapiproxy
-		- Add libmapiserver skeleton with size calculation routine for RopLogon
-		- Change DSO linking dependencies for mapiproxy shared libraries
-		- Propagate _GNU_SOURCE change from libmapi.h to mapiproxy
-2009-02-01
-    jkerihuel
-	[r1067]
-		Remove .po and .o objects within libmapiproxy subdirectory
-	[r1066]
-		Move libmapiproxy into its own directory and rebase mapiproxy headers accordingly
-		Fix make uninstall for AD and profiles directories
-	[r1064]
-		doxygen typo fix
-	[r1063]
-		Add python code and ldif files needed to create and populate the experimental
-		openchange dispatcher database.
-	[r1062]
-		Add 5-Minute configuration documentation for OpenChange server mode
-	[r1061]
-		- Rebase ldif files into sub directories:
-		  * AD for OpenChange AD modifications
-		  * profiles for OpenChange IProfAdmin interface
-		- Makes it easier figuring out LDIF files scope
-		- Prepare setup folder for LDIF openchangedb files integration
-		- Update install/uninstall Makefile rules for ldif files and
-		  make sure everything got removed
-    bradh
-	[r1060]
-		Add forgotten file.
-	[r1059]
-		Add support for short language names (e.g. en-AU) for lcid.
-
-2009-01-31
-    jkerihuel
-	[r1057]
-		Delete deprecated libmapi setup Perl script
-    bradh
-	[r1056]
-		Add summary report for tests.
-	[r1055]
-		Make mapitest return the number of failed tests.
-
-2009-01-29
-    jkerihuel
-	[r1052]
-		- Add pkg-config pc file for libmapiproxy
-		- Improve mapiproxy rules so libmapiproxy gets installed and cleaned properly
-	[r1051]
-		Free memory allocated by the fake subcontext in
-		ndr_pull_mapi_response.
-		
-		This fix saves 300kb of memory and removes 700 loss records while
-		valgrinding mapitest.
-	[r1050]
-		Fix segfault - Add sanity check - when SPropTagArray is NULL in
-		NspiQueryRows request
-	[r1048]
-		Fix openchange_newuser name typo
-	[r1047]
-		Fix server provisioning command line examples
-	[r1045]
-		Fix several libmapi leaks.
-		
-		mapi_response was allocated using emsmdb_ctx->mem_ctx memory context
-		and was not free'd when libmapi function released their
-		context. Furthermore we need to release mapi_response->mapi_repl and
-		mapi_response->handles which are now automatically free'd when
-		mapi_response destructor is called.
-		
-		However note that this fix is not perfect: mapi_response memory is not
-		free'd properly when calls exit with an error.
-		
-		This commit also make use of talloc_steal where necessary to keep
-		returned fields allocated.
-2009-01-28
-    jkerihuel
-	[r1040]
-		Use named context rather than autofree
-	[r1039]
-		Fix memory leak in emsmdb.c: Use a temporary memory context for
-		request and length allocation in emsmdb_transaction.
-		
-		- This removes 827 loss records and approximatively saves 41kb of
-		  memory while valgrinding mapitest
-	[r1038]
-		- Fix memory leak in GetDefaultProfile and GetProfileTable.
-		- Save from 10 loss records while valgrinding mapitest
-		- Developers are now responsible from freeing the GetDefaultProfile
-		  string the function allocates.
-		- Apply changes to all openchange tools.
-	[r1037]
-		Add blackbox subunit tests for mapiprofile tool
-    bradh
-	[r1043]
-		One more trivial fix.
-	[r1042]
-		Typo fixes.
-		
-		(Yep, more trivial changes)
-	[r1041]
-		Fix incorrect LCID for en-CA.
-		
-		(OK, its token, I admit).
-    jelmer
-	[r1044]
-		Don't define _GNU_SOURCE unconditionally.
-2009-01-27
-    jkerihuel
-	[r1036]
-		Prevent mapiproxy from multiple init and modules/server register
-		when an smb client connect to the server (e.g. windows browser or smbclient)
-2009-01-26
-    bradh
-	[r1033]
-		According to [MS-OXOCAL] Section 2.2.1.44.1 
-		"RecurrencePattern Structure", a monthly recurrence
-		also has a Day specific parameter.
-		
-		Add that here.
-    jelmer
-	[r1035]
-		Simply run autogen.sh rather than replicating it inside the Makefile.
-	[r1034]
-		need to run aclocal before autoconf for the pkg-config macros.
-2009-01-25
-    jkerihuel
-	[r1032]
-		Use a autofree context rather than a named one - makes sure memory is free'd when we exit the test.
-		Saves from 4 loss records while valgrind'ing mapitest.
-	[r1031]
-		Use temporary memory context for EcDoConnect.
-		Saves from 20 loss records when valgrind'ing mapitest.
-	[r1030]
-		Free PropertyProblem structures returned by CopyTo.
-	[r1029]
-		Replace deprecated talloc_init calls with talloc_named
-		This commit removes some valgrind loss records talloc_init was responsible for
-	[r1028]
-		Free everything
-		Free everything when running mapitest --list-all.
-		Valgrind however shows a loss record related to talloc_init ...
-    bradh
-	[r1027]
-		Minor Intel C compiler warning fixes.
-	[r1026]
-		Minor apidocs cleanups.
-2009-01-24
-    jkerihuel
-	[r1024]
-		Use double pointer for lp_ctx in GetLoadparmContext assessor
-	[r1023]
-		Fix memory leak in utf8 lexer.
-	[r1022]
-		- Remove custom iconv_convenience from pull_emsmdb_property and use 
-		lp_iconv_convenience on loadparm_context argument instead. 
-		
-		- Change OpenChange libmapi API to reflect this change
-		
-		- Introduce a lp_ctx assessor in libmapi/cdo_mapi.c 
-		(mostly for mapitest modules). libmapi/mapiproxy developers
-		should never have to make use of it.
-		
-		- Remove pointless duplicated call to lp_load_default in MAPIInitialize.
-	[r1021]
-		Free lpProps returned by GetProps, Fix context error in valgrind
-	[r1020]
-		- Fix memory leak bug: release ndr context in pull_emsmdb_property before returning
-		- Terminate SPropValue and SPropTagArray using an element with ulPropTag = 0. This
-		prevent from "invalid read size of 4" messages from valgrind and remove context errors.
-    jelmer
-	[r1025]
-		Don't install mapiproxy if python wasn't found, since 
-		we wouldn't know where to install the provisioning scripts or be able 
-		to use them.
-2009-01-20
-    jkerihuel
-	[r1018]
-		Merge libmapi-0.8 branch r1015 to 1017 into trunk
-	[r1015]
-		** Start libmapi-0.9 COCHRANE development **
-	[r1014]
-		Merge libmapi-0.8 branch changes into trunk
-2009-01-18
-    jkerihuel
-	[r1007]
-		Add python install/uninstall rules to provision rather than mapiproxy-servers
-	[r1006]
-		- Remove server Makefile rules
-		- Remove dead code
-		
-		Note: server and providers have been merged within mapiproxy,
-		so there is no reason keeping this deprecated code.
-2009-01-17
-    jkerihuel
-	[r1005]
-		Undoing change committed in r1004.
-	[r1004]
-		Use .po files instead of .o files for openchange tools
-	[r1003]
-		Add --version to openchange tools
-	[r1002]
-		Add COPYING file with GPLv3 license
-2009-01-16
-    jkerihuel
-	[r1001]
-		- Add RenameProfile function to IProfAdmin API
-		- Remove pointless CopyProfile from IProfAdmin API
-		- Add --rename option to mapiprofile tool
-		- Update man page to reflect this addition
-		
-		(close trac ticket #124)
-	[r1000]
-		Fix libmapi from crashing when mapi_repl is NULL.
-	[r999]
-		Update Samba4 git rev to fix the charcnv segfault met in openchange
-		tools
-    jelmer
-	[r998]
-		Try to find the Samba python modules if they're not installed in the system 
-		python directory.
-2009-01-15
-    jkerihuel
-	[r997]
-		- Fix Subscribe semantic bug and add WholeStore boolean parameter
-		- propagate API change to tools/torture callers
-	[r996]
-		- Add assessor functions to set dumpdata and debug level in libmapi
-		  (SetMAPIDumpData and SetMAPIDebugLevel)
-		- OpenChange tools modified to use these function rather than set these
-		  parameters on their own
-	[r995]
-		- Fix --debuglevel segfault in openchange tools
-		- Enable logging to stdout in MAPIInitialize
-2009-01-14
-    jkerihuel
-	[r994]
-		* OpenChange libmapi function now returns MAPI error instead of -1
-		- use OPENCHANGE_RETVAL_IF instead of MAPI_RETVAL_IF
-		- add doxygen documentation for some missing functions/files
-	[r993]
-		- Missed this event->tevent change in previous commit
-	[r992]
-		- Update openchange to use latest Samba4 master git rev (990491d)
-		- Fix references to tevent_context structures
-		- Fix iconv_convenience init in MAPIInitialize
-		- Remove errorchecks mapitest module warning
-    jelmer
-	[r991]
-		Use tevent_context_init.
-	[r990]
-		Ignore binaries.
-2009-01-13
-    jkerihuel
-	[r989]
-		Some Exchange server (stand-alone) return MAPI_E_LOGON_FAILED when setting EssDN with username rather than
-		using profile's mailbox string directly. This commit fixes the bug.
-	[r988]
-		- Add EcDoConnect and EcDoDisconnect preliminary support to
-		  dcesrv_exchange_emsmdb.c
-		- Add internal session management mechanism to EMSMDB server
-		- Add init and unbind modules function to EMSMDB server
-		- Add emsmdbp_context and session to dcesrv_exchange_emsmdb.h
-    bradh
-	[r987]
-		Fix valgrind errors caused by using free'd memory.
-2009-01-12
-    jkerihuel
-	[r986]
-		Implement 'mapiproxy downgrade' behavior in EMSMDB server and force
-		Outlook to use EcDoConnect (0x0) and EcDoRpc (0x2) rather than 0xA and
-		0xB (opnums using LZ based compression).
-	[r985]
-		- Add Preliminary implementation for RfrGetFQDNFromLegacyDN DS RFR server
-2009-01-11
-    jkerihuel
-	[r984]
-		- Preliminary implementation of NspiGetProps NSPI server function
-		- Makes sure emsabp_tdb_traverse_MId uses the correct dbuf size
-		- Use correct ldb context (users or conf) depending on where MId is
-		  located (on-memory or on-disk)
-		- Add PR_EMS_AB_NETWORK_ADDRESS mapping to emsabp_property
-		
-		*** Outlook is now able to create MAPI profile using OpenChange Server ONLY! ***
-	[r983]
-		- Preliminary implementation of NspiDNToMId NSPI server function
-		- Add emsabp_search_legacyExchangeDN to search for a record given its
-		  legacyExchangeDN attribute.
-	[r982]
-		- Preliminary implementation of NspiQueryRows NSPI server function added
-		- fix a bug in the MID TDB traversal routine: cut dptr to dsize length
-		  rather assuming it is NULL terminated
-		- Add support for "referenced" property tags
-		- Add support for PR_MV_STRING8
-		- Add emsabp_search_dn which search for a DN within AD and return the
-		  associated LDB message
-		- Add PR_EMS_AB_HOME_MDB and PR_EMS_AB_PROXY_ADDRESSES to
-		  emsabp_property array
-	[r981]
-		Prevent from trying to add a NULL element to profile database and segfault on strlen
-	[r980]
-		Prevent x500_get_dn_element from segfaulting when an incorrect DN string parameter is supplied
-	[r979]
-		- Preliminary implementation of NspiGetMatches NSPI server function
-		- Make use of a on-memory TDB database for Ephemeral Entry IDs
-		- Add TDB traversal routines to retrieve DN associated to MId
-		- Move lp_ctx within emsabp_ctx for convenience
-		- Add EphemeralEntryID to Binary_r routine
-		- add emsabp_query (Find attribute matching given property tag and
-		  return associated data)
-		- add emsabp_fetch_attrs which builds a SRow array given a MId and
-		  requested property tags.
-		- add emsabp_search which searches AD given input search criteria
-		- add a preliminary Property Tag to AD attribute mapping + associated
-		  functions in emsabp_property.c
-		
-		Note: This NspiGetMatches is limited to MAILUSER which means we only
-		look for users (located within users.ldb). This limitation will be
-		removed when we have a preliminary working emsmdb server, so we can do
-		more extensive NSPI server tests.
-	[r978]
-		Add sanity check to get_SPropValue_SRowSet, prevents the function
-		from segfault when RowSet is NULL (e.g. crafted NspiQueryRows replies)
-	[r977]
-		Prevent IProfAdmin based code from crashing when a crafted NspiGetMatches reply
-		with NULL ppOutMIds is returned.
-		 
-2009-01-10
-    jkerihuel
-	[r976]
-		- Preliminary NspiGetSpecialTable implementation added to NSPI
-		  server/EMSABP provider: Hierarchy Table supported (required during
-		  profile creation)
-		- add PT_BINARY support for mapidump_SPropValue
-		- fix a bug when PT_STRING8 or PT_UNICODE pointer is set to
-		  MAPI_E_NOT_FOUND
-
-2009-01-06
-    jkerihuel
-	[r974]
-		Add new Display Type values (used by EMSABP provider)
-	[r973]
-		Change DEBUGLEVEL for RfrGetNewDSA
-	[r972]
-		- preliminary implementation of RFR server (RfrGetNewDSA): makes Outlook happy
-		- mapiproxy-servers-install now installs openchange python scripts and ldif file
-2009-01-05
-    jkerihuel
-	[r971]
-		Move auth_serversupplied_info structure from dcesrv_exchange_nsp.h to libmapiproxy.h
-		This structure is required for NTLM_AUTH_IS_OK macro
-	[r969]
-		- Add doxygen comments for all OpenChange server modules
-		- Fix doxygen return value for exchange_nsp
-	[r968]
-		- Add mapiproxy server unbind function and hook in dcesrv_mapiproxy.c
-		- Add exchange handle enum to dcesrv_mapiproxy.h
-		- Add authentication verifier macro to libmapiproxy.h
-		- Add preliminary EMSABP Address Book Provider implementation:
-		  * supports initialization, destructor (talloc)
-		  * implements user and codepage check routines
-		  * retrieve NSPI server GUID
-		- Add NspiBind and NspiUnbind support to dcesrv_exchange_nsp.c
-		- Add internal session mechanism management to NSPI server
-		- Add init and unbind modules function to NSPI server
-		- Add doxygen comments to all dcesrv_exchange_nsp.c functions
-		- Add emsabp_context, session and non-exported Samba structure to dcesrv_exchange_nsp.h
-	[r967]
-		OpenChange configuration schema updated with Addressing schema
-		(Address-Templates, Address-Types and Display-Templates - Exchange 2003 based)
-	[r966]
-		Execute server modules init function when loaded
-    bradh
-	[r965]
-		A few API documentation fixes.
-
-2009-01-04
-    jkerihuel
-	[r963]
-		Add documentation for MAPIProxy 'server mode'
-
-2009-01-02
-    jkerihuel
-	[r961]
-		- Implement mapiproxy server mode architecture
-		- Add server modules management API
-		- Add skeletons for default OpenChange servers (nspi, emsmdb, ds_rfr)
-		- Add temporary provision Makefile rule
-
-2008-12-30
-    jkerihuel
-	[r959]
-		Initial text was correct - rollback
-	[r958]
-		Fix path typo
-    bradh
-	[r957]
-		Ensure that GetLastError() also returns the correct value.
-	[r956]
-		Start changing the MAPI_RETVAL_IF() usage to two new macros:
-		OPENCHANGE_RETVAL_IF() and OPENCHANGE_RETVAL_ERR().
-		
-		simple_mapi.c is the only one converted at this stage.
-		
-		Also added a set of unit tests that verify at least some initial
-		sanity checks.
-	[r955]
-		Remove unreachable code.
-		
-		Partly resolves ticket #124
-
-2008-12-29
-    jkerihuel
-	[r953]
-		Remove references to ldap.h header file - not installed anymore with samba4 git rev openchange uses
-	[r952]
-		mapiproxy documentation update: 3 questions added to FAQ section
-	[r951]
-		Patch from Corentin Chary:
-			- Add PR_CONTENT_FILTER_SCL property to libmapi
-	[r950]
-		- Update openchange to work with samba4 master git rev f308c2f
-		- Replace reference to events.h with tevent.h
-		- Update installsamba4.sh script to reflect latest samba4 compilation changes/requirements 
-
-2008-12-27
-    jkerihuel
-	[r948]
-		Fix mapidump date/month when freebusy period covers end of one year - beginning of next year
-		Update openchangeclient to reflect these changes.
-
-2008-12-24
-    jelmer
-	[r946]
-		Export PKG_CONFIG_PATH if it wasn't exported yet. Patch by Metze
-	[r945]
-		Fix PIC object flags for SWIG build. Patch by metze.
-
-2008-12-21
-    bradh
-	[r943]
-		User %u format specifier for unsigned integer.
-	[r942]
-		Make return value match signature.
-	[r941]
-		Miscellaneous minor cleanups. Mainly making return types
-		match signatues, format conversion (%u for unsigned values) and
-		matching up result variable types (bool instead of enum MAPISTATUS).
-	[r940]
-		Return an enum MAPISTATUS, instead of a bool, to match function signature.
-	[r939]
-		Use %u instead of %d for unsigned values.
-
-2008-12-20
-    bradh
-	[r937]
-		Another minor APIdox edit.
-	[r936]
-		API documentation tweak.
-	[r935]
-		API dox fix.
-	[r934]
-		API dox fix.
-	[r933]
-		Minor apidox fixes.
-	[r932]
-		More apidox triviality.
-	[r931]
-		Trivial APIdox edits.
-	[r930]
-		Supplement the user's PKG_CONFIG_PATH rather than 
-		overriding it.
-    jelmer
-	[r929]
-		Add bindings for GetBestBody(), GetDefaultFolder(), GetDefaultPublicFolder(), AddUserPermission(), ModifyUserPermission().
-	[r928]
-		Add bindings for create_message, delete_messages, get_message_status, set_read_flags.
-	[r927]
-		Add Python bindings for Unsubscribe(), get_task_status(), get_importance(), get_proptag_name(), get_proptag_value(), DeleteFolder(), CreateFolder(), EmptyFolder(), RemoveUserPermissions(), IsMailboxFolder().
-
-2008-12-19
-    jelmer
-	[r925]
-		Actually use pymapi variables in Makefile.
-	[r924]
-		Add configure flags for building and installing Python MAPI bindings (disabled by default).
-
-2008-12-18
-    bradh
-	[r922]
-		Add namespace prefix to scanner.
-
-2008-12-16
-    jkerihuel
-	[r920]
-		- spnego / gssapi_krb5 authentication now available for mapiprofile
-		- add the --realm | -R option
-		- update mapiprofile man page
-
-2008-12-14
-    bradh
-	[r912]
-		Remove entries for --properties and --priority, which have been removed from the openchangeclient utility.
-		
-		Partly fixes #113.
-	[r911]
-		Don't generate / install man3 pages for libmapi++ or mapitest.
-		
-		Resolves ticket #121.
-		
-		Also don't install man3 pages that are just copies of the C implementation files, or just document bugs / todo items.
-    jelmer
-	[r918]
-		Allow retrieving id and session of MAPI objects.
-	[r917]
-		Add MessageStore and Object Python classes, add bindings for OpenMsgStore, OpenUserMailbox, OpenPublicFolder.
-	[r916]
-		Add stubs for Session class.
-	[r915]
-		Add infrastructure for MAPI python module.
-	[r914]
-		Look for python and python-config binaries.
-	[r913]
-		Remove empty directory.
-2008-12-13
-    jkerihuel
-	[r910]
-		Remove obsolete --properties option and related code
-
-2008-12-10
-    jkerihuel
-	[r908]
-		Fix RecipientRow member's order
-
-2008-12-09
-    jkerihuel
-	[r906]
-		- Update to latest samba4 git master revision (3508a66)
-		- Fix references to samr info24 struct
-		- Add support for assoc_group_id proxy
-		- Add support in mapiproxy for bind/alter connections using assoc_group_id
-		- Update mapiproxy documentation
-
-2008-12-07
-    bradh
-	[r904]
-		Improve building. Partially addresses #94.
-		
-		More work required on this as we work on the 
-		portability in the future.
-	[r903]
-		Expose the underlying session.
-
-2008-11-30
-    bradh
-	[r901]
-		Remove unused --priority option.
-	[r900]
-		These offsets / values can be negative, so we shouldn't
-		use unsigned int type to represent them.
-
-2008-11-29
-    jkerihuel
-	[r898]
-		Fix Logon problem for users running Exchange 2k7 in a clustered Exchange environment.
-		
-		This patch first tries to forge EssDN Logon string from "o" and "ou" 
-		attributes stored in the profile. If Logon fails with ecUnknownUser,
-		then try to open the mailbox using the mailbox attribute stored in 
-		the profile.
-
-2008-11-28
-    bradh
-	[r896]
-		Document the --label option.
-
-2008-11-26
-    jkerihuel
-	[r893]
-		Make openchange compile and work against latest samba4 master git rev (58db2be)
-    jelmer
-	[r894]
-		Remove check for unused type 'uint_t'.
-
-2008-11-22
-    bradh
-	[r888]
-		More tweaks on the openchangeclient man1 page.
-	[r887]
-		More updates for man1 page for openchangeclient.
-		Still doesn't fully address #113.
-	[r886]
-		Update the openchangeclient man1 page.
-		
-		Partly addresses ticket #113.
-		
-		There is still some work to do on this.
-	[r885]
-		Fix a typo, and try to make the descriptions more
-		consistent.
-
-2008-11-21
-    bradh
-	[r883]
-		Initial version of man1 page for mapitest
-	[r882]
-		Initial man1 page for exchange2ical utility.
-
-2008-11-14
-    bradh
-	[r879]
-		Update man1 page for openchangepfadmin
-	[r878]
-		Minor updates for the man pages.
-
-2008-11-13
-    jkerihuel
-	[r875]
-		Fix build errors: wrong number of arguments for ocpf_propvalue
-	[r874]
-		Fix warnings when compiling with -Wextra
-	[r873]
-		Fix warnings when compiling with -Wextra
-	[r872]
-		Fix warnings when compiling with -Wextra
-    bradh
-	[r876]
-		Complete initializers here.
-
-2008-11-10
-    bradh
-	[r870]
-		Update to reflect latest state of mapiprofile.
-
-2008-11-09
-    bradh
-	[r868]
-		Prevent segfault when running mapitest. Looks like the we can
-		return MAPI_E_SUCCESS even if one of the property values is
-		MAPI_E_NOTFOUND. That error then get turned into a char*, and
-		strncmp faults.
-		
-		Also fix a possible bug relating to operator precedence, and 
-		a couple of warnings (one for signed / unsigned comparison, and
-		the other for an unsigned value never being less than zero).
-
-2008-11-08
-    bradh
-	[r866]
-		Enable output to stdout.
-		
-		Resolves ticket #106.
-		
-		Thanks to raboof for the report and fix.
-
-2008-11-07
-    bradh
-	[r864]
-		Fix missing initialisers (issue #110).
-		
-		Also fix some signed/unsigned warnings.
-	[r863]
-		Fix problems with incorrect initialisers (#110) and
-		operator precedence.
-		
-		Also fix a couple of places with signed/unsigned confusion.
-	[r862]
-		Partial fix for issue #110, and a couple of very minor cleanups.
-
-2008-11-06
-    bradh
-	[r860]
-		Minor cleanups.
-	[r859]
-		We probably want to return here, not do nothing.
-
-2008-11-05
-    jkerihuel
-	[r855]
-		Fix empty patch function problem: add a retval
-    bradh
-	[r857]
-		Typo fix.
-	[r856]
-		Explain the boost-thread trick.
-	[r854]
-		Minor documentation tweaks.
-
-2008-11-04
-    jkerihuel
-	[r852]
-		- remove usage of global_loadparm in libmapiadmin
-		- make use of session context rather than global_mapi_ctx in libmapiadmin
-		- use local context rather than mapiadmin context in libmapiadmin
-		- libmapiadmin now uses ldb helper rather than raw implementation (ldb async code)
-		- libmapiadmin and openchangepfadmin now works again (user creation/deletion) !! ;-)
-		- remove global_loadparm in torture test and replace it with torture context
-		- fix dcerpc_init to match latest samba4 API
-		- update samba4 version required to build openchange
-    bradh
-	[r850]
-		More API documentation tweaks.
-	[r849]
-		More API documentation tweaks.
-	[r848]
-		Some API dox fixes for libmapi++.
-    jelmer
-	[r851]
-		Remove unnecessary patching of lib/events/events.h.
-
-2008-11-03
-    bradh
-	[r846]
-		Update to a more recent Samba4.
-    jelmer
-	[r845]
-		Remove some usages of deprecated global_loadparm.
-	[r844]
-		Cope with new argument to dcerpc_log_packet().
-
-2008-11-01
-    jelmer
-	[r842]
-		Fix includes for DEBUG(), fix some more warnings.
-	[r841]
-		Use same_net_v4 rather than deprecated same_net().
-	[r840]
-		Fix Samba 4 git revision.
-	[r839]
-		Fix includes - debug.h can only be included once.
-	[r838]
-		Include debug header.
-	[r837]
-		Cope with API changes in Samba functions.
-	[r836]
-		Use new function is_zero_ip_v4 rather than removed is_zero_ip.
-
-2008-10-31
-    jkerihuel
-	[r833]
-		Fix OpenMsgStore binding in swig perl and fetchmail script
-
-2008-10-21
-    jkerihuel
-	[r824]
-		Fix pointless const definition for GetFreeBusyYear return type
-2008-10-20
-    jkerihuel
-	[r823]
-		- Add the IsFreeBusyConflict convenient function which checks if a
-		  given date conflicts with existing FreeBusy Busy/OOF events
-		
-		- Modify openchangeclient --sendappointment behavior to check whether
-		  start or end date conflicts with FreeBusy published data for the
-		  user.
-		
-		- Add the --force option to openchangeclient to override this behavior
-		
-		- Fix a counter bug in mapidump_freebusy_events
-	[r821]
-		Fix doxygen typo error
-	[r820]
-		- Add GetUserFreeBusyData convenient function which retrieves FreeBusy
-		  data in public folders for a given user. Note: Ambiguous name is not
-		  supported at the moment.
-		
-		- Add convenient FreeBusy mapidump routines
-		
-		- Add FreeBusy read support to openchangelient
-		
-		- Add PT_MV_LONG and PT_MV_BINARY support to pull_emsmdb_property and
-		  property.c functions
-		
-		- Add OpenUserMailbox which let developers open other mailboxes
-		  instead of the default profile one.
-		
-		- Add GetABRecipientInfo: convenient function which retrieves Address
-		  Book information for a given recipient
-
-2008-10-17
-    jkerihuel
-	[r818]
-		- Add libmapi implementation for DeletePropertiesNoReplicate
-		- Add mapitest test units for DeleteProps and DeletePropertiesNoReplicate
-	[r817]
-		Fix doxygen documentation
-
-2008-10-16
-    jkerihuel
-	[r815]
-		- Implement multisession into libmapi
-		- Update openchange tools and suite to reflect these changes
-		- Fix SRow_addprop behavior
-		
-		NOTE: OpenMsgStore, ResolveNames, GetGALTable and RFR functions
-		now take a mapi_session parameter.
-    jelmer
-	[r814]
-		Use my openchange.org email address.
-
-2008-10-09
-    jkerihuel
-	[r812]
-		- Add a session management API for mapiproxy modules. Similar code
-		  already existed for mpm_cache module. Common functions are now
-		  available to all mapiproxy modules through libmapiproxy
-		
-		- replace smbd with samba in mapiproxy documentation
-	[r811]
-		- Cache calendar, contact, journal, note, task and drafts folders IDs
-		  when GetDefaultFolder call is performed on one of these folders and
-		  keep them until obj_store is released.
-		
-		- Add a reverse lookup routine which says whether a given FID belongs
-		  to a default folder and which olFolderType it is.
-	[r810]
-		- Remove pointless memory context in GetDefaultFolder
-		- Move entryID to FID code into a separated routine (GetFIDFromEntryID)
-	[r809]
-		Restore install rule for mapi profiles ldif files in
-		libmapi-installscript. Fix the MAPI_E_NO_ACCESS bug when mapiprofile
-		tries to create a new mapi profile store.
-2008-10-08
-    jkerihuel
-	[r808]
-		- Ticket #103 resolved. openchangeclient can now perform custom folder lookup, fetch, mkdir and rmdir.
-		- mapi_object_copy routine added to mapi_object.c
-
-2008-10-06
-    jkerihuel
-	[r806]
-		Fix missing Month field in LogonTime structure
-2008-10-05
-    jkerihuel
-	[r805]
-		propagate IDL warning fix to property.idl
-    jelmer
-	[r804]
-		Add target for building python API documentation.
-2008-10-01
-    jkerihuel
-	[r802]
-		Fix samba4 release and git revision
-	[r801]
-		Fix installsamba4.sh script paths
-    jelmer
-	[r803]
-		Avoid warning.
-	[r800]
-		Install OpenChange python modules.
-	[r799]
-		Check for python dir during configure.
-	[r798]
-		ignore generated files.
-	[r797]
-		Stop installing js files.
-	[r796]
-		Use autoconf cache prefix.
-	[r795]
-		Use newer version of Samba 4.
-2008-09-30
-    jkerihuel
-	[r791]
-		Remove dcesrv_exchange.so from server Makefile rule and
-		move mapiproxy from TOOLS to SERVER.
-		
-		dcesrv_exchange and providers Makefile rules are orphan, planned
-		to be removed (with their associated code) when emsabp merge process 
-		into mapiproxy is over.
-2008-09-23
-    bradh
-	[r790]
-		Export the Binary_r structure.
-2008-09-22
-    bradh
-	[r789]
-		Use more descriptive variable names in messages example code.
-	[r788]
-		Add a description of messages to libmapi++ API documentation.
-	[r787]
-		Add messages binary to the ignore list.
-	[r786]
-		Add new example showing libmapi++ message handling, and
-		associated API documentation and build system changes.
-2008-09-21
-    bradh
-	[r785]
-		Update the API documentation main page for libmapi++
-2008-09-19
-    jkerihuel
-	[r784]
-		Add foldertree binary to the ignore list
-	[r783]
-		- Add missing Input parameter
-		- Add sanity check on ppNames
-		- Fix ticket #102
-	[r781]
-		- Fix a bug in NspiUpdateStat: make plDelta mandatory and use it for in,out
-		- Add a NspiGetSpecialTable test for Address Creation Template
-    bradh
-	[r780]
-		Fix valgrind-reported error, per ticket #101.
-	[r779]
-		Make sure we clean up after mapitest runs.
-		
-		Resolves ticket #84
-2008-09-17
-    jkerihuel
-	[r778]
-		- Add msExchUserAccountControl attribute to extended user record
-		- openchange_newuser can now create/enable/disable an OpenChange account
-	[r776]
-		Exit the test if the WriteStream operation fails
-	[r773]
-		Fix ncacn_ip_tcp binding string for OpenChange server object
-	[r772]
-		With new NSPI IDL, using cValues - 1 is incorrect and lead to errors. Use cValues directly instead
-	[r771]
-		Fix pipe function check and use ndr autogenerated defines rather than static strings
-		Fix calls to NspiDNToMId
-    bradh
-	[r774]
-		Make sure we set the body and body format properties, to
-		ensure that the message is shown correctly with 
-		openchangeclient -F.
-2008-09-16
-    jkerihuel
-	[r770]
-		- Fix provisioning
-		- Rename oc_* python scripts to openchange_*
-		- Add Full Exchange 2003 schema (classes and attributes)
-		- Full Exchange 2003 modified classes and attributes support 
-		- Add prefixmap OID for some Exchange classes and attributes
-		- Add missing ADSC classes and attributes
-		- Improve configuration LDIF file with new objects
-		
-		NOTE: provision.py should find a way to handle firstorg properly
-		NOTE: oc_provision_configuration.ldif is still incomplete
-    bradh
-	[r768]
-		API documentation improvements.
-2008-09-15
-    bradh
-	[r767]
-		Add an example to the libmapi++ documentation, and 
-		the right build magic and doxygen linkage.
-	[r766]
-		Minor API documentation fix
-2008-09-14
-    bradh
-	[r765]
-		Add forgotten part of API documentation fixes for mapitest.
-	[r764]
-		Improve mapitest API documentation.
-2008-09-13
-    bradh
-	[r763]
-		Use new DeleteFolder flags to clean up folders on deletion.
-		
-		This doesn't completely resolve ticket #84, but it does help.
-	[r762]
-		Ignore API documentation.
-	[r761]
-		Add Doxyfile to ignore list.
-	[r760]
-		Add initial support for Doxygen API documentation
-		for libmapiadmin.
-2008-09-12
-    bradh
-	[r759]
-		Implement the remainder of the standard public folders.
-2008-09-10
-    bradh
-	[r758]
-		Only do header line removal at the start of the file
-		(lines 20 through 40 seems like a good compromise).
-	[r757]
-		libmapi++ is C++, not C, so we should not optimise
-		Doxygen output for C.
-2008-09-09
-    jkerihuel
-	[r755]
-		- Update the Logon_repl IDL (0xFE) and implementation
-		- Add new folders to the mapi_obj_store for PF folders
-		- rename pf_finder to pf_search 
-    bradh
-	[r756]
-		Suppress some more unwanted headers.
-2008-09-08
-    jkerihuel
-	[r754]
-		- Add GetStoreState (0x7b) IDL, implementation and mapitest unit
-	[r753]
-		Fix typo error
-	[r752]
-		- Update the EmptyFolder IDL
-	[r751]
-		- Update the SearchFlags enum, GetSearchCriteria and SetSearchCriteria IDL
-		- Add mapitest units for GetSearchCriteria and SetSearchCriteria
-	[r750]
-		Link libmapi++ documentation to main apidocs page
-	[r749]
-		Update GetAttachmentTable IDL and remove the unknown field
-	[r748]
-		- Update DeleteFolder IDL and implementation
-		- It now supports DeleteFolderFlags as input parameter and can return the ParticalCompletion state
-		- Sanity checks added at the beginning of the function
-	[r747]
-		- Rename GetRowCount to QueryPosition
-		- IDL, implementation, documentation and openchange code updated
-		- ActionType enum fields prefixed with 'ActionType_'. Original
-		values were causing conflicts while building Perl bindings with
-		'i386-linux-thread-multi/CORE/opnames.h where OP_DELETE was already defined'
-	[r746]
-		Change enum SaveFlags to uint8_t for doxygen documentation to be generated properly
-	[r743]
-		- Update SaveChangesMessage IDL and implementation
-		- Add a SaveFlags parameter to SaveChangesMessage function
-		- update openchange code to reflect this change
-    bradh
-	[r745]
-		Build fix / fix for ticket #99.
-	[r744]
-		Filter out some new #include lines.
-		
-		This needs to be applied to other modules too.
-2008-09-07
-    jkerihuel
-	[r742]
-		Update SRow and SRowSet IDL
-	[r741]
-		Delete obsolete input_locale and instance_key structures
-	[r740]
-		Fix WStringArray_r IDL
-	[r739]
-		- Move from MV_UNICODE_STRUCT and LPWSTR to WStringArray
-		- LPWSTR structure removed
-	[r738]
-		Rename SDateTimeArray to DateTimeArray_r
-	[r737]
-		Rename SGuidArray to FlatUIDArray_r and fix the IDL
-	[r736]
-		Rename MV_LONG_STRUCT to LongArray_r
-	[r735]
-		Rename SBinary to Binary_r
-	[r734]
-		- Add removal of libmapi++ Doxyfile in make distclean rule
-		- Add Doxyfile to svn:ignore 
-	[r733]
-		Rename SShortArray to ShortArray_r
-	[r732]
-		- Move from SLPSTRArray to StringArray_r
-		- LPSTR structure removed
-	[r731]
-		Rename MAPIUID to FlatUID_r
-	[r730]
-		Fix lexer warnings during compilation (ticket #100)
-	[r729]
-		- Update the EcDoConnect IDL (ref. ticket #99)
-		- Add new fields to the emsmdb info structure
-		- Add doxygen comments to libmapi/emsmdb.c
-    bradh
-	[r728]
-		Reduce warnings when compiling with 64-bit arch.
-	[r727]
-		Initial checkin of infrastructure for libmapi++ API documentation.
-2008-09-06
-    jkerihuel
-	[r726]
-		- MAJOR NSPI protocol and libmapi stack update
-		- All NSPI protocol functions implemented
-		- NSPI stack fully documented
-		- NspiGetHierarchyInfo renamed to NspiGetSpecialTable
-		- NspiDNToEph renamed to NspiDNToMId
-		- instance_key removed from nspi_context and set as a parameter to NSPI functions
-		- SPropertyRestriction renamed to PropertyRestriction_r
-		- FlagList structure removed and replaced by a SPropTagArray
-		- MAPI_SETTINGS removed and replaced by a STAT structure
-		- new MAPI property tags added to libmapi/conf/mapi-properties
-		- NSPI module added to mapitest
-    bradh
-	[r725]
-		Clean up on failure.
-	[r724]
-		Clean up on failure.
-	[r723]
-		Minor improvements to ensure cleanup on failure.
-	[r722]
-		API documentation fix
-	[r721]
-		API documentation fix.
-	[r720]
-		API documentation fix.
-	[r719]
-		API documentation fix.
-	[r718]
-		API documentation fixes.
-2008-09-05
-    bradh
-	[r717]
-		API documentation fixes.
-2008-09-04
-    jkerihuel
-	[r716]
-		Fix EMSMDB 0xb function name
-	[r715]
-		- update EcRRegisterPushNotification IDL
-		- update Notify IDL
-		- implement complete MAPI notifications
-		- update libmapi to reflect these changes
-		- make openchangeclient prints a brief summary for each notification found
-		- update ulEventMask used in openchangeclient
-2008-09-03
-    jkerihuel
-	[r714]
-		- Rename Advise MAPI call to RegisterNotification
-		- Update RegisterNotification IDL and implementation
-2008-09-02
-    jkerihuel
-	[r713]
-		- Fix Restrict IDL and implementation
-		- Add a new parameter to the Restrict function
-		- close ticket #32
-	[r712]
-		Add mapi_nameid.h to the ignore list
-	[r711]
-		- Replace libmapi/mapi_nameid.h with a generated mparse file
-		- Add a mapi_nameid.h parser to mparse.pl
-		- Add canonical names for named properties
-		- GetProps and SetProps resolves named properties if they exist
-		- named properties can now be set directly and make mapi_nameid API be
-		  optional.
-		- replace named property tags hex value with their canonimal names
-		- replace several use of the mapi_nameid API with smaller code
-	[r710]
-		- Add new IDL file (property.idl) to push/pull structures from binary
-		  blobs and not directly related to any MAPI calls. Include the
-		  generated property.h file into libmapi.h
-		
-		- Add PT_MV_STRING8 support in pull_emsmdb_property (GetProps reply
-		  parsing) and mapidump_SPropValue
-		
-		- Add functions to property.c to retrieve RecurrencePattern,
-		  TimeZoneStruct and GlobalObjectId structures (see property.idl).
-		
-		- add a preliminary version of exchange2ical tool. This version only
-		  dumps calendar folder appointments into ICS file on standard output.
-2008-08-30
-    jkerihuel
-	[r709]
-		- Update mapi-nameid-properties with a more complete set of properties
-		- Add a header to mapi-nameid-properties for sanity purposes
-		- Move named properties with PT_STRING8 type to PT_UNICODE
-		- update openchange code to reflect these changes
-		- Add PSETID_Attachment to mapidefs.h
-2008-08-28
-    jkerihuel
-	[r707]
-		Add missing check on password for the create command
-	[r706]
-		Fix incorrect usage of realm in mapiproxy
-2008-08-27
-    jkerihuel
-	[r705]
-		Check for provider_rpc_connection retval for RFR functions.
-	[r704]
-		Update Doxyfile to parse mapiproxy/modules files and
-		include documentation on static functions.
-	[r703]
-		- Add NSPI hook on NspiQueryRows and NspiDNToEph and replace the
-		  Exchange server name with mapiproxy one.
-		- documentation updated to reflect these changes
-		- new FAQ question added
-		- developer documentation improved
-	[r702]
-		Add the RFR mapiproxy file.
-	[r701]
-		- Implement RfrGetNewDSA DN replacement in mapiproxy
-		- use lp_realm rather than sockaddr in NspiGetProps (FQDN rather than IP address)
-		- update mapiproxy documentation to reflect these changes
-2008-08-26
-    jkerihuel
-	[r698]
-		- Add implementation of the NSPI Referral protocol (exchangeRFR)
-		- update dcesrv_exchange and mapiproxy prototypes for RFR
-		- add references to the RFR pipe in mapiproxy
-		- prefix NSPI client connections with a RfrGetNewDSA call
-		- add RFR functions implementation in libmapi/IMSProvider.c
-		- add a --getfqdn option to mapiprofile
-		- fix a minor mapiprofile option parsing bug
-2008-08-25
-    jkerihuel
-	[r697]
-		Fix mapiproxy dummy module unbind prototype
-	[r696]
-		- Remove flags in EcDoRpc top function, fix compilation vs latest samba4-git version
-		- EcDoRpc indent updated
-2008-08-15
-    clsk
-	[r694]
-		Get rid of initialization order warning
-2008-08-11
-    jkerihuel
-	[r691]
-		- add unbind hook for mapiproxy
-		- add ahead mapiproxy mode
-		- add read ahead in cache module
-		- add synchronization mechanism in cache module
-		- update mapiproxy documentation to reflect these changes
-2008-08-08
-    bradh
-	[r690]
-		Temporarily comment out installation of files removed
-		in r683.
-2008-08-01
-    jelmer
-	[r685]
-		Fix arguments, paths in provision scripts.
-	[r683]
-		Merge python provision/newuser scripts.
-	[r681]
-		Simplify installation of manpages a bit.
-2008-07-29
-    jkerihuel
-	[r679]
-		Add configure check for libboost-thread. Add libmapi++ to the build
-		only if it is available.
-2008-07-27
-    clsk
-	[r678]
-		- session constructor doesn't login to the server anymore, it calls MAPIInitialize().
-		- Created session::login() members.
-		- test applications use default profile.
-2008-07-26
-    jkerihuel
-	[r676]
-		- Import Alan Alvarez work from libmapi++ into trunk
-		- Add a g++ check in configure.ac: don't call libmapi++ rules if g++
-		  is missing
-		- Add libmapi++ to the build system
-		- Add a patch function to installsamba4.sh: rename private to
-		  private_data in samba4 events.h header file
-		- Change #include directives so it uses <libmapi++ ... rather than
-		  relative paths.
-2008-07-24
-    jkerihuel
-	[r674]
-		- Add a statitic function monitoring streams over OpenStream and Last
-		  ReadStream operations. Monitoring stream Release is not relevant
-		  since Outlook does not close the handle directly after last
-		  ReadStream operation. Should put in evidence difference between
-		  non-cached(1st retrieval) and cached (further retrieval).
-		
-		- Fix a few memory leaks
-2008-07-23
-    jkerihuel
-	[r672]
-		- Commit initial revision for the mapiproxy cache module
-		- Update mapiproxy hook API for the dispatch routine
-		- Introduce the mapiproxy structure for modules to control top-level
-		  mapiproxy behavior.
-		- Update mapiproxy documentation to reflect these changes
-2008-07-21
-    jkerihuel
-	[r670]
-		* Fix remaining ByteRead parameter size for ReadStream operations.
-2008-07-20
-    jkerihuel
-	[r669]
-		* Improve/Update Open/Read/WriteStream IDLs
-		* Fix ByteRead parameter size for ReadStream operation.
-2008-07-19
-    jkerihuel
-	[r668]
-		Improve OpenAttach, CreateAttach and DeleteAttach IDL - remove unknown
-		parameters.
-	[r667]
-		Propagate r666 changes to OpenMsgStore and fix build
-    bradh
-	[r666]
-		Minor rename of bitmap value to avoid conflict with
-		Private as a class name.
-2008-07-17
-    jkerihuel
-	[r663]
-		Minor change: remove old debugging string from mapitest
-	[r660]
-		Fix incorrect header
-	[r658]
-		Remove deprecated mapi_handles API
-    bradh
-	[r665]
-		Initial checkin of some uno (static checker) support
-		files.
-		
-		There will be a script to run uno with the right options,
-		but that requires more work.
-2008-07-16
-    jkerihuel
-	[r655]
-		Fix OXOMSG-ABORT-SUBMIT return value and return success when expected
-		error values (MAPI_E_UNABLE_TO_ABORT, ecNoDelSubmitMsg) are encountered.
-	[r654]
-		- Call mapi_object_release in GetDefaultFolder
-		- Remove pointless references to mapi_object_t
-    bradh
-	[r656]
-		Fix little memory leak.
-2008-07-15
-    jkerihuel
-	[r653]
-		Fix invalid OpenFolder calls in mapitest modules
-	[r652]
-		Remove references to SaveChanges in doxygen see also statement
-	[r651]
-		- Rename SaveChanges to SaveChangesAttachment (0x25)
-		- Update SaveChangesAttachment IDL
-		- Update references to SaveChanges
-	[r650]
-		- Fix the huge memory leak described in Ticket #91
-		- Rewrite the mapitest NameID test to use the mapi_nameid convenient
-		  API
-2008-07-12
-    jkerihuel
-	[r648]
-		- Add mapi_get_errstr auto-generated routine which returns the MAPI
-		  retval as a string
-		- Add print routine for MAPI retval in mapitest
-		- Add a color mode (--color) which prints either green or red MAPISTATUS
-		- Update mapitest modules to use these new routines
-    bradh
-	[r647]
-		Minor API documentation fix.
-2008-07-11
-    jkerihuel
-	[r646]
-		Add all MAPI errors
-	[r645]
-		- Add GetOwningServers (0x42) implementation (IDL + libmapi + mapitest)
-	[r644]
-		- Report and make consistent usage of PropertyProblem in the IDL:
-		  SetProps, DeleteProps and CopyProperties
-		
-		- Remove unknown field in GetProps and GetPropsAll and replace them
-		  with the correct IDL mapping.
-		
-		- Add IDL for SetPropertiesNoReplicate (0x79) MAPI call
-		
-		- Minor typo fix in IMAPIProp.c
-	[r643]
-		Improve CreateMessage request IDL
-	[r642]
-		Improve OpenMessage response IDL
-	[r641]
-		- Add PublicFolderIsGhosted (0x45) MAPI call (IDL + libmapi + mapitest)
-		
-		- Improve OpenFolder, CreateFolder and OpenPublicFolderByName response
-		  IDL: make these call able to check whether the folder is ghosted or
-		  not.
-	[r640]
-		Revert emsmdb pipe version to the hacked one. Makes mapiproxy work with samba4-alpha5 release.
-	[r639]
-		SeekRow and SeekRowBookmark IDL improved
-	[r638]
-		Improve the SetColumns IDL: remove unknown fields
-2008-07-06
-    jkerihuel
-	[r637]
-		Minor code convention fix
-	[r636]
-		Check NTSTATUS return value from dcerpc_ndr_request. Prevent mapiproxy
-		from segfault when invalid dcerpc response is received.
-	[r635]
-		Expose MAPISTATUS error in OXCTABLE-CATEGORY::FreeBookmark. 
-		Requires investigation
-    bradh
-	[r634]
-		Implement GetIdFromLongTermId and GetLongTermIdFromId
-		functions (ROP:0x43 and 0x44), and associated mapitest.
-	[r633]
-		Documentation typo fix.
-	[r632]
-		Change the QueryNamesFromIDs() call to match
-		MSDN, including changing the name to QueryNamedProperties().
-		
-		Also implement mapitest for QueryNamedProperties(),
-		GetNamesFromIDs() and GetIDsFromNames().
-		
-		Update torture test to match.
-2008-07-05
-    jkerihuel
-	[r631]
-		- Build system update: use samba4-alpha5 release with wget method
-		- introduce 'make samba' and 'make samba-git'
-2008-07-04
-    bradh
-	[r630]
-		Make sure we have names[] array large enough.
-		
-		Problem identified using default uno run.
-		
-		Resolves #87.
-2008-07-03
-    jkerihuel
-	[r629]
-		Fix a small errno bug in GetBestBody
-		Add dump-data and debug options to exchange2mbox
-2008-06-30
-    jkerihuel
-	[r627]
-		- Move emsmdb interface version back to 0.81 (patch applied in samba4 trunk)
-		- remove sed hack, modifications applied in samba4 trunk
-		- update required samba4 git rev required
-    bradh
-	[r628]
-		Typo fix.
-2008-06-25
-    jkerihuel
-	[r626]
-		Minor documentation update: remove deprecated reference to ./bin/smbpython
-	[r625]
-		Fix torture suite entry point name
-		Fix torture module installation path
-	[r624]
-		- Add implementation for the BestBody algorithm
-		- Add MAPI_E_NOT_ENOUGH_MEMORY error code
-		- Remove trailing }}\0 from lzfu code
-		- Update openchange tools to use GetBestBody rather than
-		the initial check on PR_MSG_EDITOR_FORMAT
-	[r623]
-		Add a very basic stat module for mapitest: gives a quick overview
-		of tests which failed at the end of the report.
-	[r622]
-		- Defines a global stream size in mapitest.h
-		- Decrease stream size from 0x4000 to 0x3000
-		  Sounds like Exchange 2003 SP2 doesn't support 0x4000, return MAPI_E_CALL_FAILED
-		 
-2008-06-24
-    jkerihuel
-	[r621]
-		Fix OC_CHECK_SAMBA_VERSION string
-	[r620]
-		- Move samba4_ver.sh from top dir to script
-		- update parts of openchange relying on samba4_ver.sh
-	[r619]
-		Add configure check for lib Z
-		 
-	[r618]
-		- Temporary fix ldb.pc problem and patch ldb.pc.in
-		- Update samba4 version to the latest revision
-		- Add libmapiproxy to svn:ignore proplist
-    bradh
-	[r617]
-		Try a different git revision, just for now.
-2008-06-17
-    jkerihuel
-	[r614]
-		- Update Samba4 version needed
-		- Change entry point function from init_module to samba_init_module
-		- update documentation
-2008-06-16
-    jelmer
-	[r613]
-		Fix calls of ldb_init() as required by newer versions of Samba.
-	[r612]
-		Avoid bashisms.
-	[r611]
-		Support newer versions of Samba4.
-2008-06-14
-    bradh
-	[r609]
-		Add some other standard GUIDs
-2008-06-11
-    jelmer
-	[r605]
-		Fix silly typo.
-	[r604]
-		Fix linking.
-	[r603]
-		Use version and soversion in mapiproxy library.
-	[r602]
-		Make modules directory overridable.
-2008-06-10
-    bradh
-	[r601]
-		Change API as identified on devel mailing list.
-		
-		Here is the email:
-		After some investigation into an error reported by valgrind, I'm proposing an
-		API change for the MoveCopyMessages() function.
-		
-		The signature is currently
-		enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,  mapi_object_t 
-		*obj_dst,  mapi_id_t *message_id,  bool WantCopy)
-		
-		The problem is the message_id array. The subtle part is that it needs to be 
-		terminated with a null mapi_id_t*, because of this:
-		for (request.count = 0; message_id[request.count]; request.count++);
-		
-		That is a bit error prone - enough so to be wrong in the mapitest.
-		
-		Now we could just fix the mapitest and document the requirements, or we could 
-		change the signature.
-		
-		Two ideas for a different signature:
-		1. We could add a uint16_t count to the signature, that says how long the 
-		array is.
-		2. We could use a better data structure than mapi_id_t*. I'm suggesting
-		mapi_id_array_t:
-		enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,
-		                                          mapi_object_t *obj_dst,
-		                                          mapi_id_array_t *message_id,
-		                                          bool WantCopy)
-2008-06-09
-    bradh
-	[r600]
-		Add mapitest coverage for CopyTo operations on 
-		folders and attachments, and update API docs.
-		
-		Also fix one place where we inadvertently used
-		CopyProps instead of CopyTo...
-2008-06-08
-    bradh
-	[r597]
-		Typo fixes in comments.
-	[r596]
-		Minor documentation updates.
-	[r595]
-		Clean up created message for SpoolerLockMessage() test.
-2008-06-07
-    bradh
-	[r594]
-		Update samba4 version test.
-	[r593]
-		typo fix.
-	[r592]
-		Make sure properties are copies into the last valid 
-		location in the extended array (i.e. count-1) not the
-		count location.
-		
-		Also, make sure we cast the data to a uint8_t for
-		conversion to boolean.
-		
-		Also fix compile warning about returning integer instead
-		of pointer.
-	[r591]
-		We may read up to 0x1000 bytes, so ensure there is
-		enough room to add the terminating null.
-	[r590]
-		Minor cleanup of the talloc context for FreeBookmark().
-		
-		Also change around some code to protect things a bit
-		better against null pointer inputs.
-2008-06-06
-    bradh
-	[r588]
-		Implement a bit more mapitest for CopyTo (0x39), in
-		support of #83.
-		
-		Also make it clean up and report failures properly.
-2008-06-05
-    bradh
-	[r587]
-		Implement the CopyTo operation (0x39), including initial mapitest.
-		JK previously committed the IDL for this.
-		
-		Also make CopyProps (0x67) use an appropriate data structure for
-		its IDL and update implementation to match.
-2008-06-04
-    bradh
-	[r586]
-		Minor documentation updates/corrections.
-2008-06-02
-    jkerihuel
-	[r583]
-		Introduce a default case for MAPI Restriction. In some circumstances -
-		while Outlook creates an OOF Rules - it sets a PT_SRESTRICT mapi
-		property tag which value is set to 0xFF. However 0xFF doesn't match
-		any restriction case.
-2008-06-01
-    jkerihuel
-	[r582]
-		- Add IDL for OpenEmbeddedMessage (0x46) MAPI call
-	[r581]
-		- Add IDL for ReloadCachedInformation (0x10) MAPI call
-	[r580]
-		- Add IDL for CopyTo (0x39) MAPI call
-	[r573]
-		- Update the Samba4 GIT revision needed to run openchange properly
-	[r572]
-		- import mapiproxy project from mapiproxy branch
-		- add custom proxypack MAPI call
-		- remove deprecated dcesrv_exchange_remote
-    bradh
-	[r579]
-		Add missing part of mapitest for SetReadFlags
-		
-		This should have been part of r578.
-	[r578]
-		mapitest for SetReadFlags
-	[r577]
-		Implement SetReadFlags (operation 0x66).
-		
-		Also minor API docs fix.
-	[r576]
-		Move some test infrastructure from the oxctable.c module
-		into the common area.
-	[r575]
-		Fix IDL error for SetReadFlags, and use existing flags
-		define (MSGFLAGS_READ) instead of creating a new set.
-	[r574]
-		Build fix for relocation of mapiproxy/ to be under the
-		top level directory (instead of under the utils/
-		directory)
-2008-05-31
-    jkerihuel
-	[r571]
-		merge from mapiproxy branch:
-		      * ndr_push Logon_req manually
-	[r568]
-		merge from mapiproxy branch:
-		      * Add IDL and server boiler template for EcDoConnectEx (0xA)
-		        EMSMDB RPC function
-		
-		      * Fix ndr_push_mapi_response code in ndr_mapi.c
-		
-		      * Add the ndr_push_EcDoRpc_MAPI_REPL function in
-		        ndr_mapi.c. Handles special Notify and Pending cases
-		
-		      * Handle op_MAPI_Pending case properly in
-		        ndr_pull_EcDoRpc_MAPI_REPL
-		
-		      * Add code to ndr_push QueryRows in ndr_mapi.c: Do not push any
-		        DATA_BLOB if there is no RowCount
-	[r565]
-		merge from mapiproxy branch:
-		      * Fix GetReceiveFolder [out] IDL
-		      * Fix some naming convention typo
-	[r564]
-		merge from mapiproxy branch:
-		      * Fix SetMessagReadFlag [out] IDL
-	[r563]
-		- Add [flag(NDR_REMAINING)] to SetMessageReadFlag. This is not
-		  perfect, but it will prevent mapiproxy from ndr_pull error while
-		  setting message read flag on public folders messages.
-	[r562]
-		merge from mapiproxy branch:
-		      * Fix CreateMessage [out] IDL
-	[r561]
-		merge from mapiproxy branch:
-		      * rename OpenModeFlags to OpenFolder_OpenModeFlags in OpenFolder
-		      * rewrite OpenMessage [in] IDL and report changes in
-		        libmapi/IStoreFolder.c
-	[r560]
-		merge from mapiproxy branch:
-		      * Add IDL for Pending (0x6e) MAPI call
-		      * Reorder some MAPI calls in EcDoRpc_MAPI_REPL_UNION
-	[r559]
-		- Add SetReadFlags to EcDoRpc_MAPI_{REQ,REPL}_UNION
-	[r558]
-		merge from mapiproxy branch:
-		      * Add IDL for SetSyncNotificationGuid (0x88) MAPI call
-	[r557]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncGetTransferState (0x82) MAPI call
-	[r556]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncImportReadStateChanges (0x80) MAPI call
-		
-		Note: This IDL is temporary and should be improved after completion of
-		the merging process.
-	[r555]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncOpenCollector (0x7e) MAPI call
-	[r554]
-		merge from mapiproxy branch:
-		      * Add IDL for DeletePropertiesNoReplicate (0x7a) MAPI call
-	[r553]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncImportMessageMove (0x78) MAPI call
-	[r552]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncUploadStateStreamBegin (0x75) MAPI call
-		      * Add IDL for SyncUploadStateStreamContinue (0x76) MAPI call
-		      * Add IDL for SyncUploadStateStreamEnd (0x77) MAPI call
-	[r551]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncImportDeletes (0x74) MAPI call
-	[r550]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncImportHierarchyChange (0x73) MAPI call
-	[r549]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncImportMessageChange (0x72) MAPI call
-	[r548]
-		merge from mapiproxy branch:
-		      * Add IDL for SyncConfigure (0x70) MAPI call
-	[r547]
-		merge from mapiproxy branch:
-		      * Add IDL for RegisterOptions (0x6f) MAPI call
-		
-		Note: This call is undocumented in Microsoft documentation, but MSDN
-		RegisterOptions function generates this call on the wire.
-	[r546]
-		merge from mapiproxy branch:
-		      * Add IDL for Progress (0x50) MAPI call
-	[r545]
-		merge from mapiproxy branch:
-		      * Add IDL for FastTransferSourceGetBuffer (0x4a) MAPI call
-	[r544]
-		merge from mapiproxy branch:
-		      * Add IDL for GetPerUserLongTermIds (0x60) MAPI call
-		      * Add IDL for GetPerUserGuid (0x61) MAPI call
-		      * Add IDL for ReadPerUserInformation (0x63) MAPI call
-	[r543]
-		merge from mapiproxy branch:
-		      * Add IDL for LongTermIdFromId (0x43) MAPI call
-		      * Add IDL for IdFromLongTermId (0x44) MAPI call
-	[r542]
-		merge from mapiproxy branch:
-		      * Add IDL for ModifyRules (0x41) MAPI call
-	[r541]
-		merge from mapiproxy branch:
-		      * Add PT_SRESTRICT support in mapi_SPropValue_CTR
-		
-		      * Add PT_ACTIONS and RuleAction support in mapi_SPropValue_CTR
-		
-		      * Fix mapi_SNotRestriction NDR push routine - add a wrapper to
-		        work around the no-pointer deep recursion pb and remove
-		        existing nopull,nopush,noprint code from ndr_mapi.c
-		
-		      * Fix mapi_SComment_Restriction IDL
-		      
-	[r540]
-		- Introduce PT_MV_UNICODE support in mapi_SPropValue_CTR (IDL only)
-		- use mapi_LPWSTR for PT_MV_UNICODE
-		- rename mapi_LPWSTR structure to mapi_name in Kind structure and
-		  change its field names.
-	[r536]
-		- Fix emsmdb version
-		- Change MAPI opnum enum identation -- Helps to fine down merging from
-		  mapiproxy branch
-    bradh
-	[r539]
-		API docs typo fix.
-	[r538]
-		Minor API documentation fixes.
-	[r537]
-		Update label to reflect SetReadFlags -> SetMessageReadFlag 
-		renaming.
-		
-		This should have been part of r529 - missed it.
-2008-05-30
-    jkerihuel
-	[r535]
-		merging from mapiproxy branch:
-			- Fix MV_UNICODE_STRUCT and unicode strings
-			- Keep LPWSTR for exchange_nsp and move from LPWSTR to
-		          mapi_LPWSTR for exchange_emsmdb
-			- Add the NspiGetTemplateInfo IDL
-			- Fix the NspiUpdateStat IDL
-	[r534]
-		Fix build: SetMessageReadFlag function name was not propagated in the
-		module_oxcmsg.c
-    bradh
-	[r529]
-		Initial merge of changes for rename of SetReadFlags to
-		SetMessageReadFlags (op 0x11) and IDL for SetReadFlags 
-		(op 0x66).
-	[r528]
-		Use private_data instead of private, for C++ happiness.
-	[r527]
-		Minor cleanup. Using "try" confuses my c++ compiler...
-	[r526]
-		This is really part of r525. It moved to IMAPITable.c
-	[r525]
-		Update the table operations:
-		 - implement ExpandRow and CollapseRow
-		 - implement GetCollapseState and SetCollapseState
-		 - add mapitest coverage for the above, plus the Restrict call
-		 - implement ResetTable
-		 - implement FreeBookmark
-		 - add mapitest coverage for SRowSet parsing code
-		 - minor IDL fixes
-		 - various API documentation bits
-    jelmer
-	[r533]
-		Use right directory for samba4_ver.sh script.
-	[r532]
-		Use common location for Samba 4 git revision.
-2008-05-27
-    bradh
-	[r522]
-		Use PT_ERROR where appropriate.
-	[r521]
-		Update the SRowSet parser, fixing breakage I introduced.
-2008-05-26
-    bradh
-	[r518]
-		Update examples to reflect recent API changes.
-    jelmer
-	[r520]
-		Don't rely on absolute file paths since the distribution may be installing 
-		in other locations.
-	[r519]
-		make scripts executable.
-2008-05-25
-    bradh
-	[r515]
-		Avoid segfaulting if you ask for a specific test or tests and 
-		forgot to start the server.
-		
-		Here is an example:
-		[bradh at conferta trunk]$ ./bin/mapitest --mapi-calls=OXCTABLE-CATEGORY --mapi-calls=OXCTABLE-RESTRICT --mapi-calls=NOSERVER-LZFU
-		Failed to connect host 192.168.11.77 on port 135 - NT_STATUS_HOST_UNREACHABLE
-		Failed to connect host 192.168.11.77 (192.168.11.77) on port 135 - NT_STATUS_HOST_UNREACHABLE.
-		    MapiLogonEx              : MAPI_E_RESERVED (0xFFFFFFFF)
-		#############################[mapitest report]#################################
-		        [*] Date                     : Sun May 25 11:45:29 2008
-		        [*] Confidential mode        : [no]
-		        [*] Samba Information        : 4.0.0alpha4-GIT-44d8b70
-		        [*] OpenChange Information   : 0.8-SVN-build-510 (Romulus)
-		
-		        [*] System Information       :
-		                Kernel name          : Linux
-		                Kernel release       : 2.6.23.17-88.fc7
-		                Processor            : x86_64
-		###############################################################################
-		
-		
-		[*] NOSERVER-LZFU
-		[TEST] NOSERVER-LZFU
-		------------------------------------------------------------------------
-		        * uncompress_rtf2                    : 0x00000000
-		        * uncompress_rtf2                    : PASSED
-		------------------------------------------------------------------------
-		[RESULT] NOSERVER-LZFU: [SUCCESS]
-		========================================================================
-		
-		[*] OXCTABLE-RESTRICT
-		Server is offline, skipping test: "OXCTABLE-RESTRICT"
-		[*] OXCTABLE-CATEGORY
-		Server is offline, skipping test: "OXCTABLE-CATEGORY"
-2008-05-24
-    bradh
-	[r510]
-		ignores objects that contain invalid handlers in mapi_object_release().
-		
-		Patch by Alan Alvarez. Compile tested, passes mapitest on SBS2003.
-2008-05-23
-    bradh
-	[r507]
-		Fix API documentation to match signature.
-2008-05-20
-    bradh
-	[r504]
-		Update QueryRows IDL and implementation to match
-		msdn documentation.
-		
-		The main work here is reworking the SRowSet parsing
-		routine.
-2008-05-18
-    bradh
-	[r501]
-		Typo fix - allow cleanup to work properly.
-2008-05-17
-    bradh
-	[r497]
-		Make sure it has a return value.
-2008-05-11
-    bradh
-	[r495]
-		Rename GetColumns remote operation to GetColumnsAll, and 
-		fix up IDL and implementation to match.
-		
-		Add some more unit test coverage, and pretty-up the
-		output a little.
-	[r494]
-		Fix up breakage introduced in r493.
-    jelmer
-	[r496]
-		Make sure nagios directory gets created if it didn't exist yet.
-2008-05-10
-    bradh
-	[r493]
-		Refactor the unit tests.
-		
-		Extract out the setup and some of the cleanup code.
-2008-05-08
-    jkerihuel
-	[r490]
-		- Update openchange code to work with Samba4 4.0.0alpha4-GIT-44d8b70
-		- Use event_context structure
-		- update installsamba4.sh script to revert to this revision.
-		- update torture modulesdir reference
-    jelmer
-	[r492]
-		Look a little bit harder for the Samba installation.
-2008-05-05
-    jkerihuel
-	[r489]
-		- Add GetLocalReplicaIds MAPI call (IDL + implementation + mapitest)
-		- Add OXCFXICS mapitest module
-2008-05-03
-    jkerihuel
-	[r488]
-		- Fix "the very secret" openchange coding style
-		- Add Copyright for our humble new libmapi developer ;-)
-    bradh
-	[r487]
-		Implement the CopyProperties operation, including
-		a mapitest for this.
-2008-05-02
-    jkerihuel
-	[r485]
-		- Add TransportSend MAPI call (IDL + implementation + mapitest). This
-		code maybe needs some review regarding memory.
-	[r484]
-		- Add the GetTransportFolder MAPI call (IDL + implementation +
-		  mapitest)
-	[r483]
-		- Add SpoolerLockMessage MAPI call (IDL + implementation + mapitest)
-	[r482]
-		- Add SetSpooler MAPI call (IDL + implementation + mapitest)
-	[r481]
-		- Add GetRulesTable (IDL + implementation + mapitest)
-		- Add the OXORULE mapitest suite
-    bradh
-	[r480]
-		Typo fix.
-    jelmer
-	[r486]
-		Make sure config.mk is the last file removed during distclean.
-2008-05-01
-    jkerihuel
-	[r479]
-		- Add the Abort MAPI call (IDL + implementation)
-		
-		OpenChange doesn't support yet asynchronous operation which explains
-		why no associated mapitest test has been implemented. This should be
-		done in the future.
-	[r478]
-		- Add the MoveFolder MAPI call (IDL + implementation + mapitest)
-		- Fix some typo in mapitest doxygen
-	[r477]
-		- Add MoveFolder MAPI call (IDL + implementation + mapitest)
-		- Fix some doxygen stuff
-		- add a common function within mapitest which looks for a folder name
-		  within a container and return the opened folder object on success.
-	[r476]
-		Add auto-generated Doxyfile to the svn ignore list
-	[r475]
-		- Add AbortSubmit MAPI call (IDL + implementation + mapitest)
-	[r473]
-		- Uninitialize MAPI and general memory context at the end of mapitest
-    bradh
-	[r474]
-		Clean up / flush the stream after use. 
-		
-		Saves a bit more "still reachable" in valgrind too.
-2008-04-30
-    jkerihuel
-	[r470]
-		- Rename CopyMessages to MoveCopyMessages
-		- Improve IDL + implementation and mapitest added
-    bradh
-	[r471]
-		Make sure the version shown for mapitest documentation
-		is automatically set to match the package version.
-	[r468]
-		complete the rest of the API documentation autonumbering.
-    jelmer
-	[r472]
-		Remove duplicate use of $(SHLIBEXT).
-	[r469]
-		Avoid parallel builds for now.
-2008-04-29
-    jkerihuel
-	[r467]
-		Fix GetContentsTable binding in perl swig
-	[r466]
-		- Improve the GetHierarchyTable and GetContentsTable IDL and public
-		  IDL implementation (new parameters in,out)
-    bradh
-	[r465]
-		Initial part of automatic list numbering for doxygen comments.
-		
-		This doesn't work correctly with the current apidocs.css, which
-		turns the list numbers into bullet points for reasons I don't 
-		understand.
-2008-04-28
-    jkerihuel
-	[r464]
-		- Improve the DeleteMessages IDL request
-	[r463]
-		- Update libmapi version from 0.7 to 0.8
-		
-		- Public API change for the GetReceiveFolder function; now takes a
-		  message class as 3rd parameter.
-	[r458]
-		- Improve GetSearchCriteria request IDL (unknown removed)
-		- update libmapi copyright headers 2007 -> 2007-2008.
-	[r457]
-		- Improve the SubmitMessage IDL
-		- minor indentation fixed in IMessage.c
-	[r456]
-		- Add CopyToStream MAPI call (IDL + implementation + mapitest)
-	[r455]
-		- Add SeekStream MAPI call (IDL + implementation + mapitest)
-		- Add SetStreamSize MAPI call (IDL + implementation + mapitest)
-	[r454]
-		- Add CommitStream MAPI call (IDL + implementation + mapitest)
-		- Add GetStreamSize MAPI call (IDL + implementation + mapitest)
-		- refactor the stream test to include all stream related operations
-		- add a common function which generates a random ASCII blob of data
-    bradh
-	[r453]
-		Add doxygen support for the mapitest examples.
-    jelmer
-	[r459]
-		Allow cleaning individual parts.
-2008-04-27
-    jkerihuel
-	[r452]
-		- Add GetStatus call (IDL + implementation + mapitest)
-	[r451]
-		- Fix format string problem in mapitest headers
-	[r450]
-		Run offline suites by default.
-	[r449]
-		- Introduce the online/offline mode for suite
-		- Fix Exchange headers print bug when server is offline
-		- reset errno to 0 before running new test
-    bradh
-	[r447]
-		Install the libmapiadmin.h header.
-	[r446]
-		Fix a compile-time warning on amd64, for the second
-		argument to the getline() call - incompatible pointer
-		type.
-		
-		I'm assuming that size_t is equivalent to uint32_t
-		on a 32-bit architecture, but not on a 64-bit arch.
-		
-		A quick test showed no difference in actual output.
-    jelmer
-	[r448]
-		Remove bashisms in installsamba4.sh
-2008-04-26
-    jkerihuel
-	[r445]
-		- Add ReadRecipients MAPI call (IDL + implementation + mapitest)
-		- Improve some ModifyRecipients and Recipients structure naming
-2008-04-25
-    jkerihuel
-	[r444]
-		- Add RemoveAllRecipients call (IDL + implementation + mapitest)
-	[r443]
-		- Add OpenPublicFolderByName call added (IDL and implementation).
-		
-		- Note: the reply IDL doesn't handle Server and ServerCount yet.
-		
-		- Note: this call only refers to NNTP folders (e.g: folders located
-		within "Internet Newsgroups". If developers use this call within "All
-		Public Folders", then the call with return MAPI_E_NOT_FOUND.
-		
-		- Call not added to mapitest cause it require RightsAuthor permissions
-		on Internet Newsgroups which is not the case by default.
-		
-		- dump-data and debug options added to mapitest
-		- FOLDER suite renamed to OXCFOLD (naming convention)
-	[r441]
-		Rename module folder to oxcfold
-	[r440]
-		Replace the existing mapitest tool with a new implementation. It is
-		less complete but more modular.
-    jelmer
-	[r442]
-		Add proto headers to ignore file.
-2008-04-20
-    jkerihuel
-	[r438]
-		OpenFolder request: replace unknown field with OpenModeFlags
-	[r437]
-		- Rename 0xFE opnum from OpenMsgStore to Logon
-		- Update the Logon request IDL
-    bradh
-	[r439]
-		Add BEGIN_DECLS for private_proto.h.
-	[r436]
-		Add forgotten part of rev435.
-	[r435]
-		Add unit test framework for compressed RTF decoding.
-		
-		Refactor lzfu.c to improve testability.
-2008-04-19
-    jkerihuel
-	[r434]
-		Fix openchangeclient --mailbox --pf with wasn't launched anymore due
-		to some incorrect sanity check tests.
-	[r433]
-		- Remove deprecated fuzzer_msgstore torture test
-		- replace mapi_flags with logon_id in EcDoRpc_MAPI_REQ
-2008-04-16
-    bradh
-	[r432]
-		A couple of minor fixes to make it read better.
-    jelmer
-	[r431]
-		properly clean up sofiles
-	[r430]
-		Import exchange nagios check script by Bill Edmunds.
-	[r429]
-		Add support for creating libocpf soname symlink.
-	[r428]
-		Use standard include for uint64_t definition.
-	[r427]
-		Cleanup talloc and tdb before building samba4.
-2008-04-14
-    jkerihuel
-	[r426]
-		Check for ocpf_set_Recipients retval (MAPI_E_NOT_FOUND)
-	[r425]
-		- Reset ocpf to NULL after release so the ocpf_init/release couple can be called more than once.
-		- Sanity check on recipient, avoid parsing if no recipient is set. Return MAPI_E_NOT_FOUND instead.
-	[r424]
-		Add reference to the ocpf lib within the pc file.
-2008-04-09
-    jelmer
-	[r423]
-		Remove duplicate SWIG instructions (already covered by stdint.i).
-	[r422]
-		Ignore files created by swig.
-	[r421]
-		Use config.mk in swig/perl/Makefile.
-	[r420]
-		Allow sambaprefix and prefix to be different. Allow building with unknown 
-		Samba git revisions (will still warn though).
-	[r419]
-		Add --with-samba argument to configure so samba and openchange can be installed in different directories.
-2008-04-08
-    jkerihuel
-	[r418]
-		Add domain to the mapiprofile dump output.
-	[r417]
-		Fix OpenMessage IDL and GetRecipientTable fetched data
-		
-		-This line, and those below, will be ignored--
-		
-		_M   trunk
-		M    trunk/exchange.idl
-		M    trunk/libmapi/IStoreFolder.c
-		M    trunk/libmapi/emsmdb.c
-		M    trunk/libmapi/IMessage.c
-2008-04-07
-    jelmer
-	[r416]
-		Fix typo, change samba-config -> samba-hostconfig.
-2008-04-06
-    jkerihuel
-	[r415]
-		- Add openchangepfadmin to make install
-		- Add openchangemapidump and locale_codepage to make clean
-2008-04-05
-    jelmer
-	[r413]
-		Merge the samba4-latest branch.
-2008-04-03
-    jkerihuel
-	[r408]
-		Revert so version number to 0.7
-	[r407]
-		Fix Perl bindings: update mapidump_message
-	[r405]
-		** Start libmapi-0.8 ROMULUS development **
-	[r402]
-		Add ChangeLog and apidocs to the releases
-	[r400]
-		- Delete unmaintained regression suite
-		- Fix typo error in torture-clean rule
-	[r399]
-		Add modified release script originally from abartlett/samba4
-	[r398]
-		- Check for specific Samba4 git revision in configure.ac
-		- Prefix locale functions with lcid and make them _PUBLIC_
-    bradh
-	[r406]
-		API documentation update.
-    jelmer
-	[r403]
-		Fix some typos.
-2008-04-02
-    jkerihuel
-	[r397]
-		Add installation script for samba4
-	[r396]
-		- Apply the nspi pointer patch - make openchange works with
-		samba4-alpha3 git 41309dc
-		
-		- update howto.txt
-    bradh
-	[r390]
-		Move the top level API documentation to an "overview"
-		section and add a redirect to that overview.
-		
-		This keeps the doxygen output more nicely separated for
-		packaging.
-		
-		Also, generate the man pages where the install expects
-		to find them.
-2008-04-01
-    jkerihuel
-	[r388]
-		- Fix strsep bug in openchangeclient
-		- Add RECIPIENT support to libocpf
-	[r383]
-		- escape/unescape strings support added
-		- PT_MV_STRING8 type added to OCPF write API
-2008-03-31
-    jkerihuel
-	[r382]
-		- return MAPI_E_NOT_FOUND if NspiGetMatches doesn't return any results
-		  (based upon patch from lofi at mountproc.org)
-		- makes the workstation parameter of mapiprofile optional (use
-		  gethostname if not defined by the user on command line)
-	[r381]
-		- Fix an allocation memory problem in cast_SPropValue
-		- update svn:ignore proplist
-2008-03-30
-    jkerihuel
-	[r380]
-		Update the documentation build so it keeps generating an embedded
-		website in with apidocs/html as root directory.
-	[r378]
-		- Add support for PT_UNICODE and PT_SHORT to libocpf
-		- Initial implementation of the libocpf write API
-		- Update libocpf documentation
-		- add --ocpf-dump option in openchangeclient
-		- Fix realdistclean rules for server
-		- add cast_SPropValue function to libmapi/property.c which cast
-		  mapi_SPropValue to SPropValue
-    bradh
-	[r379]
-		Split API documentation into two separate sections - one
-		for libmapi and one for libocpf.
-		
-		Also add in a top level intro page.
-2008-03-27
-    jkerihuel
-	[r376]
-		New build system which gathers a list of things that can be built with
-		the libraries/utilities the user has installed and build that when
-		"make all" is run.
-2008-03-26
-    jkerihuel
-	[r375]
-		Add missing allocation for OLEGUID
-	[r373]
-		--ocpf-syntax doesn't require MAPI to be initialized. Furthermore
-		  makes ocpf-syntax "exclusive" (quit after performing the operation).
-    bradh
-	[r372]
-		r371 was bad. What was I thinking with that nonsense!
-		
-		Revert to something sane.
-	[r371]
-		Make the ./bin/ directory if it doesn't exist.
-		
-		This should resolve ticket #33.
-2008-03-23
-    bradh
-	[r370]
-		Improve language handling when creating profiles.
-		
-		You can now get a list of valid languages and use either
-		the language code ID or the language name to specify what
-		language later versions of Exchange should reply with.
-	[r369]
-		Typo fix - duplicate ; at the end of the structure.
-	[r368]
-		Match format to unsigned int argument.
-	[r367]
-		Make the format specifier match the unsigned argument.
-2008-03-22
-    jkerihuel
-	[r366]
-		propset svn:ignore update
-	[r365]
-		Update propset svn:ignore on doc/examples and libocpf targets
-	[r364]
-		- Fix ticket #29: http://trac.openchange.org/ticket/29
-		
-		- use access(2) to see if the database already exists
-		- test if the profile already exists prior trying to add it
-		- add descriptive error messages
-		- catch CTRL-C signal and run a profile deletion routine
-    bradh
-	[r363]
-		Update API documentation for ocpf_nproperty_add().
-	[r362]
-		Typo fix.
-2008-03-16
-    jkerihuel
-	[r361]
-		Fix mapidump_message call parameters
-2008-03-13
-    jkerihuel
-	[r360]
-		Add fid/mid parameters to mapidump_message and changed
-		openchangeclient_fetchitems to reflect these changes.
-	[r359]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-		updates the OCPF doxygen file.
-	[r358]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-		adds the doc/examples into the build system and enables make examples.
-	[r357]
-		Patch From Brad Hards, <bradh at frogmouth.net>:
-		API documentation update and minor fix for the error value change.
-2008-03-09
-    jelmer
-	[r355]
-		Update bzr ignores.
-2008-03-06
-    jkerihuel
-	[r354]
-		- Add PT_BINARY property support to OCP
-		- Add stream support to OCPF for large PT_BINARY blobs.
-		- Fix a bug which prevented from having no/empty PROPERTY or NPROPERTY
-		  sections.
-2008-03-05
-    jkerihuel
-	[r353]
-		- Prevent from assigning a value which type doesn't match with
-		  the property one.
-		- Add missing substitution variable support for some named properties
-		  declaration
-		- Improve sample_appointment.ocpf example
-		- Add PT_MV_STRING8 keyword to the list of supported property type
-		  identifiers.
-2008-03-04
-    jkerihuel
-	[r352]
-		Improve OCPF PT_MV_STRING8 support.
-	[r351]
-		- Initial revision for libocpf and its documentation
-		- YACC support added to the build system
-		- custom lid and string support in mapi_nameid
-		- lookup functions added for OOM, lid and string
-		- OCPF commands added to openchangeclient (ocpf-file, ocpf-syntax,
-		  ocpf-sender)
-		- PR_FID displayed in openchangeclient --mailbox
-		- PT_MV_STRING8 support added to cast_mapi_SPropValue
-2008-03-02
-    jkerihuel
-	[r350]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-			updates code to build with current API
-	[r349]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-			little update for some API dox
-2008-02-21
-    jkerihuel
-	[r348]
-		- Add --update option to openchangeclient and allow users to modify
-		  existing messages (calendar, task, contact, note)
-		- Add --delete option to openchangeclient and allow users to delete
-		  existing messages (calendar, task, contact, note)
-		- Add some folder/message unique ID to mapidump outputs and send*
-		  openchangeclient functions.
-		- Fix a bug in set_SPropValue: add sanity check on unicode
-		  string. Thanks to Suman Manjunath for this patch.
-		- Fix mapidump_task function and identifiers of named properties used.
-2008-02-19
-    jkerihuel
-	[r347]
-		Fix missing sanity check on priority
-	[r346]
-		Fix a bug in openchangeclient when tasks are created without body
-	[r345]
-		private flag added to openchangeclient appointments
-	[r344]
-		Fix folder IDs problem for Exchange 2007 SP1
-2008-02-09
-    jkerihuel
-	[r343]
-		Fix names IDL against Samba4 4.0.0alpha3-GIT-41309dc
-2008-01-24
-    jkerihuel
-	[r342]
-		- Fix a bug in IStoreFolder.c:OpenMessage which was also affecting
-		  GetRecipientTable. We were extending SPropTagArray prior calling
-		  emsmdb_get_SRow. This was causing ndr_pull_error in OpenMessage_repl
-		  and erroneous data to be inserted in the SRow.
-		
-		- Fix libmapi/socket/interface.c:
-		     - Use the latest version from Samba4 which removes reference to
-		       global_loadparm.
-		     - Moves struct interface declaration to netif.h
-		     - Report changes to emsmdb.c notification functions.
-		
-		- Change GetGALTable prototype to match general libmapi policy. Remove
-		  the usage of bool and replace it with uint8_t. Possible values added
-		  to mapidefs.h
-2008-01-22
-    jkerihuel
-	[r341]
-		- Improve NspiQueryRows IDL and implementation
-		- Add GetGALTable implementation: fetch all the Global Address List
-		  recipients
-		- Add --userlist option to openchangeclient
-		- Add a convenient and basic dumping function for Global Address List
-		  recipients.
-	[r340]
-		- Improve OpenMessage reply IDL
-		- Fetch mapi recipients from OpenMessage reply
-		- Add GetRecipientTable convenient function
-		- Add OPENCHANGE-MAPI-RECIPIENT torture test to test
-		  GetRecipientTable implementation.
-		- Add convenient SPropTagArray_add function
-		- Add internal emsmdb_get_SRow routine
-2008-01-21
-    jkerihuel
-	[r339]
-		Patch from Suman Manjunath <msuman at novell.com>:
-		
-		- Adds named-properties which define recurrence patterns for
-		  appointment and task. 
-		- Adds named properties for appointment timezone
-	[r338]
-		- Fix the SNotRestriction IDL and write custom push,pull,print
-		  functions
-		- Add 2 new MAPI calls to the IDL: 
-		  * GetSearchCriteria,
-		  * SetSearchCriteria
-		- add sample {Get,Set}SearchCriteria torture test
-		- add convenient mapi_id_array implementation
-		- add GetDefaultFolder support for CommonView and Finder folders
-2008-01-20
-    jelmer
-	[r337]
-		Make sure directory exists.
-2008-01-18
-    jkerihuel
-	[r336]
-		- Fix tiny 'nail down samba4 version' bug
-		- update the minimal Samba4 required version
-	[r335]
-		- Add FindRow call to the IDL
-		- Improve mapi_Restriction support
-		- Remove deprecated ndr_print_QueryRows function
-		- Add a print function for fuzzyLevel
-		- Add preliminary FindRow implementation test to MAPI-RESTRICTIONS
-		  torture test
-		- Add couple of new MAPI tags to mapi-properties
-		- change initial bookmark index to 3
-2008-01-16
-    jkerihuel
-	[r334]
-		- Add 2 new MAPI calls to the IDL and mapitest:
-		  * SetReceiveFolder
-		  * GetReceiveFolderTable
-		
-		- Fix a bug in the SortTable test when no messages are returned by
-		  QueryRows
-	[r333]
-		- Add SeekRowApprox to the IDL and mapitest
-		- Fix some doxygen typo
-	[r332]
-		- New calls added to the IDL, torture suite and mapitest:
-		    * CreateBookmark
-		    * SeekRowBookmark
-		- Internal mapi_object_bookmark_t implementation added to
-		  mapi_object_table_t
-		- SBinary_short default ndr_print function changed to custom
-2008-01-14
-    jkerihuel
-	[r331]
-		Temporary fixes unexpected segfault in SortTable test. Emails sent
-		during the Submit test have sometimes not yet been dispatched when the
-		SortTable test begins. This fix adds a sleep(1) and an arbitrary
-		number of attempts (5).
-	[r330]
-		Add 2 new MAPI calls to the IDL and libmapi:
-		    * AddressTypes
-		    * SortTable
-		
-		Tests for SortTable added to mapitest and the torture suite
-		Test  for AddressTypes added to mapitest.
-2008-01-13
-    jkerihuel
-	[r329]
-		Fix perl bindings and fetchmail test
-	[r328]
-		2 new MAPI call added to the IDL and mapitest: 
-		  * GetMessageStatus
-		  * SetMessageStatus
-2008-01-11
-    jkerihuel
-	[r327]
-		- Add DeleteAttach MAPI call
-		- Add new mapi unit tests:
-		  * QueryColumns
-		  * CreateAttach
-		  * SaveChanges
-		  * GetAttachmentTable
-		  * DeleteAttach
-		- Update mapitest README
-		- Add some convenient functions to mapitest_common.c
-2008-01-10
-    jkerihuel
-	[r326]
-		Add a preliminary draft of the mapitest standalone MAPI test suite.
-2008-01-05
-    jkerihuel
-	[r324]
-		Add missing files
-	[r323]
-		- Fix the build with the latest Samba4 version.
-		
-		- Add a basic libmapi/version.h auto-generated 
-		  file (based on Samba4 one)
-		- Remove some warnings when compiling the utf8 
-		  lexer
-		- Add a emsmdb_info structure to fetch some 
-		  information from the Exchange server
-		
-		WARNING: Please note that EMSABP is definitely broken and 
-		         requires a review and update.
-    jelmer
-	[r325]
-		DESTDIR should never get into any source files, that would defeat its purpose.
-2008-01-04
-    jkerihuel
-	[r322]
-		Fix the torture suite.
-2007-12-28
-    jelmer
-	[r321]
-		provide extra required argument.
-	[r320]
-		Store a loadparm context in the global mapi context.
-	[r319]
-		Deal with samba version.h's that don't contain the Subversion revision.
-2007-12-15
-    jelmer
-	[r318]
-		Use SWIG-provided typemaps for stdint.
-2007-11-29
-    ali
-	[r317]
-		Fix Content-Type field in exchange2mbox
-		Reported by Yuriy Filatov <yuriy.filatov at gmail.com>
-2007-11-28
-    jkerihuel
-	[r316]
-		- Improve the CreateMessage IDL
-		- Add new parameters to IMAPIFolder CreateMessage libmapi function
-		- Add --mkdir --rmdir options to openchangeclient
-		- Update the CreateFolder API and openchangeclient documentation
-		- Fix CreateFolder calls in openchange tools and torture suite
-		- Fix gendb_search warning
-2007-11-25
-    jkerihuel
-	[r315]
-		Add new PSETID_Address named properties 
-	[r314]
-		Fix a few code convention typos 
-		
-		Patch from Suman Manjunath <msuman at novell.com> applied:
-		converts a 'struct timeval' to 'NTTIME'.
-		minor extension of 'set_SPropValue_proptag', used while setting PT_SYSTIME properties.
-2007-11-21
-    jkerihuel
-	[r313]
-		update Samba4 first revision to 26100
-    jelmer
-	[r312]
-		Cope with ndr updates.
-2007-11-12
-    jkerihuel
-	[r311]
-		Patch from Brad Hards: Fix possible Heap overflow in lzfu code
-2007-11-07
-    jkerihuel
-	[r310]
-		Fix profile creation in a clustered Exchange 2007 environment.
-2007-11-02
-    jkerihuel
-	[r309]
-		Fix QueryColumns req size.
-2007-11-01
-    jkerihuel
-	[r308]
-		** Start libmapi-0.7 PHASER development **
-		
-		add --dump-data option to mapiprofile for debugging purpose
-2007-10-31
-    jkerihuel
-	[r306]
-		openchangepfadmin (1) man page added
-	[r305]
-		Store messageID in the object when SaveChangesMessage is called
-	[r304]
-		Nail down Samba4 version for libmapi-0.6
-2007-10-30
-    jkerihuel
-	[r303]
-		- Add PR_MSG_EDITOR_FORMAT property to the sendmail operation
-		- Fix body dump bug when PR_MSG_EDITOR_FORMAT property is missing (default set to PLAINTEXT)
-		- Continue to process the mailbox when a problem is encountered with mesage contents (not attachment)
-		- Fix a typo bug in openchangeclient body help string
-	[r302]
-		Update doxygen section
-2007-10-29
-    jkerihuel
-	[r301]
-		- Add doxygen man (3) pages to installman and uninstallman rules
-		- do not run doxygen if apidocs already exists
-2007-10-28
-    jkerihuel
-	[r300]
-		Move documentation to doxygen 
-2007-10-25
-    jkerihuel
-	[r299]
-		Add convenient date related functions for implementors:
-		returns a timeval struct matching a PT_SYSTIME property
-		for improved date manipulation in 3rd party softwares
-2007-10-24
-    jkerihuel
-	[r298]
-		Fix build to work with latest Samba4 revision (4.0.0alpha2-SVN-build-25722)
-	[r297]
-		Fix make realdistclean when swig perl is enabled
-	[r296]
-		Fix swig perl bindins compilation: move *.o to *.po
-	[r295]
-		use talloc_memdup to copy const data in the body DATA_BLOB
-		Should only provide valid pointer to talloc_free 
-2007-10-23
-    jkerihuel
-	[r294]
-		Fix the DeleteMessages [out] IDL.
-		
-		The remaining bytes were not part of DeleteMessages but
-		MAPI notification (0x2a)
-2007-10-22
-    jkerihuel
-	[r293]
-		- Add RTF support in exchange2mbox
-		- Use openchange-tools public functions
-		- Replace GetPropsAll calls with GetProps
-	[r292]
-		- fetchmail: 
-			* Use GetProps rather than GetPropsAll for message dump
-			* Rely on PR_MSG_EDITOR_FORMAT to select the type of body
-			* Open a stream for PR_BODY and PR_HTML if the size exceeds max property size
-		
-		-This line, and those below, will be ignored--
-		
-		M    trunk/Makefile.in
-		A    trunk/utils/openchange-tools.c
-		M    trunk/utils/openchangeclient.c
-		M    trunk/utils/openchange-tools.h
-		M    trunk/utils/openchangeclient.h
-		M    trunk/libmapi/mapidefs.h
-2007-10-20
-    jelmer
-	[r291]
-		Fix ignores.
-2007-10-19
-    ali
-	[r290]
-		Remove useless svn:ignore
-    jkerihuel
-	[r289]
-		Add WrapCompressedRTFStream function for PR_RTF_COMPRESSED content.
-		
-		Original lzfu decompress routine fetched from libpst-0.5.2
-	[r288]
-		make enum MAPISTATUS variables naming uniform in libmapi
-2007-10-16
-    jkerihuel
-	[r287]
-		Add PT_CLSID case to get_SPropValue_data
-	[r286]
-		Add/Fix pull property support for PT_UNICODE and PT_CLSID (used by GetProps)
-	[r285]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-		Fix compilation for x86_64 platforms.
-2007-10-14
-    ali
-	[r284]
-		More svn:ignore updates
-	[r283]
-		Update of svn:ignore
-2007-10-10
-    jkerihuel
-	[r282]
-		added the IDL license
-	[r281]
-		Convert OpenChange to GPLv3
-	[r280]
-		- Add .po files to make clean 
-		- Fix a couple of warnings in the utf8 conversion lexer 
-		- Prefer long filenames to truncated one for attachments in openchangeclient
-2007-10-09
-    jkerihuel
-	[r279]
-		Prevent exchange2mbox from segfault when PR_MESSAGE_DELIVERY_DATE is unset
-	[r278]
-		Add PT_CLSID and PT_MV_CLSID support to the IDL
-	[r274]
-		- Add new named properties
-		- Convenient function for MNID_STRING props lookup added
-    jelmer
-	[r277]
-		Make .po a recognized suffix.
-	[r276]
-		Fix compile error.
-	[r275]
-		Use -fPIC for library objects.
-2007-10-08
-    jkerihuel
-	[r273]
-		- Rename GetAllNamesFromIDs to QueryNamesFromIDs (better naming)
-		- fix SPropValue_CTR boolean to uint8_t in the IDL and emsmdb.c
-		
-		- add mapi_nameid convenient interface and headers
-		- mapi-named-properties populated, parser added to mparse.pl, file
-		  added to the build system
-		
-		- remove any incorrect reference to named properties in openchange
-		  tree
-		
-		- remove deprecated libmapi/mapi.h file
-		- remove unused ulFlag parameter from IProfAdmin functions
-		- remove unused memory context from libmapi/x500.c
-		
-		- support sendnote operation in openchangeclient
-		- optimize check/list oc_element functions in openchangeclient
-		
-		- update swig interface
-2007-10-05
-    jkerihuel
-	[r272]
-		- New MAPI calls: Named properties support
-		      	 * GetNamesFromIDs
-		  	 * GetIDsFromNames
-		  	 * GetAllNamesFromIDs
-		
-		- Modified MAPI calls:
-		  	 * OpenMessage
-			 * SaveChanges
-		These calls now have more granularity in libmapi with flags support
-		
-		- sample mapi-named-properties file introduced in libmapi/conf
-		
-		- Torture test suite:
-			* suite temporary fixed (import torture_rpc_* functions from
-		          Samba4)
-			* torture_namedprops test added
-		
-		- SWIG Perl bindings fixed according to changes described above
-		- minor improvements in libmapi/mapidump.c
-2007-10-02
-    jkerihuel
-	[r271]
-		- Decrease MAX_READ_SIZE to 0x1000
-		- Clean-up Read/WritreStream related code
-		- add dump-data option to openchangepfadmin (debugging purpose)
-2007-10-01
-    jkerihuel
-	[r270]
-		Fix build: 
-			- remove reference to core/nterr.h
-			- add global_loadparm reference where missing
-			- add reference to core/error.h where needed
-    jelmer
-	[r269]
-		Improve output during build.
-	[r268]
-		Fix lp_load().
-	[r267]
-		Pass loadparm contexts, should fix the build with newer Samba revisions.
-2007-09-28
-    jkerihuel
-	[r266]
-		- WriteStream API changed: now returns the number of bytes written
-		- WriteStream man page updated
-		- 16 bytes extra-data bug fixed when sending attachments in openchangeclient
-		- Set open mode to 0600 when attachments are stored on the filesystem
-		 
-2007-09-19
-    jkerihuel
-	[r265]
-		Fix preliminary Perl bindings so it works with Samba4 alpha2
-		and latest libmapi revision.
-	[r264]
-		Patch from Andrew Gaylard <ag at computer.org>:
-		
-		- When calling openchangeclient with the --dump-data switch, it will
-		dump core, since the global_mapi_ctx pointer isn't initialised yet.
-		The fix is to wait until it's set before accessing it.
-	[r263]
-		Patch from Andrew Gaylard <ag at computer.org>:
-		- Leaving any blank lines before .TH directives appears to cause a blank page
-		to be output when converting man pages to DVI files (which is a step to converting
-		them to PDF). The following patch remove the blank line above the .TH in each man page file. 
-		
-		- mapiprofile doesn't understand the -A switch, as mentioned in it's man page.
-		It should be -I.
-2007-09-13
-    jkerihuel
-	[r262]
-		- Add objectClass to the object: container, message or attachment
-		- Rename content to message in openchangebackup functions
-		- add objectClass parameter to ocb_record_init
-2007-09-12
-    jkerihuel
-	[r261]
-		- Move debug options to their correct location (after MAPIInitialize)
-		- Improve code related to LDB transactions
-		- Add convenient error checking macros
-2007-09-11
-    jkerihuel
-	[r260]
-		- Add preliminary openchangemapidump draft
-		- Fix lp_parm_* 1st parameter in the torture suite
-		- New functions in property.c for MAPI data retrieval
-2007-09-09
-    jelmer
-	[r259]
-		Use configure definition for mandir.
-2007-09-08
-    dan
-	[r258]
-		Activate debugs this time
-	[r257]
-		Replaced remaining gotos with MAPI_RETVAL_IF so errno is set correctly
-	[r256]
-		MAPI_RETVAL_IF missing ";" could cause surprises ;-)
-	[r255]
-		Add error check for samr call.
-		set errno with MAPI_RETVAL_IF.
-2007-09-06
-    dan
-	[r254]
-		Make required packaged more clear (LinuxMagazin input)
-2007-09-05
-    jelmer
-	[r253]
-		Remove invalid comment.
-2007-09-04
-    jkerihuel
-	[r252]
-		- Clean-up function prototypes
-		- Dump email when NEWMAIL notification is received
-2007-08-31
-    jelmer
-	[r251]
-		Proper dependencies.
-	[r250]
-		Don't regenerate proto headers unless necessary.
-	[r249]
-		Add 'make check'.
-	[r248]
-		Use install for installing files/directories.
-	[r247]
-		Actually use replacement variable for libmagic.
-2007-08-30
-    jkerihuel
-	[r246]
-		Remove forgotten BOOL
-	[r245]
-		Remove mapi_session pointer in mapi_objects
-		Add public function to IProfAdmin: retrieve default ldif path location outside the OC tree
-2007-08-28
-    jkerihuel
-	[r244]
-		Prevent users from creation of *undeletable* folders in Outlook and
-		perform sanity check on dirclass + display possible values. 
-	[r243]
-		Provides a way to modify Default and Anonymous permissions for a given folder.
-	[r242]
-		Fix errno in getdir function + add sanity check on opt_rmdir
-	[r241]
-		- Fix a memory related bug in mapiadmin_add_user
-		- Add latest howto.txt modifications from Dan
-	[r240]
-		- Fix bug in *UserPermission function: return when user is not found
-		- Add sanity checks to mapi_object API functions
-		- mapi_object_release reset errno to 0: need to release object
-		after displaying the potential error message.
-	[r239]
-		Fix a mapidump_appointment bug
-		Add PF folder support to fetch-items operation
-2007-08-27
-    jkerihuel
-	[r238]
-		openchangeclient now support send/read/delete operation on custom PF directories.
-	[r233]
-		- Add libmapiadmin library draft: Add/Remove Exchange user
-		- openchangepfadmin tool added: Public Folders management
-		- Add Sanity check to CreateFolder
-    jelmer
-	[r237]
-		Update ignore list.
-	[r236]
-		Fix last references to BOOL, True and False.
-	[r235]
-		Fix more references to BOOL, False and True.
-	[r234]
-		Use standard type and values for booleans since Samba no longer exports 
-		BOOL, True and False.
-2007-08-21
-    jkerihuel
-	[r232]
-		- Add OpenPublicFolder function to libmapi, Open Public Folder store
-		- change torture suite API to match latest Samba4 pidl changes
-		- utf8_convert regexp improved
-		- minor changes: printf to DEBUG
-		- howto.txt patch from Dan included
-		- Samba4 torture code related to user account creation included in the
-		  torture suite.
-2007-08-06
-    jkerihuel
-	[r231]
-		Fix segmentation fault when running update prior populating the database.
-2007-07-31
-    jkerihuel
-	[r230]
-		Remove obsolete file from the torture suite 
-	[r229]
-		- Add Exchange Administration test to the torture suite: Create Exchange user
-	[r228]
-		Dan update on howto.txt
-2007-07-10
-    jkerihuel
-	[r227]
-		- Add Exchange ACLs support to MAPI library
-		- Add 2 new MAPI opnum: GetTable and ModifyTable
-		- Improve mapidump functions
-2007-07-04
-    jkerihuel
-	[r226]
-		- Improve aclocal check in autogen.sh
-		- Fix flex binary detection in configure.ac
-2007-06-22
-    jkerihuel
-	[r225]
-		Same player ...
-	[r224]
-		Fix libmapi symlink
-	[r223]
-		Create libmapi.so symlink
-2007-06-21
-    jkerihuel
-	[r222]
-		Fix mandir installation path
-		Add ldconfig intructions to openchange installation documentation
-	[r221]
-		Fix build.
-2007-06-20
-    jkerihuel
-	[r220]
-		RES_AND and RES_OR preliminary implementation.
-2007-06-19
-    jkerihuel
-	[r218]
-		- doc patch from Brad Hards
-		- rename PROFILE_NOPASSWORD to OC_PROFILE_NOPASSWORD
-		- fix a warning in property.c
-2007-06-16
-    jelmer
-	[r210]
-		Add some 'const' (fixes compile warnings).
-	[r209]
-		Use sonames (required for the Debian packages).
-	[r208]
-		Add .bzrignore file.
-	[r207]
-		Update version number and use globally defined version number in libmapi.pc.
-2007-06-15
-    jkerihuel
-	[r205]
-		- Add IDL implementation for restrictions Content, Property,
-		CompareProps, Bitmask, Size, Exist.
-		- Add Restrict MAPI call handling the restrictions above
-		- OPENCHANGE-MAPI-RESTRICTIONS torture test added to the suite.
-		- convenient sendmail function added to mapi_common.c
-		- get property size function for mapi_SPropValue added to property.c
-		
-		test --This line, and those below, will be ignored--
-		
-		M    Makefile.in
-		M    exchange.idl
-		M    torture/openchange.c
-		A    torture/mapi_restrictions.c
-		M    torture/mapi_common.c
-		M    libmapi/property.c
-		M    libmapi/IMAPITable.c
-2007-06-11
-    jkerihuel
-	[r204]
-		Documentation update: Perl bindings installation
-2007-06-10
-    jkerihuel
-	[r203]
-		- Add mapitags and mapicode support to Perl SWIG bindings
-		- SPropTagArray support
-		- SRowSet preliminary support
-		- new constructor/destructor for mapi objects
-2007-06-09
-    jkerihuel
-	[r202]
-		- IProfAdmin patch applied: having password outside of the profile
-		
-		- Perl bindings draft added to the trunk and to the build system:
-		  --enable-swig-perl=yes
-		
-		- datarootdir fixed in libmapi.pc.in
-2007-06-06
-    jkerihuel
-	[r201]
-		- Add CopyMessages IDL and COPYMAIL torture implementation
-		- Fix man page install dir according to latest Samba4 changes
-		- Add datarootdir var to libmapi.pc.in and fix configure warning
-2007-06-01
-    jkerihuel
-	[r199]
-		convenient function which retrieve a value from a SPropValue array
-		given its property tag name, otherwise NULL
-2007-05-31
-    jkerihuel
-	[r198]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-		openchangeclient man page updated
-	[r197]
-		- Add Windows UTF8 to classic UTF8 conversion through a lexer
-		- openchangeclient --mailbox option changed to use it
-		- flex and bison support added to configure.ac
-		- windows_to_utf8 function added: wrapper over yyparse_utf8 routine
-2007-05-29
-    jkerihuel
-	[r196]
-		- features added to openchangeclient:
-			* --send-appointment
-			* --send-contact
-			* --send-task
-			* custom parameters
-		- openchangeclient man page updated
-		- new properties added to mapi-properties
-	[r195]
-		- Add man pages for simple_mapi.c functions:
-		 * GetDefaultFolder
-		 * GetFolderItemsCount
-	[r194]
-		- Remove deprecated functions from IMsgStore.c
-		- Update man pages documentation
-	[r193]
-		Fix install rule in Makefile: add missing headers
-		Move callback retval from uint32_t to int
-	[r192]
-		Fix notification callback retval
-	[r191]
-		- Advise opnum added to the IDL
-		- Parts of the Notify response IDL implementation
-		- Add Notification support to libmapi
-		- Add --notifications option to openchangeclient
-2007-05-28
-    jkerihuel
-	[r190]
-		Patch from Brad Hards <bradh at frogmouth.net>:
-			- PR_BUSINESS_FAX_NUMBER 
-			- improves the information provided on a contact by 
-		  	  mapidump_contact()
-2007-05-25
-    jkerihuel
-	[r189]
-		- Fix the release call in,out
-		- Call Release from mapi_release_object
-		- Add sanity check to OpenMsgStore
-		- clean up parts of the mapi_newmail test
-	[r188]
-		EcDoDisconnect code now sounds to work properly
-		Tested against Exchange 2000 / Exchange 2003
-	[r187]
-		- Fix SpropValue property pull problem when GetProps layout is set
-		- Add a dumpdata boolean to mapi_ctx_t so tools can dump hex data
-		- Add PR_CONTAINER_CLASS fetch to openchangeclient --mailbox
-		- Add debuglevel and dumpdata options support to openchangeclient
-2007-05-24
-    jkerihuel
-	[r186]
-		- Remove useless memory allocation in mapidump.c
-		- Improve mapidump_appointment
-		- Add sample mapidump_note
-		- Add --fetchitems option to openchangeclient:
-		This command offers an easy way to fetch calendar, contacts,
-		tasks, notes and mails from the Exchange server.
-		- Add IPF container class defines to mapidefs.h
-		- Add and Fix property tags
-2007-05-22
-    jkerihuel
-	[r185]
-		- Commit the EcDoRpc max_data patch proposed on the devel list
-		- Clean up folders related functions from the torture suite 
-		(GetDefaultFolder makes this code obsolete)
-2007-05-21
-    jkerihuel
-	[r184]
-		Add the --mailbox option to openchangeclient which recursively
-		lists the full mailbox folder hierarchy
-	[r183]
-		- Add PT_SYSTTIME support to get_SPropValue_data
-		- Add mapidump_SPropValue_date dumping function
-		- Add PT_SYSTIME support to mapidump_SPropValue
-	[r182]
-		- Add multi-valued SBinary_short support to mapi_SPropValue_CTR in the
-		IDL
-		
-		- Add GetDefaultFolder implementation to simple_mapi.c. This function
-		provides a convenient way to retrieve default folders ID. const
-		olFolder values are stored in libmapi/mapidefs.h
-		
-		- Modify the torture test suite to reflect these changes.
-		
-		- OpenMsgStore now decodes all the fid returned in the response
-		
-		- fix a bug size in libmapi/property.c
-2007-05-18
-    jkerihuel
-	[r181]
-		- Fix SMTP recipient in libmapi
-		- Add SMTP recipient support to openchangeclient
-		and the torture test suite
-		- Fix a bug in SRow_addprop
-2007-05-17
-    jkerihuel
-	[r180]
-		- OpenMessage IDL changed: we have a permission field.
-		It is now set by default to 0x3 (read/write) until we 
-		change OpenMessage prototype.
-		
-		- Add a sanity check to MAPIInitialize when no profdb
-		is specified
-2007-05-15
-    jkerihuel
-	[r179]
-		Remove remaining MAPISTATUS and replace them with enum MAPISTATUS
-	[r178]
-		- SetReadFlags IDL and implementation added to libmapi
-		- Warning fixed in emsabp.h
-	[r177]
-		Fix a bug in openchangeclient when attachments are using
-		PR_ATTACH_LONG_FILENAME rather than PR_ATTACH_FILENAME to store
-		attachment filename.
-	[r176]
-		Patch supplied by Brad Hards <bradh at frogmouth.net> which renames 
-		private structure member to private_data for C++ compatibility.
-	[r175]
-		Add libmapi/simple_mapi.c designed to hold convenient 
-		functions for application development.
-		
-		- GetFolderItemsCount added which returns the number of
-		total and unread messages for a given folder.
-2007-05-14
-    jkerihuel
-	[r174]
-		- Fix a body openchangeclient bug which now prevent openchangeclient
-		from segfault when no body is specified.
-		- Add GetDefaultProfile call to exchange2mbox for the default
-		operation.
-		- Improve fuzzer_msgtore output
-2007-05-13
-    jkerihuel
-	[r173]
-		Add a fuzzer torture test on OpenMsgStore which
-		test all the possible max_data value.
-		
-		Should help to understand if libmapi fails because
-		of max_data or not. 
-2007-05-12
-    jkerihuel
-	[r171]
-		exchange2mbox improved:
-		- tdb dependency removed
-		- message-id are now stored in the profile database
-		- it now mirrors deletion operation from the mbox file back to the
-		Exchange server.
-		- man page updated to reflect these changes
-	[r170]
-		- GetProfileAttr function prototype modified. It now returns the
-		results count for the given attribute and store values in a string
-		array.
-		- GetProfileAttr man page updated to reflect these changes
-		- Fix mapiprofile attribute search command
-		- migrate from open/write calls to stream ones in exchange2mbox
-    texane
-	[r172]
-		newmail torture + notifications implementation
-		
-		-- texane
-2007-05-11
-    jkerihuel
-	[r169]
-		Fix the SambaXP live demo segfault: When an ambiguous recipient is
-		specified, it now skips the name properly and maintain a correct
-		SRowSet.
-	[r168]
-		- Fix a bug when storing attachments into mbox
-		- Add default path support to exchange2mbox
-2007-05-10
-    jkerihuel
-	[r167]
-		- Update libmapi version according to the roadmap
-		- Fix nspi_resolvenames to use default profile database and profile
-2007-05-09
-    jkerihuel
-	[r166]
-		- Add default profile database and profile support in the torture suite.
-		- Fix a bug in mapidump_task
-2007-05-08
-    jkerihuel
-	[r165]
-		- Change MAPILogonEx to MAPILogonProvider and avoid potential
-		emsmdb endpoint related problem
-		- add sanity check on global session pointer
-2007-05-06
-    ali
-	[r164]
-		Merged MAILOOK-branch changes r64:163 into the trunk.
-2007-03-04
-    jkerihuel
-	[r79]
-		Remove ChangeLog, use svn log instead ;p
-2007-02-13
-    jkerihuel
-	[r63]
-		- libmapi includes moved from libmapi/include to libmapi
-		- Remove arguments from prototype definitions generation in mkproto.pl
-		- __BEGIN_DECLS __END_DECLS support in header files
-		- united libmapi/libmapi.h header file
-		- openchange.h header removed
-		- PIDL generated files moved to gen_ndr
-		- compilation rule for libmapi header installation added
-		- useless torture tests removed
-		
-		jkerihuel.
-2007-02-12
-    jkerihuel
-	[r62]
-		Replace OpenProperty and ReadAttach calls with OpenStream and ReadStream call
-		Add GetAttachmentTable call
-		
-		jkerihuel.
-2007-02-09
-    jkerihuel
-	[r58]
-		Remove -Werror CFLAGS until I figure out how to fix
-		our problem definitively.
-		
-		Remove static from dcesrv_exchange.c functions definition
-		
-		jkerihuel.
-    texane
-	[r61]
-		. reimplement GetProps
-		. retrieve attachment size
-		. modify fetchmail and fetchattach torture
-		
-		-- texane
-	[r60]
-		
-		. add GetPropList to exchange.idl
-		. add GetPropList implementation to IMAPIProp.c
-		-- texane
-	[r59]
-		- Add fetchattach torture; Attachment size is not yet
-		defined and 42 is used.
-		- add 3 new EcDoRpc opnums:
-			- OpenAttach
-			- ReadAttach
-			- OpenProperty
-		
-		-- texane
-2007-02-08
-    jkerihuel
-	[r57]
-		Forgot to add IMAPISession.c
-		
-		jkerihuel.
-2007-02-07
-    jkerihuel
-	[r56]
-		Remove spurious warnings at compile time and
-		add -Werror -Wstrict-prototypes to CC.
-		
-		jkerihuel.
-	[r55]
-		Dispatch libmapi functions into filenames matching
-		the MAPI interface they belong to.
-		
-		jkerihuel.
-	[r54]
-		Fix the attach issue by value and add torture test to
-		the openchange torture suite.
-		
-		jkerihuel.
-    texane
-	[r53]
-		attachment torture test implementation
-		
-		-- texane
-2007-02-06
-    jkerihuel
-	[r52]
-		Add a null element at the end of MAPI_REQ array
-		so we can exit from the loop in ndr_print_mapi_request
-		
-		jkerihuel.
-	[r49]
-		- Add the DeleteMessages IDL
-		- New torture tests added:
-			* OPENCHANGE-MAPI-SENDMAIL
-			* OPENCHANGE-MAPI-DELETEMAIL
-		
-		These are experimental implementation
-		
-		jkerihuel.
-    texane
-	[r51]
-		subject option for delete message torture test
-		
-		-- texane
-	[r50]
-		added (recipients == null) check
-		added default body
-		added default subject
-		-- texane
-2007-02-03
-    jkerihuel
-	[r48]
-		Add NspiResolveNames and the associated torture test.
-		
-		jkerihuel.
-2007-02-01
-    jkerihuel
-	[r47]
-		Fix nspi decoding problem due to the usage of
-		a hyper instead of a dlong.
-		
-		jkerihuel.
-	[r46]
-		- Add a preliminary NspiUpdateStat IDL
-		- Fix the new server code convention naming 
-		(function prefixed with dcesrv_)
-		- Fix a security bug in emsabp provider code
-		
-		jkerihuel.
-	[r45]
-		Fix the allocation memory for the EcDoRpc_{MAPI_REQ,MAPI_REPL} pointer.
-		
-		jkerihuel.
-	[r44]
-		Add SetProps [out] support.
-		
-		Temporary allocation pb fixed in ndr_pull_mapi_response.
-		Final fix in next commit.
-		
-		jkerihuel.
-2007-01-31
-    jkerihuel
-	[r43]
-		Fix the SetProps [in] IDL
-		
-		New mapi call support added:
-		- ModifyRecipients [in,out]
-		- SubmitMessage [in,out]
-		
-		jkerihuel.
-	[r42]
-		Add IDL support for the following mapi calls:
-		
-		[in] CreateMessage
-		[in] SetProps
-		
-		The SetProps IDL is still experimental and the
-		content blob should be decoded more than the current 
-		IDL does.
-		
-		jkerihuel.
-2007-01-30
-    jkerihuel
-	[r41]
-		Fix the align problem in QueryRows reply blob
-		Add some printing output and clean useless DEBUG.
-		
-		jkerihuel.
-2007-01-29
-    jkerihuel
-	[r40]
-		Fix the OpenMessage IDL and add ndr_print support
-		to the MAPI-FETCHMAIL torture test so we can
-		read information.
-		
-		jkerihuel.
-	[r39]
-		Commit of the first experimental but working implementation
-		of the MAPI-FETCHMAIL torture test able to retrieve mails
-		from an Exchange Server.
-		
-		jkerihuel.
-	[r38]
-		- Add a preview implementation of cached data system for multi MAPI calls requests
-		- Add SetColumns and QueryRows calls to mapi.c + mapi_fetchmail torture test
-		- Enhance some MAPI calls IDL
-		- Fix some pull/print functions according to error_code and row_count values
-		
-		jkerihuel.
-2007-01-28
-    jkerihuel
-	[r37]
-		Manual handling of EcDoRpc_MAPI_REPL pull and print function.
-		When a mapi call returns an error_code different from MAPI_E_SUCCESS,
-		we have to stop processing the function IDL since no parameters follow.
-		
-		jkerihuel.
-	[r36]
-		add MAPISTATUS to EcDoRpc_MAPI_REPL
-		add mapi library code for:
-		- OpenFolder
-		- Release
-		- GetContentsTable
-		- GetReceiveFolder
-		
-		add mapi calls described above to MAPI-FETCHMAIL torture test
-		
-		jkerihuel.
-	[r35]
-		add mapi_response to emsmdb_transaction so we can get the results
-		check the mapi call error core in OpenMsgStore
-		
-		jkerihuel.
-	[r34]
-		Add MAPISTATUS field in each mapi calls
-		Add new MAPICODE (MAPI_E_CALL_FAILED)
-		
-		jkerihuel.
-	[r33]
-		Fix the mapi_request push function
-		Add a first approach to the MAPI client side library
-		Add a first approach of the MAPI-FETCHMAIL torture test
-		Fix the smb.conf.example with new fields and remove Samba4 unused ones
-		
-		jkerihuel.
-2007-01-27
-    jkerihuel
-	[r32]
-		Initial mapidump commit
-		OpenMessage IDL fixed
-		
-		jkerihuel.
-2007-01-24
-    jkerihuel
-	[r31]
-		Unused and dummy code removed
-		
-		jkerihuel
-	[r30]
-		- Remove the MAPI decoding TDR layer and associated functions
-		- Add MAPI decoding in exchange.idl at NDR layer
-		- mapi_request / mapi_response pull/print ok
-		- implement subcontext for async response decoding in
-		some EcDoRpc IDLs.
-		- new MAPITAGS added related to Message envelope properties
-		- clean up the code and remove unused files
-		
-		- Add new MAPI opnums and associated IDL:
-			* [in]     Release          (opnum=0x1)
-			* [in,out] OpenFolder       (opnum=0x2)
-			* [in,out] OpenMessage      (opnum=0x3)
-			* [in,out] GetContentsTable (opnum=0x5)
-			* [in,out] GetProps         (opnum=0x7)
-			* [in,out] Secolumns        (opnum=0x12)
-			* [in,out] QueryRows        (opnum=0x15)
-			* [in,out] GetReceiveFolder (opnum=0x27)
-			* [in,out] OpenMsgStore     (opnum=0xFE)
-		
-		** WARNING  **
-		
-		1. Assumption
-		==============
-		For IDL with unknown fields followed the IDL may 
-		change and the mapping of these unknown bytes incorrect. 
-		It's just based on assumptions and results of the different
-		wireshark captures.
-		
-		2. Broken Code
-		==============
-		- The mapi_request / mapi_response pull function
-		- emsmdb torture tests and libmapi/emsmdb.c
-		
-		All this code is currently broken and will be fixed
-		when we start writing the new emsmdb torture suite
-		using the new API.
-		
-		
-		jkerihuel
-2007-01-22
-    jkerihuel
-	[r29]
-		Fix ndr_pull_MAPI_DATA function
-		
-		jkerihuel.
-	[r28]
-		- Add new mapi opnums
-		- Add a first IDL implementation for OpenMsgStore out
-		
-		jkerihuel.
-	[r27]
-		- Enhance the handles id support in MAPI_DATA
-		- Remove unused code
-		
-		EMSMDB encoding/decoding is currently broken.
-		It will be fixed when we start the client side
-		mapi library implementation.
-		
-		jkerihuel.
-2007-01-21
-    jkerihuel
-	[r26]
-		- Change IMAPISession.idl to mapi.idl
-		- enhance mapi content payload decoding (multiple calls supported)
-		- add sub EcDoRpc opnums and IDL for setcolumns (in)
-		
-		jkerihuel
-    pkhun
-	[r25]
-		
-		- memory leak fixed
-		- new function on emsabp provider for entry id generation
-		
-		pkhun
-2006-12-27
-    jkerihuel
-	[r24]
-		Old mapitables code deleted and merge of the samdb
-		code used in openchange (emsabp_result_guid function).
-		
-		The following revision compiles and work fine with
-		Samba4 revision 20341
-		
-		jkerihuel.
-2006-12-17
-    pkhun
-	[r23]
-		
-		Instance keys management changed (we now use struct instance_key and uint32_t instead of an array of 4 uint8_t)
-		
-		pkhun
-2006-12-15
-    jkerihuel
-	[r22]
-		- Fix compilation warnings based on patches provided 
-		by Stefan Huehner <stefan at huehner.org>
-		- Fix the DSO issue for x64 platforms
-		- Add the evolution plugin in the compilation process
-		- remove the mapidump code (obsolete and replaced with ndrdump usage)
-		
-		jkerihuel.
-2006-12-13
-    jkerihuel
-	[r21]
-		evolution plugin moved into client/evolution for
-		a correct and extensible naming convention.
-		
-		EcDoRpc IDL modified:
-		- opnum are now 8 bits
-		- action enum added 
-		- EcDoRpc ndrdump output enhanced
-		
-		IMAPISession IDL modified:
-		- Change OpenMsgStore function name to MAPI_RPC_LOGON
-		for the 0xFE opnum operation.
-		
-		Fix warnings in the code.
-		
-		jkerihuel.
-2006-12-09
-    loic
-	[r20]
-		Openchange-Evolution plugin commit
-		I reorganized openchange evolution plugin source tree.
-		Now we have one directory for the camel-openchange provider, and one for the openchange eplugin.
-		Everything can be found in the oc-evolution directory.
-		This is code a minimalist implementation of the camel provider for evolution.
-		It will make appears an openchange server type in the server list handled by evolution.
-		Still have to fix the ./configure to create a Makefile though.
-2006-12-05
-    jkerihuel
-	[r19]
-		Fix the memory allocation problems in the emsmdb torture test
-2006-12-03
-    jkerihuel
-	[r17]
-		Removed ascstr and directly add it to the IDL
-	[r16]
-		Fix the NspiQueryRows response where strings
-		containing the user email address have to be
-		NULL terminated.
-		
-		The EMSABP provider is working ;-)
-    pkhun
-	[r18]
-		
-		The emsabp provider is now able to return multiple users
-		when searching for part of a username.
-		
-		pkhun
-2006-11-30
-    jkerihuel
-	[r15]
-		Fix the networkAddress binding strings for the
-		Exchange object in the configuration db. The
-		SERVER variable based on exchange:server had
-		been added while we needed the NETBIOSNAME one
-		
-		Fix a segmentation fault in emsabp.c due to an
-		unchecked pointer res->msgs. This was causing
-		smbd to segfault when the supplied legacyExchangeDN
-		sent by the user wasn't present in the database.
-		
-		jkerihuel
-2006-11-27
-    jkerihuel
-	[r14]
-		Remove unused files and directory.
-		Update Makefile.in and remove storedb compilation
-		rules.
-    pkhun
-	[r13]
-		
-		Fixed :
-		- NspiQueryRows
-		- NspiDNToEph
-		- NspiGetProps
-		- provisioning (for the legacyExchangeDN of the server entry)
-2006-11-26
-    jkerihuel
-	[r11]
-		Fix the build and remove dynconfig samba lib
-		dependency.
-		
-		jkerihuel
-    pkhun
-	[r12]
-		Unused ldif files removed + Schemas definitions updated
-		
-		pkhun
-	[r10]
-		Provisionning fixed (old ldif files cleaned)
-		
-		pkhun
-2006-11-22
-    jkerihuel
-	[r9]
-		add tags rules to the Makefile
-		
-		jkerihuel.
-	[r8]
-		add the \\pipe\\protected_storage named pipe
-		to exchange_nsp bindings
-		
-		jkerihuel.
-2006-11-21
-    jkerihuel
-	[r7]
-		Add a dcerpc_server module in charge of the 
-		exchange interfaces registration. When this module
-		is loaded prior the remote endpoint, it let us proxify 
-		the exchange_nsp and exchange_emsmdb ones.
-		
-		Change the exchange_nsp ncacn_np binding string to
-		reflect how Exchange server is currently using it.
-		
-		Conform the IDL with latest pidl requirements and
-		move the MAPI_DATA structure from exchange_nsp to
-		exchange_emsmdb.
-		
-		jkerihuel
-2006-11-14
-    jkerihuel
-	[r6]
-		Create the $prefix/modules/{dcerpc_server,torture}
-		directories.
-		
-		This fix openchange make install rule.
-		
-		jkerihuel.
-	[r5]
-		This commit conforms openchange with the Samba4
-		trunk and fix the autotools checks.
-		
-		I've modified the openchange torture file to
-		match the current smbtorture API and the
-		OPENCHANGE-NSPI-PROFILE test was successful.
-		
-		The NSPI ndrdump suite has fully been tested and
-		works correctly.
-		
-		jkerihuel.
-2006-11-05
-    jkerihuel
-	[r3]
-		This commit fix the build system:
-		- add the -ldynconfig dependency to LDFLAGS
-		- add header checks in configure.ac. We need them
-		for the moment cause Samba4 doesn't install some headers
-		required by openchange core
-		- fix the make install
-		
-		- remove autotools generated files and definitively
-		ignore them with the .svnignore file
-		
-		- keepref keyword removed from exchange_nsp interface
-		
-		jkerihuel.
-    pkhun
-	[r4]
-		+ aclocal.m4 removed from repository
-		+ provisionning fixed
-		
-		pkhun.

Added: trunk/openchange/ChangeLog
===================================================================
--- trunk/openchange/ChangeLog	                        (rev 0)
+++ trunk/openchange/ChangeLog	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,5859 @@
+2010-02-09
+    jkerihuel
+	[r1715]
+		Add canonical names for codepage related properties (involved in
+		PT_STRING8 encoding/decoding)
+
+2010-02-08
+    jkerihuel
+	[r1711]
+		- Add parser for codepage-lcid
+		
+		- Add entire set of conversion functions for lcid, codepage, language
+		  and locale
+		
+		- mapiprofile now uses codepage/lcid matching LC_CTYPE environment
+		  variable for language detection, otherwise codepage/lcid matching
+		  language list. Language list is now dumped from codepage-lcid
+		  auto-generaed code.
+		
+		- Remove deprecated util and tests directory from libmapi and from
+		  build system. We now only rely on codepage_lcid.c
+		
+		- Update openchange code (utils, mapiprofile, mapitest and
+		  exchange2ical libs) to use this new API.
+		
+		- I have not looked into icalparameter_get_language, but assuming it
+		  is relying on previous API, I may have introduced a bug here. Looks
+		  like the function outputs for example "en-US" while we now checks
+		  for "en_US" to match setlocale output.
+    bradh
+	[r1710]
+		Minor API documentation adds.
+	[r1709]
+		Add unit test coverage for the GetGALTable() function.
+		
+		This is mostly lifted from utils/openchangeclient.c
+	[r1708]
+		Switch to only building Qt4 bindings if specifically asked for.
+		
+		This is a bit experimental for now, so lets go safer...
+
+2010-02-05
+    jkerihuel
+	[r1706]
+		In this particular case (error returned, mapi_response shouldn't
+		be free'd)
+	[r1705]
+		Fix bug 605827 - SRowSet was free'd while still needed
+
+2010-02-04
+    jkerihuel
+	[r1703]
+		Template file which associates Language, LCID, Locale and Codepage.
+		Furthermore commits will implement the mparse parser which will
+		auto-generate the associated C files. This should give us a reliable
+		way to use it in mapiprofile, MAPI profiles database and for
+		PT_STRING8 proper conversion purposes.
+		
+		If anything is missing or is incorrect, updating the file will
+		be trivial.
+
+2010-02-03
+    bradh
+	[r1701]
+		Fix bug where you couldn't select another messages in the default folder without
+		changing folder first.
+		
+		Looks like this is just a bit I forgot to update when changing from an initial
+		cut to the "more working" implementation.
+
+2010-02-02
+    jkerihuel
+	[r1699]
+		- Fix trac ticket #183: PT_UNICODE properties are now turned to UTF-8
+		  directly.
+		
+		- Remove deprecated utf8_convert lexer and windows_to_utf8 routine
+		
+		- Change openchange tools to use _UNICODE tag version instead
+		
+		- octool_get_propval now prefer UNICODE properties over PT_STRING8
+		  ones (default behavior).
+		
+		- Change mapidump_message API to take an optional mapi_object_t
+		  message parameter. If the message object is specified, we can have
+		  access to the subject, and recipients (to, cc, bcc) without having
+		  to query them within a GetProps call.
+    bradh
+	[r1698]
+		Fix an ugly cut-n-paste error.
+	[r1697]
+		Add pkg-config support for libmapi++.
+
+2010-02-01
+    jkerihuel
+	[r1695]
+		Fix ticket #123 (known as 562948 on gnome bugzilla):
+		"Unable to send mails containing UTF8 strings"
+		
+		OpenChange was using strlen(str) * 2 + 2 to calculate the 
+		expected size for utf16 string. This patch fixes this and
+		replaces it with a function that make proper utf8 to utf16 
+		conversion.
+		
+		This commit also replaces PT_STRING8 properties in openchangeclient.c
+		with PT_UNICODE ones to ensure utf8 strings get converted properly.
+
+2010-01-26
+    jkerihuel
+	[r1693]
+		- Add NormalizedSubject and SubjectPrefix strings to object_message_t
+		  structure.
+		- Add a function to retrieve TypedString value
+		- Add a mapidump function for obj_message (only retrieve subject and
+		  recipients)
+		- Add --fetchsummary option to openchangeclient: Dumps properties from
+		  OpenMessage response only (subject and recipients) rather than going
+		  through GetProps and dumping a more complete version.
+    bradh
+	[r1692]
+		Move make distclean to the end again.
+
+2010-01-23
+    bradh
+	[r1690]
+		Remove a copy of the dlinklist.h header, and just use the samba
+		version instead.
+
+2010-01-20
+    bradh
+	[r1688]
+		Install missing file.
+
+2010-01-13
+    bradh
+	[r1686]
+		Allow us to find samba python code on 64-bit machines.
+
+2010-01-10
+    jkerihuel
+	[r1684]
+		Update EcDoConnectEx IDL to match latest specifications
+    bradh
+	[r1683]
+		Minor additions to "make clean" / "make distclean" to remove
+		generated python bits, and also the config.h file.
+
+2010-01-08
+    bradh
+	[r1681]
+		Implement IsMailboxFolder for public folder types.
+		
+		Involves some refactoring of the way we handled the mapi_object_store_t,
+		such that we now talloc_zero the structure. 
+		
+		Adds mapitest coverage for these.
+		
+		Resolves Ticket #134.
+
+2010-01-06
+    bradh
+	[r1679]
+		Add unit tests for IsMailboxFolder
+		
+		Also use 0xFFFFFFFFF instead of -1 for no-such-mailbox, consistent with the unsigned data type.
+
+2010-01-04
+    jkerihuel
+	[r1677]
+		Change location of .cpp.o and .ccp.po to the correct location
+		and inhibit compilation line output for moc and cpp compilation.
+    bradh
+	[r1676]
+		Try harder to clean up libmapi++ bits.
+
+2010-01-03
+    jkerihuel
+	[r1673]
+		Ignore moc files and generated binary
+	[r1672]
+		Update OpenChange version to 0.10 NOMAD
+		
+		Nomad is a mechanical explorer sent from Earth in 2002. 
+		It was melded with an alien device named Tan Ru and the resulting robotic
+		hybrid began destroying anything that was imperfect including, in 2267,
+		itself. 
+    bradh
+	[r1674]
+		Add documentation for qt/ subdirectory.
+	[r1671]
+		Try harder to find moc.
+	[r1670]
+		Initial commit of some Qt-style bindings.
+		
+		This is mostly for testing, although hopefully the library will
+		emerge with a set of mostly-useful widgets for implementing
+		real clients.
+
+2009-12-31
+    bradh
+	[r1668]
+		Quiet the build here.
+		
+		Inadvertent removal in a previous patch.
+	[r1667]
+		Some support for ReviewBoard.
+
+2009-12-29
+    bradh
+	[r1665]
+		Update OpenMessage flags to match specification values.
+	[r1664]
+		Cleanup libmapi++ code when we "make clean".
+	[r1663]
+		Add svn ignore entries.
+	[r1662]
+		Remove inline from shared library class.
+		
+		Fixes build on Intel C++ compiler.
+
+2009-12-27
+    clsk
+	[r1660]
+		libmapi++ is no longer a header-only library
+
+2009-12-26
+    bradh
+	[r1658]
+		Add first part of Restrictions support.
+	[r1657]
+		A little more documentation fixes.
+2009-12-25
+    jkerihuel
+	[r1654]
+		Fix MAPIUninitialize() crash when leaving after an unsuccessful call.
+		In such situation, mapi_response is not allocated but has a destructor
+		associated. This fix removes the destructor whenever the error code is
+		different from MAPI_E_SUCCESS.
+		
+		Also add a minor (probably useless) check on mapi_response pointer validity
+		before attempting any other child's free.
+    bradh
+	[r1656]
+		A couple of minor API documentation fixes.
+
+2009-12-24
+    jkerihuel
+	[r1651]
+		Rename libmapi into openchange in our release script.
+		Makes more sense given the scope of our releases.
+	[r1650]
+		Fix format string warnings.
+	[r1649]
+		New ModifyRecipients IDL and implementation.
+		
+		This patch improves the logic within the RecipientFlags bitmask
+		calculation function and make use of different MAPI properties for
+		ModifyRecipients. 
+		
+		Fix trac ticket #125 and https://bugzilla.gnome.org/show_bug.cgi?id=568763
+    bradh
+	[r1648]
+		Minor API documentation fix.
+2009-12-23
+    bradh
+	[r1647]
+		Fix some exchange2ical memory leaks / "still reachable" memory.
+	[r1645]
+		Fix property tag array count, so we get the language in Summary
+		lines in the ical output.
+	[r1644]
+		Add protection against null CN values.
+		
+		Resolves ticket #232.
+		
+		Thanks to Arnout Engelen for the bug report and the patch to fix the problem.
+	[r1643]
+		Handle all day events for UTC+  timezones.
+		
+		This resolves ticket #217. Thanks to Arnout Engelen for both reporting
+		the problem, and providing a patch. In the end I heavily modified the 
+		patch, and implemented a much simpler version while we sort out the
+		timezone identifier problems.
+
+2009-12-22
+    bradh
+	[r1641]
+		Minor documentation update to reflect GSoC exchange2ical merge.
+	[r1640]
+		temporary fix for building on FreeBSD 7.2.
+	[r1639]
+		Remove this file - converted it to trac tasks.
+2009-12-21
+    jkerihuel
+	[r1635]
+		Patch from Johnny Jacob <johnnyjacob at gmail.com>:
+		
+		Changed MonitorNotification to be non-blocking.
+		Also checks whether to process notifications using a callback.
+	[r1634]
+		Open Profile Store using global_mapi_ctx for the memory context. This
+		fix removes 20 context errors when running valgrind on mapitest.
+	[r1633]
+		- Fix important memory leaks in OpenChange NSPI stack. The memory
+		  context modifications applied to the EMSMDB stack have been
+		  propagated to the NSPI one. NSPI dcerpc_* functions now rely on a
+		  temporary context passed in parameter to the nspi_* functions from
+		  libmapi/nspi.c.
+		
+		- Changes propagated to torture, mapitest, IProfAdmin interface and
+		  ResolveNames function to match the internal API.
+		
+		- Add missing MAPIFreeBuffer call in mapitest modules
+	[r1632]
+		Minor cosmetic change
+	[r1631]
+		Minor changes to match our coding convention more closely
+	[r1630]
+		Return (const void *) instead of (void *) where missing
+	[r1629]
+		- Fix important memory leaks within the OpenChange stack. Most of the
+		  leaks came from the pipe memory context used in emsmdb_transaction
+		  which was only released on MAPIUninitialize and sometimes leaded in
+		  lost blocks. This fix makes extensive usage of the temporary memory
+		  context used in top MAPI calls implementation. This context is
+		  passed in argument to emsmdb_transaction and used for dcerpc_*
+		  operations.
+		
+		  When we return from any libmapi call implementation, this context is
+		  destroyed. This guarantee no extra memory within NDR layer is kept.
+		
+		  The only requirement for this patch to work is to make sure the data
+		  we return from MAPI calls is either reparent to another memory
+		  context or copied properly.
+    bradh
+	[r1638]
+		Add support for skipping tests that don't apply to some
+		server versions.
+	[r1637]
+		Change the format of the server version, so it matches the Microsoft
+		way of doing versions.
+
+2009-12-20
+    jkerihuel
+	[r1627]
+		Fix store version info assignment - Exchange version now works again
+		in mapitest.
+	[r1626]
+		Clarify the developer's task when using GetPropList.
+		
+		We were allocating the SPropTag proptag array with the session context
+		pointer, which was not released with a MAPIFreeBuffer(SPropTagArray).
+		
+		We are now using SPropTagArray pointer as parent context and clarify
+		that the developer must pass an allocated SPropTagArray pointer to the
+		function.
+	[r1625]
+		Missing mapi_object_release leading in small leaks.
+	[r1624]
+		Sanitize RfrGetNewDSA function and memory usage.
+		
+		The function was returning either a const char * passed in parameter
+		or the string returned by RfrGetNewDSA call. Furthermore we were using
+		the session pointer for the memory context. Finally the function description
+		was not matching its behavior.
+		
+		What this patch does:
+		- use a named memory context for RfrGetNewDSA call
+		- return an allocated string on success otherwise NULL
+		- release RFR memory context properly
+		
+		valgrind before patch (mapitest):
+		==28876== LEAK SUMMARY:
+		==28876==    definitely lost: 0 bytes in 0 blocks
+		==28876==    indirectly lost: 0 bytes in 0 blocks
+		==28876==      possibly lost: 3,193,529 bytes in 23,296 blocks
+		==28876==    still reachable: 345 bytes in 2 blocks
+		==28876==         suppressed: 0 bytes in 0 blocks
+		==28876==
+		==28876== For counts of detected and suppressed errors, rerun with: -v
+		==28876== ERROR SUMMARY: 2351 errors from 2351 contexts (suppressed: 45 from 10)
+		
+		valgrind after patch (mapitest):
+		==29083== LEAK SUMMARY:
+		==29083==    definitely lost: 0 bytes in 0 blocks
+		==29083==    indirectly lost: 0 bytes in 0 blocks
+		==29083==      possibly lost: 3,190,285 bytes in 23,256 blocks
+		==29083==    still reachable: 345 bytes in 2 blocks
+		==29083==         suppressed: 0 bytes in 0 blocks
+		==29083==
+		==29083== For counts of detected and suppressed errors, rerun with: -v
+		==29083== ERROR SUMMARY: 2338 errors from 2338 contexts (suppressed: 45 from 10)
+	[r1623]
+		This patch fixes most of the leaks coming from pull_emsmdb_property() function.
+		pull_emsmdb_property is using pointers and allocate memory to prevent from
+		returning a local variable address. Such pointers include PT_I2, PT_I8, PT_LONG, 
+		PT_ERROR or PT_BOOLEAN. Pointer's values are assigned in set_SPropValue but were
+		never released/free'd. This patch implements free_emsmdb_property to fix this problem.
+		
+		valgrind before patch (mapitest):
+		==26674== LEAK SUMMARY:
+		==26674==    definitely lost: 0 bytes in 0 blocks
+		==26674==    indirectly lost: 0 bytes in 0 blocks
+		==26674==      possibly lost: 3,264,485 bytes in 23,387 blocks
+		==26674==    still reachable: 345 bytes in 2 blocks
+		==26674==         suppressed: 0 bytes in 0 blocks
+		==26674==
+		==26674== For counts of detected and suppressed errors, rerun with: -v
+		==26674== ERROR SUMMARY: 2370 errors from 2370 contexts (suppressed: 45 from 10)
+		
+		valgrind after patch (mapitest):
+		==27270== LEAK SUMMARY:
+		==27270==    definitely lost: 0 bytes in 0 blocks
+		==27270==    indirectly lost: 0 bytes in 0 blocks
+		==27270==      possibly lost: 3,127,733 bytes in 23,293 blocks
+		==27270==    still reachable: 345 bytes in 2 blocks
+		==27270==         suppressed: 0 bytes in 0 blocks
+		==27270==
+		==27270== For counts of detected and suppressed errors, rerun with: -v
+		==27270== ERROR SUMMARY: 2348 errors from 2348 contexts (suppressed: 45 from 10)
+    bradh
+	[r1622]
+		Minor API documentation fixes.
+
+2009-12-19
+    jkerihuel
+	[r1620]
+		- Add a macro to mparse.pl to free both mapi_response 
+		  and mem_ctx within OpenChange calls implementation.
+		  For the moment it is only implemented in OpenUserMailbox call.
+		
+		- Fix a memory leak in OpenUserMailbox: When the call failed 
+		  (ecUnknownUser or ecUseEnryption) mapi_response was not free'd
+		  properly.
+	[r1619]
+		Minor indentation fix
+    bradh
+	[r1618]
+		Add some missing newlines to reduce compilation noise.
+	[r1617]
+		Merge in Ryan Lepinski's Google Summer of Code work on exchange2ical.
+		
+		See the gsoc_exchange2ical branch history for commits.
+		
+		I also made a change to address ticket #216, and
+		fixed a couple of typos.
+
+2009-12-18
+    bradh
+	[r1615]
+		Minor updates to provisioning instructions.
+		
+		Thanks to Girish Venkatachalam for some suggestions.
+
+2009-12-17
+    jkerihuel
+	[r1611]
+		Fix 'unused variable' warning on FreeBSD for exchange2mbox
+    bradh
+	[r1613]
+		Add documentation for the --freebusy option.
+	[r1612]
+		Warning fix.
+
+2009-12-16
+    jkerihuel
+	[r1607]
+		Fix segfaults in mapitest launched with exchange2010
+	[r1606]
+		Fix compilation warnings
+    bradh
+	[r1609]
+		Add missing -L directory specifier.
+		
+		Looks like this was tolerated by gnu ld, but not by opensolaris ld.
+		
+		Patch by Brian Lu (Sun). Thanks again.
+	[r1608]
+		Add documentation for new mapiprofile --encrypt option, introduced in r1602.
+	[r1605]
+		Fix a couple of typos that trash CFLAGS during build.
+
+2009-12-15
+    jkerihuel
+	[r1603]
+		Automatically switch from connect to seal on the emsmdb pipe if
+		ecNotEncrypted is returned by EcDoConnect.
+	[r1602]
+		- Make OpenChange natively working with Exchange 2010
+		- Factorize binding string construction code within a single function
+		- the seal flag is mandatory to connect to Exchange 2010
+		- add seal boolean value to MAPI profile creation and mapi_profile
+		  structure
+		- add --encrypt option to mapiprofile to set the seal value
+
+2009-12-14
+    bradh
+	[r1600]
+		Add documentation for set_SPropTagArray().
+		
+		Thanks to Brian Lu (Sun) for reporting.
+
+2009-12-13
+    jkerihuel
+	[r1598]
+		This doesn't really fix ticket #149, but this should
+		at least prevent from triggering segmentation fault when
+		PR_EMAIL_ADDRESS_UNICODE doesn't have any cn=Recipients,cn= substring 
+    bradh
+	[r1597]
+		Trivial fix (newline) for warning on FreeBSD compiler.
+	[r1596]
+		Add support for manually creating the library symlinks for FreeBSD
+		
+		This is a somewhat speculative commit. 
+		
+		Also fixes a couple of cosmetic whitespace issues.
+
+2009-12-12
+    jkerihuel
+	[r1594]
+		Patch from Bryan Lu <brian.lu at sun.com>:
+		
+		Create symbol link only on Solaris
+		
+		This closes ticket #221 and makes it possible to compile openchange
+		on Solaris.
+	[r1593]
+		Temporary bug fix in emsabp.c - If restrictions are NULL in
+		emsabp_search, return MAPI_E_INVALID_OBJECT. This prevents from using
+		invalid res pointer leading in segmentation fault.
+		
+		Initial fix proposed by Erik Hovland <erik at hovland.org>
+	[r1592]
+		Patch from Erik Hovland <erik at hovland.org>:
+		
+		fid might be null. Check it before dereferencing in the
+		ocpf_folder_lookup() call. Similar behavior fixed in openchangeclient
+		folder_lookup() function.
+	[r1591]
+		Patch from Erik Hovland <erik at hovland.org>:
+		
+		NotificationData 'could' be null. Check it before handing it to
+		notification-callback(). This is important because eventually
+		NotificationData will be dereferenced in the code path.
+	[r1590]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		Fix MAPI Warning error codes
+	[r1589]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		bugfix: Bugs in abp_tdb layer fixed.
+		
+		emsabp_tdb_traverse_MId() returns 'false' (i.e. not found) in most of
+		the cases.
+	[r1588]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		Implement NspiQueryRows() address list enumeration
+		
+		We can now run openchangeclient --userlist on OpenChange NSPI server
+		and Outlook 2003 is able to query GAL.
+		
+		Note: the initial patch was proposing:
+		"(&%s(showInAddressBook=*))", purportedSearch
+		
+		I replaced it with "%s", purportedSearch only since we don't have yet
+		any showInAddressBook attribute in AD.
+	[r1587]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		- Add server side implementation for NspiResolveNamesW
+		- Refactor and split emsabp_verify_user in two functions
+		
+		A new function emsabp_get_account_info() implemented to fetch info
+		about given user name.  emsabp_verify_user() uses the above function
+		check if authenticated account_name is valid mail account and if so,
+		account_name is cached in emsabp context for future use
+	[r1586]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		NspiGetProps() reimplemented to match [MS-NSPI] specification more
+		closely.
+		
+		As a side-effect, emsabp_fetch_attrs() was altered to return
+		MAPI_E_INVALID_BOOKMARK in case requested MId is not found.  This way
+		the function returns more meaningful error codes - if requested MId is
+		not found this surely means InvalidBookmark rather than CorruptStore
+
+2009-12-11
+    jkerihuel
+	[r1584]
+		Path from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		Propagate dwFlags for incoming call to get EntryIDs correctly.
+		
+		Actually we need to propagate dwFlags so that emsabp_query()
+		function to be able to determine whether EphemeralEntryID
+		or PermanentEntryID is requested to be built.
+	[r1583]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		Implement PR_SEARCH_KEY attribute getter
+	[r1582]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>
+		
+		Add PR_ADDRTYPE_UNICODE and PR_EMS_AB_PROXY_ADDRESSES_UNICODE getters.
+	[r1581]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		- Extend NspiDNToMId() to search in Configuration and Domain
+		  partitions.
+		
+		- NspiDNToMId() has been extended to cache returned data properly,
+		  i.e. DNs from Configuration partition are cached in ttb_ctx db, DNs
+		  from Domain partition are cached in in-memory db ttdb_ctx.
+	[r1580]
+		Patch from Kamen Mazdrashki <kamen.mazdrashki at postpath.com>:
+		
+		emsabp_set_PermanentEntryID() implements MS specification more
+		closely.  For reference: [MS-NSPI] and [MS-OXOABK]
+	[r1579]
+		- Replace emsabp_get_server_GUID with samdb_ntds_objectGUID Samba4
+		  function.
+		- Change the way we initially fetched server GUID
+		
+		Credits to Kamen Mazdrashki <kamen.mazdrashki at postpath.com> for
+		initial patch and associated research:
+		
+		It turns out MS implementation for NSPI reads the guid from: "CN=NTDS
+		Settings,CN=<NETBIOS_NAME>,CN=Servers,CN=Default-First-Site-Name,CN=Sites,<CONFIG_DN>" entry.
+	[r1578]
+		Fix samdb_connect warning.
+		Add function prototype to nsp,emsmdb header files.
+		Change samdb_ctx from void * to ldb_context *
+    bradh
+	[r1577]
+		Update docs to match those in mapiproxy doxygen docs.
+	[r1576]
+		Roll to the latest Samba4 version.
+		
+		This should have no noticeable difference over the
+		Samba4 alpha9 release, but its nice to use the latest
+		version, and it might make a difference on the server
+		side.
+2009-12-10
+    jkerihuel
+	[r1575]
+		Fix OpenChange server code and access to Samba4 databases.
+		Starting with samba4-alpha9, there is no more configuration.ldb or users.ldb.
+		All information can be accessed through a single access to SamDB and configuration records
+		accessed through ldb_get_config_basedn.
+		
+		The following implementation has been tested and is working with:
+		- mapiprofile profile creation
+		- openchangeclient --mailbox
+		- Outlook 2003 account creation
+		- Outlook 2003 mailbox opening
+
+2009-12-09
+    jkerihuel
+	[r1573]
+		Fix openchange user provisioning scripts
+	[r1572]
+		Forgot to commit this LDIF modifications for openchange provisioning
+
+2009-12-08
+    jkerihuel
+	[r1570]
+		- Fix OpenChange server provisioning (exchange classes and attribute only)
+		- Remove deprecated provisioning steps
+		- OpenChange user provisioning is still broken at this point, but will be
+		fixed in further revisions.
+
+2009-12-02
+    jkerihuel
+	[r1568]
+		Fix a cast warning at compilation time for libmapi++
+	[r1567]
+		- Update openchange libraries to 0.9: close trac ticket #165
+		- Propagate pkgconfig solution in trac ticket #94 to other libs
+	[r1566]
+		- Update openchange code to work with samba4-alpha9 release
+		- Apply minor fix to ldb_wrap_connect (number of parameters)
+		- Update mapiproxy code to handle new Samba4 assoc_group implementation properly
+		- Update samba4 version script to match alpha9 and related git commit
+
+2009-11-27
+    bradh
+	[r1564]
+		Ensure we get output if sqlite3 isn't found at configure time.
+		
+		Now outputs "no" instead of a blank.
+
+2009-11-26
+    bradh
+	[r1562]
+		Fix attribution, per IRC discussion.
+
+2009-11-25
+    bradh
+	[r1560]
+		Ensure API documentation gets generated for utilities functions.
+		
+		Some undocumented stuff in here to look at later.
+	[r1559]
+		Add additional mapidump functions for notifications
+		
+		This is a patch from Johnny Jacob (Novell), with unit tests and some extra checks by me.
+		
+		Maintains good test coverage for this file.
+
+2009-11-23
+    bradh
+	[r1557]
+		Avoid use-after-free for the number of rows in the SRowSet.
+		
+		Resolves issue #212, which has the valgrind error.
+
+2009-11-22
+    bradh
+	[r1555]
+		Add test for get_proptag_value().
+	[r1554]
+		Minor cleanups for mapidump functions.
+		
+		- Add support for dumping property tags using PT_SHORT.
+		- Modify the tag for PR_whatever_ERROR results to include the _ERROR bit
+		- Minor format change for PT_BINARY (training colon)
+		- Ensure PT_SYSTIME respects the seperator value (API change)
+		- Add a conditional assert() using infrastructure introduced in r1553.
+		
+		Implement mapitest support for all of libmapi/mapidump.c
+		
+		Update openchangeclient for the API change.
+	[r1553]
+		Introduce a compile time definition that is set for SVN snapshot releases.
+		
+		The intent is to use this to protect assert() calls that indicate incomplete code.
+
+2009-11-19
+    bradh
+	[r1551]
+		Improved Sun Studio compiler support.
+		
+		Patch by Brian Lu (Sun) - thanks again.
+	[r1550]
+		Revert inadvertent part from previous commit (r1549)
+	[r1549]
+		Add coverage testing support.
+		
+		./configure now supports --enable-coverage, which builds with the right options
+		to support gcov. Also adds a new makefile target ("coverage") that runs the
+		required post-processing steps.
+		
+		Also added a test script that does a range of openchange related (client side)
+		operations. This is useful for generating the test load for coverage checks.
+		
+		So the basic recipe here is
+		1. Add the --enable-coverage option at configure time.
+		2. Do a clean build
+		3. Install it, or otherwise ensure that coverage-enabled libs are used
+		4. generate the test load (e.g. run ./script/smoketest.sh)
+		5. "make coverage"
+		6. Inspect the results in ./covresults
+
+2009-11-13
+    bradh
+	[r1547]
+		Add support for the SunStudio compiler.
+		
+		I previously special-cased the Intel C compiler, and relied on some ugly ordering requirements to
+		ensure it all worked.
+		
+		This approach is cleaner, allowing options to be build up separately for each compiler, and for
+		the C and C++ versions.
+		
+		Tested on Linux with all three compilers.
+
+2009-11-09
+    bradh
+	[r1545]
+		Adding missing include.
+		
+		Ticket #220.
+		
+		Patch from Brian Lu (Sun). Thanks very much.
+
+2009-11-07
+    bradh
+	[r1543]
+		Additional portability fixes for SunOS.
+		
+		Based on a patch (ticket #220) by Brian Lu (Sun). Thanks very much.
+		
+		I modified the patch to try to use autoconf where possible.
+		
+		Resolves ticket #220.
+	[r1542]
+		Remove MAP_FILE flag from mmap(). Looks like this is only required on really
+		old unix systems (e.g. NetBSD prior to 1.0), which we probably won't ever support.
+		
+		Patch by Brian Lu (Sun) - thanks very much.
+		
+		Partly resolves ticket #220 - still need to handle the first patch.
+
+2009-11-02
+    bradh
+	[r1540]
+		Fix build problem using Sun Studio compiler.
+		
+		Reported by Brian Lu (Sun), including a patch (Ticket #219)
+		
+		I slightly modified the patch, but nothing substantial.
+
+2009-10-21
+    jkerihuel
+	[r1538]
+		Patches provided by raboof:
+		- Ticket #213 deprecated include directive removal
+		- Ticket #214 missing sanity check
+		- Ticket #215 fix some DEBUG macro level for sain ouput
+
+2009-10-19
+    bradh
+	[r1536]
+		spello fixes.
+
+2009-10-18
+    clsk
+	[r1534]
+		Use mapi_profile_get_ldif_path to find ldif path when one is not given
+
+2009-10-09
+    clsk
+	[r1531]
+		Added libmapi++ wrapper function for CreateProfileStore
+
+2009-10-08
+    bradh
+	[r1529]
+		Update buildsystem to avoid using bash-specific (well, not sh-supported) +=
+		mechanism.
+		
+		Should allow FreeBSD to be supported.
+
+2009-10-06
+    bradh
+	[r1527]
+		Alternative solution to ticket #179, provided by Alan Alvarez.
+		
+		This alternative avoids the need for the user to clean up the string returned by what().
+		
+		Also includes a test case, which I've used to validate that the original (prior to r1524) code 
+		is faulty, and that both fixes (From Erik Hovland and from Alan Alvarez) deal with it.
+		
+		Resolves Ticket #179 (again).
+
+2009-09-26
+    bradh
+	[r1524]
+		Make sure that the string given by what() can be used. 
+		
+		Patch by Erik Hovland - thanks very much.
+		
+		Resolves ticket #179.
+	[r1523]
+		Ensure that the libmapi++ messages example works even if there is no
+		PR_CONVERSATION_TOPIC (subject).
+    jelmer
+	[r1525]
+		Add 'make dist'.
+
+2009-09-20
+    bradh
+	[r1521]
+		Modify mapi_object_set_logon_id() to be able to report errors.
+		
+		Original patch by Erik Hovland, I made some changes.
+
+2009-09-19
+    bradh
+	[r1519]
+		Implement RopReloadCachedInformation (0x10).
+		
+		Minor change to IDL (previously implemented), and adds
+		implementaiton and mapitest code.
+		
+		Also editorial comment fix in some related mapitest stuff.
+		
+		Resolves ticket #186
+	[r1518]
+		Implement GetValidAttachments ROP (0x52).
+		
+		Includes IDL, implementation and mapitest.
+		
+		mapitest also checks DeleteAttach behaviour, which I don't think we previously
+		covered anywhere. 
+		
+		Also includes a comment fix in the mapitest code.
+
+2009-09-16
+    bradh
+	[r1516]
+		Whitespace cleanup.
+		
+		Patch by Erik Hovland <erik at hovland.org>
+
+2009-09-14
+    bradh
+	[r1514]
+		Update the properties list.
+		
+		Patch from Girish Venkatachalam <girish at gayatri-hitech.com>
+
+2009-09-12
+    bradh
+	[r1512]
+		Update API to use MAPITAGS enum.
+	[r1511]
+		Update to match API change.
+	[r1510]
+		Use appropriate enum here.
+	[r1509]
+		Use enum for OpenEmbeddedMessage call.
+	[r1508]
+		Use enums where appropriate.
+	[r1507]
+		Update users of FindRow to use enums.
+	[r1506]
+		We are supposed to be returning a MAPISTATUS, so switch to using 
+		the OPENCHANGE_RETVAL_ERR macro here.
+	[r1505]
+		Use appropriate enums instead of int types.
+	[r1504]
+		Use enums instead of ints / hardcoded values.
+	[r1503]
+		Use enum types where appropriate.
+		
+		Fixes warnings from Intel C compiler.
+	[r1502]
+		Return a suitable MAPISTATUS if we can't talloc sufficient memory here.
+		
+		Fixes warning from Intel compiler.
+
+2009-09-11
+    bradh
+	[r1500]
+		Only pass "-Wmissing-prototypes -Wstrict-prototypes" to CFLAGS,
+		not to CXXFLAGS as well.
+		
+		Avoids g++ warnings.
+	[r1499]
+		Use enumerated type instead of integer.
+	[r1498]
+		Remove unreachable code.
+	[r1497]
+		Add "static" to avoid the need for additional declarations.
+		
+		Avoids noise from the intel c compiler.
+	[r1496]
+		Namespace variable in macro, so we don't get noise about shadowing a
+		declaration of "i"
+	[r1495]
+		Help icc find comparison_fn_t.
+	[r1494]
+		Match up data types in argument and format string.
+	[r1493]
+		Remove unused variable, and change a name to avoid a "shadowed declaration" 
+		warning.
+
+2009-09-10
+    bradh
+	[r1491]
+		Portability fixes for Intel C Compiler.
+		
+		Set CFLAGS early, otherwise AC_PROG_CC will set
+		CFLAGS to "-O2 -g", which later has -O3 appended, which
+		icc complains about.
+		
+		Check if we're really icc, and if so, turn off some warnings.
+		Also turn off the "FORTIFY_SOURCE" define which causes problems
+		with missing builtins.
+		
+		The warnings can (and should) be turned back on later, after we
+		fix the current issues.
+
+2009-09-02
+    bradh
+	[r1489]
+		Correct diagnostics messages.
+
+2009-08-29
+    bradh
+	[r1487]
+		Remove explicit -Wstrict-aliasing=3 from command line.
+		
+		This is implied by gcc -Wall option, and icc produces nuisance warnings
+		with it enabled (related to the -W option, not the code being compiled).
+	[r1486]
+		Fix some memory leaks and a bug in mapiprofile.
+		
+		I introduced the bug in r1467, there could be others that are similar.
+
+2009-08-24
+    bradh
+	[r1484]
+		Minor rewording of description
+	[r1483]
+		Minor cleanups.
+
+2009-08-18
+    bradh
+	[r1477]
+		Move initialisation up, to make sure everything is valid in the failure paths
+		
+		Patch by Erik Hovland. Thanks once again.
+		
+		This closes out ticket #178.
+	[r1476]
+		Remove unreachable code.
+		
+		Patch by Erik Hovland. Thanks again.
+		
+		This is the second part of ticket #177. This completes the checkin of that ticket.
+	[r1475]
+		Remove unreachable code.
+		
+		Patch by Erik Hovland. Thanks very much.
+		
+		This is the first part of ticket #177.
+
+2009-08-17
+    bradh
+	[r1473]
+		Ensure that we check the result of the operation we just performed.
+		
+		Patch by Erik Hovland. Thanks very much for continuing to provide these.
+		
+		This is the third part of the patch in ticket #177. The first two parts are yet to be addressed.
+	[r1472]
+		Make sure that return values are checked and report that given status if there is an error. 
+		
+		Patch from Erik Hovland, with minor additional changes. Thanks again for the patch.
+		
+		Resolves #176.
+	[r1471]
+		More cleanups of memory leaks for setting up database and an associated failure case.
+	[r1468]
+		fix leak in openchangeclient
+		
+		(as seen with valgrind of "openchangeclient -m")
+	[r1467]
+		Fix memory leak in mapiprofile utility
+
+2009-08-14
+    bradh
+	[r1465]
+		Ensure that when we pass --profile to mapitest, that profile
+		gets used instead of the default.
+		
+		Also fix a small memory leak when using --profile, and add some
+		extra comments.
+	[r1464]
+		Fix error handling case.
+		
+		Patch from Erik Hovland - thanks very much.
+		
+		Resolves ticket #175.
+
+2009-08-13
+    bradh
+	[r1461]
+		Remove unused enum values.
+	[r1460]
+		Remove unused code - no simple tests.
+
+2009-08-09
+    bradh
+	[r1454]
+		Update the script version of samba4 to alpha8.
+
+2009-08-05
+    jelmer
+	[r1450]
+		Add tevent to dependencies.
+
+2009-08-03
+    bradh
+	[r1448]
+		Remove unused headers.
+		
+		Patch by Erik Hovland - thanks very much,
+		
+		Resolves ticket #164.
+	[r1447]
+		Apply patch from Erik Hovland, from ticket #162.
+		
+		From the original patch:
+		"The problem is that when you do stat first w/ a file string anyone can
+		exploit the time in between to do whatever they want with the file that
+		the string is a name for. Instead, try to open straight away. Then fstat
+		w/ the file descriptor."
+		
+		I think the patch is fine, although I didn't run the torture test.
+
+2009-08-02
+    bradh
+	[r1444]
+		Avoid duplicate call to mapi_object_get_logon_id
+		
+		Based on a patch proposed by Erik Hovland, but adapted to follow the
+		pattern used in OpenStream().
+		
+		Resolves issue #163.
+	[r1443]
+		Applied modified version of patch from Erik Hovland to address unused variables.
+		
+		See http://trac.openchange.org/attachment/ticket/160/unused-values for
+		the rationale.
+		
+		This resolves #160.
+		
+		My version removes variables (rather than commenting them out) since we don't need
+		them now. I also updated the documentation for options that are no longer available
+		
+		The origin of the unused PR_FOLDER_CHILD_COUNT is a bit strange. It was introduced
+		in r808 (to resolve #103), and looks like it might have been used for debugging - no
+		impact on the code. I pulled out the whole lot.
+		
+		Tested with openchangeclient --fetchmail --folder="Sent Mail" and mapitest.
+	[r1442]
+		Use array form of delete (error identified with libmapixx-attach test, using valgrind).
+	[r1441]
+		Fix potentially unused variable.
+		
+		Tested with mapitest (even though nothing should have been affected) and
+		with libmapixx-test and libmapixx-attach under valgrind.
+		
+		Patch is remaining part of http://trac.openchange.org/ticket/153
+		
+		Thanks to Erik Hovland for the patch.
+
+2009-07-29
+    bradh
+	[r1433]
+		Remove dead / unused code.
+		
+		See http://trac.openchange.org/ticket/152#comment:1 for rationale.
+		
+		Original patch by Erik Hovland - thanks again.
+	[r1432]
+		Update test case to reflect new behaviour
+
+2009-07-18
+    jelmer
+	[r1423]
+		Link libmapistore against tdb.
+	[r1422]
+		Update copies of config.guess and config.sub.
+	[r1421]
+		Link libmapiproxy against tdb.
+	[r1420]
+		Declare a SOVERSION for libmapistore.
+	[r1419]
+		Use LDFLAGS when linking exchange2ical.
+	[r1418]
+		Create symlink for libmapistore.
+	[r1417]
+		Link libmapi against tevent since it uses tevent_context_init, link ndr_exchange.po into libmapiserver since it uses some ndr_push_* symbols.
+	[r1416]
+		Fix typo in variable name.
+
+2009-06-21
+    jelmer
+	[r1365]
+		Fix typo in Python variable name.
+	[r1364]
+		Keep separate flags for libraries around in config.mk.
+	[r1362]
+		Link libmapiserver against all libraries.
+
+2009-06-18
+    jkerihuel
+	[r1357]
+		Add some PidTag* mapping involved with Recipients and RecipientRow
+
+2009-05-28
+    jkerihuel
+	[r1350]
+		Patch from Erik Hovland <erik at hovland.org>:
+		
+		Initializes variables to make sure they aren't used uninitialized.
+		
+		Ref ticket #153
+	[r1349]
+		- Add sanity check on mapitest_common creation routines within
+		  mapitest modules
+		
+		- Apply patch from Erik Hovland <erik at hovland.org>: check return
+		  types.
+	[r1348]
+		Patch From Erik Hovland <erik at hovland.org>
+		
+		In torture_rpc_mapi_sendattach a call is made to the system function
+		read at line 199. The return value of read is assigned to read_size,
+		which happens to be of unsigned type. So if read returns -1 (which it
+		can) it will not be noticed. The patch changes the type to ssize_t
+		(signed) and checks for -1 as well as zero to break out of the loop.
+		
+		Ref ticket #156
+	[r1347]
+		Patch from Erik Hovland <erik at hovland.org>
+		
+		1. In mapiproxy, the directory handle dir will be leaked after it is
+		done being used.
+		2. exchange2mbox main() should use exit at line 785 just like all of
+		the other error paths so that we don't leak anything
+		
+		ref. ticket #157
+	[r1346]
+		Patch from Erik Hovland <erik at hovland.org>
+		
+		Adds a #include config.h to suppress compiler warnings for vasprintf
+	[r1345]
+		Patch from Erik Hovland <erik at hovland.org>:
+		
+		Make sure pointers are valid before dereferencing
+		1. lpProps 'might' be null
+		2. Add folder to variables checked before moving on.
+		4. Check nprop->guid before giving to strcmp, two times
+		6. Check definition before handing to strlen (which will dereference
+		it) Reworked this one to include talloc_free
+		7. Check MessageClass? before handing to strncasecmp
+		8. Check backend, return if null.
+		10. Don't print out anything if lpProp is null
+		11. Check attach_size before dereferencing
+
+2009-05-25
+    jkerihuel
+	[r1343]
+		Fix pull structure for QueryRows reply when no RowData is available
+
+2009-05-07
+    jkerihuel
+	[r1341]
+		- Add preliminary IDL support for Exchange 2003/2007 EMSMDB RPC calls:
+		  * EcDoConnectEx
+		  * EcDoRpcExt2
+		
+		- Add LZxpress and XorMagic support to EcDoRpcExt2 request/reply
+		  blob. However it doesn't yet support Chained calls.
+		
+		- Add AuxInfo/AUX_HEADER structures and IDL
+		
+		- Refactor mapi_request and mapi_response: move obfuscate_data calls
+		  up to the EcDoRpc layer
+
+2009-04-27
+    jkerihuel
+	[r1339]
+		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+		
+		call ProcessNotification() after each successful 
+		emsmdb_transaction() in all the libmapi calls.
+	[r1338]
+		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+		
+		Mapi notifications can occurs inside any emsmdb_transaction; currently
+		only the notification send by the server inside the
+		emsmdb_transaction_null() in MonitorNotification() are
+		parsed/processed/delivered to the appropriate callback.
+		
+		To be able to process all the received notifications, the notification
+		structure must comprise the private data to be passed to the
+		notification callback, since in the average mapi call this data is not
+		available. This patch modifies the Subscribe() call and the 
+		mapi_notification structure, adding the private_data parameter (also the 
+		related Subscribe() calls are update)  and add a libmapi call 
+		(DispatchNotifications) to force the notification dispatching in
+		a [quite] non blocking way
+
+2009-04-26
+    jkerihuel
+	[r1336]
+		Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+		
+		ProcessNotification() is ignoring the handle value contained into the
+		processed notifications. This means that if many Subscribe() calls are
+		performed on different folders but with the same flags, all the
+		registered callback are [incorrectly] signaled with each received
+		notification.
+		
+		The attached patch match the handler contained into the notification
+		message against the notification object handle to avoid such
+		replication.
+
+2009-04-23
+    jkerihuel
+	[r1331]
+		Make sure delayed authenication is not called when server mode is enabled
+    bradh
+	[r1333]
+		Update property list to reflect current OAB props.
+		
+		This deletes a few incompatible properties. Cannot determine the history of the PR_MAILBEAT_ props.
+	[r1332]
+		Fix display of Folder ID values (one is filled with ., the other is prefixed with .16 instead of being filled.
+		
+		Also remove duplicate close() of file descriptor.
+	[r1330]
+		Typo fix.
+
+2009-04-22
+    bradh
+	[r1328]
+		Warning fix.
+
+2009-04-21
+    bradh
+	[r1326]
+		Implement RopTransportNewMail (0x51).
+		
+		Includes IDL, libmapi implementation, and basic mapitest coverage.
+		
+		Also fix a few doxygen / formatting things.
+
+2009-04-19
+    jkerihuel
+	[r1324]
+		- Add Redirect buffer support for OpenMsgStore and OpenPublicFolder.
+		This commit fixes the ecWrongServer (0x478) error users encounter
+		while running openchange based software in a clustered Exchange 
+		environment.
+
+2009-04-18
+    bradh
+	[r1322]
+		Implement RopCloneStream (0x3b) and RopWriteAndCommitStream (0x90).
+		
+		Includes IDL, implementation and mapitest tests.
+
+2009-04-17
+    bradh
+	[r1320]
+		Fix Search notifications.
+		
+		MS concurred that the docs are wrong.
+		
+		Patch by Paolo Abeni - thanks very much for the
+		investigation and the patch.
+	[r1319]
+		Update GetStoreState documentation.
+	[r1318]
+		Implement RopSetPropertiesNoReplicate (0x79).
+		
+		IDL was already done. mapitest for DeletePropertiesNoReplicate was
+		reused / updated.
+
+2009-04-16
+    bradh
+	[r1316]
+		Implement (IDL, libmapi, mapitest) RopHardDeleteMessagesAndSubfolders (0x92)
+		
+		Also fix some bugs in mapitest common code, and an incorrect sanity check in CreateFolder().
+
+2009-04-15
+    bradh
+	[r1314]
+		Implement RopHardDeleteMessages (0x91). 
+		
+		Includes IDL, implementation and mapitest.
+    jelmer
+	[r1313]
+		Ignore generated property file.
+
+2009-04-13
+    bradh
+	[r1311]
+		Add PT_ACTIONS to list of data types.
+		
+		Not fully/correctly handled yet.
+
+2009-04-12
+    jkerihuel
+	[r1309]
+		- Add dcerpc_mapiproxy:delegated_auth option 
+		This option delays mapiproxy-remote server authentication when
+		the client sends the first request on a given pipe. This is
+		mandatory in order to have delegated credentials to work.
+		
+		- Factor remote connection into mapiproxy_op_connect
+
+2009-04-11
+    bradh
+	[r1307]
+		Add session state to the notification.
+		Patch by Paolo Abeni - thanks for the investigation and fix.
+		
+		Also remove a stray debug message.
+	[r1306]
+		Add a new mapitest suite for OXCNOTIF (Core Notifications).
+		
+		Add a test to the OXCNOTIF suite based on test case provided by Paolo Abeni.
+
+2009-04-10
+    bradh
+	[r1304]
+		Update IDL for ModifyRules (0x41) and add IDL for 
+		UpdateDeferredActionMessages (0x57).
+		
+		This is a checkpoint commit, pending further investigation
+		into how we handle PtypRestriction and PtypRuleAction.
+
+2009-04-08
+    bradh
+	[r1302]
+		Mapitest cleanups - remove GetLastError(), and other minor edits.
+	[r1301]
+		Implement LockRegionStream and UnlockRegionStream ROPs.
+		
+		These appear to be a relatively recent addition to the 
+		documentation, possibly only used in Exchange 2007 / Outlook
+		2007.
+		
+		This is complete except for testing of whether the locking
+		actually works.
+
+2009-04-06
+    jkerihuel
+	[r1299]
+		Use parent folder full replica ID: 2 bytes instead of 1 byte
+	[r1297]
+		- Add Implementation for Logon redirect response buffer in OpenChange IDL
+		- Update libmapiserver size calculation routine for Logon call to handle this case
+
+2009-03-30
+    jkerihuel
+	[r1293]
+		Add session and logon_id to the list of parameters to copy between objects.
+		This patch fixes a problem in openchangeclient when using the --folder parameter.
+    bradh
+	[r1294]
+		Remove code relating to free'ing the bookmark returned
+		by SetCollapseState. Initial investigations with MS
+		lead me to believe that you can't free that resource.
+		
+		May be more work in this area as investigation continues.
+
+2009-03-25
+    jkerihuel
+	[r1291]
+		Fix memory leaks for functions relying on pull_emsmdb_property
+
+2009-03-16
+    jkerihuel
+	[r1289]
+		Fix emsabp valgrind errors
+
+2009-03-12
+    jkerihuel
+	[r1287]
+		Make it possible to specify a version number for release different
+		from major/minor from configure.ac
+
+2009-03-11
+    jkerihuel
+	[r1285]
+		Make it possible to open and control up to 255 mailboxes within a 
+		single MAPI session.
+		
+		It implements an internal management of a logon_id array at session
+		level + enable transparent transport/copy of current logon_id value
+		among MAPI calls + finally transparently free the logon_id value when
+		the store object (PF or mailbox) is being released.
+	[r1284]
+		- Retrieve recipients from OpenEmbeddedMessage reply
+		- Test the implementation in mapitest
+		- Avoid potential memory leak: steal context for returned ulPropTags.
+
+2009-03-08
+    jkerihuel
+	[r1282]
+		Be more tolerant with Logon request flags
+	[r1281]
+		Set retval to MAPI_E_INVALID_BOOKMARK rather than returning.
+		This case still needs to be fixed though.
+	[r1280]
+		Delete debug message
+	[r1279]
+		Create a default GetProps reply on error
+
+2009-03-06
+    jkerihuel
+	[r1277]
+		Fix retval problem in libmapi/nspi.c for GetIDsFromNames.
+		Function returns MAPI_E_SUCCESS, but errno is set to 0x0000000b.
+		Set errno to retval to work around this problem.
+		
+		
+		NSPI-GETIDSFROMNAMES
+	[r1276]
+		OXCPRPT-NAME-ID mapitest now passes: The QueryNamedProperties ecMemory retval
+		has been worked-around by setting QueryFlags to NoStrings to limite the results
+		scope. This means the MNID_STRING case is not fully checked anymore. We should maybe
+		add additional tests to do full coverage.
+	[r1275]
+		Fix GetNamesFromIDs IDL and implementation.
+		
+		Note: We should probably update the function prototype
+		so it takes a mapi_SPropTagArray rather than a single property.
+    bradh
+	[r1274]
+		Protect against bad results from GetGALTable().
+		
+		Resolves ticket #142
+
+2009-03-04
+    jkerihuel
+	[r1272]
+		Patch from Paolo Abeni: Add sanity check to Subscribe
+		and prevent applications from crashing if notify context 
+		is uninitialized.
+
+2009-03-03
+    jkerihuel
+	[r1270]
+		Ensure NSPI server functions have a valid dcesrv_handle
+	[r1269]
+		Add quick/additional configuration information on how to setup openchange server
+	[r1268]
+		This commit adds a retval check on private data retrieval function and prevents QueryPosition from causing a 
+		segfault when parent object is meant to come from GetContentsTable.
+	[r1267]
+		- Fix NspiGetMatches server reply when specified username is invalid and
+		search fails.
+		- Make use of talloc hierarchy for NspiGetProps properties fetch + fix
+		a talloc_free bug leading to segfault on failure.
+	[r1265]
+		Prevent from registering same mapistore backend multiple times
+    bradh
+	[r1266]
+		Howto updates.
+
+2009-03-02
+    jkerihuel
+	[r1261]
+		Add skeleton for GetRulesTable 
+	[r1258]
+		- return MAPI_E_SUCCESS when QueryRows reply count is 0
+		- Move Reminders from IPM Subtree to Mailbox root
+	[r1257]
+		- Add QueryPosition implementation
+		- Move from offset to numerator/denominator couple for table objects
+		
+		Outlook now opens properly using openchange server and display the
+		mailbox folder list with icons ;-)
+	[r1256]
+		- Add skeletons for Restrict, SortTable, FindRow calls
+		- Introduce emsmdb provider table object
+		- Add preliminary table implementation for system/special folders
+		- Add preliminary implementation of GetHierarchyTable, SetColumns and QueryRows
+		- Improve creation of GetProps reply blob for Mailbox folder
+		- Fix bug in EcRRegisterPushNotification when associated handle is invalid
+		- Remove some usage of ldb_filter and use format string instead 
+		- Update libmapiserver sanity checks and look for error_code != MAPI_E_SUCCESS
+		  so openchange server is able to return failed replies to MAPI clients
+		- Introduce flaggedPropertyRows in libmapiserver_push_property (needed by QueryRows)
+		
+		This commit makes openchange server work with "openchangeclient --mailbox" ;-)
+		
+		Still preliminary but anyway worthwhile enough to be mentioned ...
+	[r1255]
+		- Add a function to count subfolders of a container
+		- Add a function to wrap MAPI tables over openchangedb
+		- Factorize code used to fetch property values from LDB records
+	[r1254]
+		- Add default properties to folder records while provisioning mailbox
+		- Add few more mapping for PR_* to PidTag
+		- Add a new MAPI property to the list
+	[r1253]
+		Avoid openchangeclient --mailbox to segfault when run vs openchange server
+    bradh
+	[r1263]
+		Remove some ldb_filters, and just use varargs into ldb_search
+	[r1262]
+		warning fix for 64-bit arch.
+	[r1260]
+		Revert previous commit.
+	[r1259]
+		Experimental commit to fix build problems resulting
+		from property changes.
+
+2009-03-01
+    jkerihuel
+	[r1251]
+		- Add PidTagDisplayName property to Mailbox object
+		- Add PidTagParentFolderId to all system/special folders
+	[r1250]
+		- handles array depends if a valid mapi_repl exists. This commit
+		  fixes the destructor semantics.
+		- Fix a mapitest segfault encountered while run vs openchange server
+		- Return 1 in SRowSet_propcpy if an error was encountered.
+	[r1249]
+		Fix libmapi stack segfault when MAPI calls returns 
+		with error_code different from MAPI_E_SUCCESS.
+	[r1248]
+		Do not process NSPI request if we can't find the handle
+	[r1247]
+		Remove unnecessary ldb_filter parameter and replace it
+		with ldb_search format string.
+
+2009-02-28
+    jkerihuel
+	[r1245]
+		- GetPropertyIdsFromNames skeleton added
+	[r1244]
+		- Fix how Release replies are handled in mapi_repl[] array
+		- Remove Release size calculation
+		- Fix QueryRows size in libmapiserver
+		- Add a dummy/skeleton GetPropertiesSpecific function for mapistore objects.
+		- GetHierarchyTable skeleton added
+		- SetProperties skeleton added
+		- CreateMessage skeleton added
+		- SaveChangesMessage skeleton added
+		 
+
+2009-02-27
+    jkerihuel
+	[r1241]
+		Set mapi_response to NULL upon init ... just to get sure
+	[r1240]
+		Fix MAPIUninitialize segfault
+    bradh
+	[r1242]
+		Warning fix.
+
+2009-02-26
+    jkerihuel
+	[r1238]
+		- Add skeleton for GetContentsTable Rop
+		- Add skeleton for some [MS-OXCTABL] Rops: SetColumns, SortTable, QueryRows, SeekRows
+		- Add libmapiserver size calculation functions for all the above
+		- Ensure we only set objects parameter if it exists
+		- Return when dcesrv handle is not available
+	[r1236]
+		Merge s4-alpha7 branch back into trunk
+
+2009-02-25
+    jkerihuel
+	[r1227]
+		- Add several PidTag to openchange.ldb folders
+		- Add provisioning convenient function which adds attribute/value pair
+		to a given folder record
+		- Replace existing special folders reference within Inbox with PidTagIpm* tags
+		- Add new PidTag values to mapi-properties
+		- Add a function to libmapiproxy to build a folder EntryID as described in MS-OXODATA
+		- Add a function which builds special properties for openchangedb folders
+		- Add PT_BOOLEAN case to openchangedb folder get property function
+		- Keep a reference to the mailbox username within emsmdb provider context
+		- Create and return a handle in RegisterNotification
+		 
+	[r1226]
+		Improve PT_I8 dump
+	[r1225]
+		Wrong MessageClass size calculation fixed 
+    jelmer
+	[r1229]
+		Remove duplicate _GNU_SOURCE definition (already specified by Makefile)
+	[r1228]
+		Ignore new binary and trial output.
+
+2009-02-24
+    jkerihuel
+	[r1223]
+		- Fix systemfolder value for System/Special folders
+		- Add GetProps support to System/Special folders
+	[r1222]
+		Add auto-generated parser to the ignore list
+	[r1221]
+		- Add auto-generated parser for MAPI property to PidTag mapping
+		- Add some PidTag values
+		- Add a lookup and get property functions on system folders
+	[r1220]
+		- tuple SystemIdx in the dictionnary to workaround the ordering problem
+		- Add ParentFolderId attribute to System Folders
+	[r1217]
+		- Add creation of "Special folders" to mailbox provisioning
+		- Rename fid attribute to PidTagFolderId
+		- Rename name attribute to PidTagDisplayName
+		- Rename ExplicitContainerClass to PidTagContainerClass
+	[r1216]
+		Fix GlobalCount increment
+	[r1215]
+		Fix mailbox provisioning
+    bradh
+	[r1219]
+		Add test for FILETIME structure.
+	[r1218]
+		Update docs for mapiproxy entry.
+    jelmer
+	[r1214]
+		Fix handling of fids.
+2009-02-23
+    jkerihuel
+	[r1208]
+		- Fix openchangedb mailbox hierarchy and introduces subfolders
+		as described in [MS-OXOFOLDS] specifications.
+		- Update openchangedb API to reflect this change.
+	[r1207]
+		Rename private mailbox folder "non_ipm_subtree" to "mailbox_root"
+		to fit with MS-OXOFOLDS specifications.
+	[r1206]
+		- Add provisioning code for GetReceiveFolder defaults
+		- Check if mapistore content repository already exists for the user
+		- Make mailbox creation verbose
+    jelmer
+	[r1213]
+		Fix parentfolder reference.
+	[r1212]
+		Fix syntax error.
+	[r1211]
+		Use recursive call to create folders.
+	[r1210]
+		Simplify list iteration, PEP8, avoid using string exceptions.
+
+2009-02-22
+    jkerihuel
+	[r1204]
+		Fix 'dereferencing type-punned pointer' warnings
+	[r1203]
+		- Add strict-aliasing compiler flags
+		- Fix format string warnings on ubuntu buildbot
+	[r1202]
+		- Add _FORTIFY_SOURCE=2 to the compiler CFLAGS
+		- Fix warnings introduced by -D_FORTIFY_SOURCE
+    bradh
+	[r1201]
+		I might have been a bit hasty with that last commit...
+		
+		Need sqlite3.
+	[r1200]
+		Try harder to find sqlite3.
+		
+		Seems to be in sqlite.pc on Ubuntu.
+	[r1198]
+		Fix warning on 64-bit arch.
+2009-02-21
+    jkerihuel
+	[r1197]
+		- Add RopGetReceiveFolder (0x27) implementation
+		The function respects should respect the semantics and behavior
+		as described in MS-OXCSTOR specifications. However the python's
+		code modification required: add ExplicitMessageClass attributes
+		to folder records is not yet effective.
+		
+		- Add GetReceiveFolder size calculation function to libmapiserver
+		- Add a function to openchangedb API to retrieve the FID/ExplicitMessageClass
+		couple for a given SystemFolder within user's mailbox.
+	[r1196]
+		- Provision scripts: create a mapistore default storage space within ${private}/mapistore/${username}
+		- Provision scripts: add default sqlite:// mapistore URI for system folders
+		- Add mapistore context initialization when calling OpenFolder on SystemFolder
+		- Add mapistore context release for folders in emsmdbp object destructor
+	[r1195]
+		Factorize emsmdbp objects
+		Add emsmdbp_object generic talloc destructor
+    bradh
+	[r1194]
+		Add test for PT_MV_LONG.
+	[r1193]
+		Add tests for PT_I8 and PT_BINARY
+	[r1192]
+		Fix warning about no newline at end of file.
+		
+		Remove most recently added tests from "to be done" list.
+	[r1191]
+		Add a couple more mapi_SPropValue tests.
+
+2009-02-19
+    jkerihuel
+	[r1189]
+		- Initialize mapistore within emsmdb provider context
+		- Add destructors for MAPI handles and mapistore contexts
+		- Remove emsmdbp_ctx memory context structure member and
+		allocate directly with emsmdbp_ctx
+	[r1188]
+		I don't see any good reason why we would pad MAPI replies with some bytes. 
+		I guess it comes from some prehistoric openchange code.
+	[r1187]
+		Fix systemfolder assignment depending on IsSystemFolder value
+	[r1186]
+		- Initialize OpenFolder server reply
+	[r1185]
+		- Wrap TDB connections to mapistore (code from samba4) so
+		multiple instances can open read/write to the same TDB database
+		- Remove static id_mapping_context (replaced with tdb_wrap calls)
+		- Update mapistore linkage rules so mapistore can be used with exchange_emsmdb server
+		- Link mapistore with exchange_emsmdb
+	[r1183]
+		Fix aclocal warning for AC_DEFINE comparison_fn_t
+	[r1182]
+		Remove useless GetProfilePtr from IProfAdmin interface
+		Closes trac ticket #131
+	[r1181]
+		Add missing script - prevent configure from generating warning vs missing file.
+	[r1180]
+		Remove stamp-h1 file during distclean and add it
+		to the ignore list.
+	[r1179]
+		- Add server-side GetReceiveFolder (0x27) skeleton
+	[r1178]
+		Work around the comparison_fn_t redefinition problem
+		between libocpf and ndr.h
+	[r1177]
+		FreeBSD doesn't have time.h daylight global variable
+    bradh
+	[r1184]
+		start testing mapi_SPropValue_array.
+		This also tests some underlying functions.
+
+2009-02-18
+    jkerihuel
+	[r1175]
+		Add comparison_fn_t support to ndr.h
+		This was the latest change require to make openchange compiles under FreeBSD
+		
+		= samba4/openchange FreeBSD support completed =
+
+2009-02-17
+    jkerihuel
+	[r1173]
+		Remove duplicated post_install call
+	[r1172]
+		Add a post_install operation on FreeBSD
+		Make sure pidl is installed properly.
+	[r1171]
+		Patch samba4 tarball so it compiles properly on FreeBSD 7.0
+		Note: this is a dirty hack which needs to be removed in the future
+	[r1170]
+		Install Samba4 correctly although user's PKG_CONFIG_PATH env variable
+		may not be adjusted properly.
+	[r1169]
+		Avoid download samba4 release tarball if already available
+		in current directory.
+	[r1168]
+		- Add test for comparison_fn_t in configure.ac
+		- libocpf auto-generated files include stdlib.h and prevent from
+		having the proper comparison_fn_t typedef. This commit works around this
+		problem and define comparison_fn_t within a private header.
+	[r1165]
+		getline is a stdio GNU_SOURCE extension not available under FreeBSD.
+		Use fgetln instead when it is compiled on this OS.
+	[r1164]
+		FreeBSD doesn't define sighandler_t but sig_t
+	[r1163]
+		Replace open() call with O_DIRECTORY flag (Linux specific) with opendir
+	[r1162]
+		- Add non-default search path /usr/local/{include,lib} to
+		CFLAGS and LDFLAGS when compiling OpenChange under FreeBSD
+		- Make use of LDFLAGS while compiling openchange tools
+    bradh
+	[r1167]
+		A few improvements for property handling.
+		
+		Also add unit tests to verify behaviour is correct.
+		
+		The implementation for the FlatUID (GUID) structure appears broken. Perhaps I'm not using it correctly.
+	[r1166]
+		Microsoft confirmed the LCID is wrong in the spec, and will be updated in the next rev.
+
+2009-02-16
+    jkerihuel
+	[r1160]
+		Check for Flex version < 2.5.35
+		Make sure users can define the FLEX environment variable
+	[r1159]
+		Add automake scripts for AC_CANONICAL_HOST support
+		Needed for FreeBSD OS detection in configure.ac
+
+2009-02-14
+    bradh
+	[r1153]
+		Fix warnings from lexer output.
+	[r1152]
+		Fixes for warnings on 64-bit architectures.
+	[r1151]
+		Fix warning on 64-bit architecture.
+    jelmer
+	[r1157]
+		Add some more tests for openchange.mailbox.
+	[r1156]
+		Fix creation of new mailbox after provision.
+	[r1155]
+		Always use the same URL when connecting to openchangedb.
+	[r1154]
+		Fix arguments to openchangedb_provision.
+
+2009-02-13
+    jkerihuel
+	[r1149]
+		Fix libmapi 64-bit machine cast warnings mentioned in Brad's devel email
+    bradh
+	[r1148]
+		Warning fix for 64-bit arch.
+
+2009-02-12
+    jkerihuel
+	[r1146]
+		Add doxygen definition for RopRelease
+	[r1145]
+		- Add server-side skeleton implementation for RopOpenFolder and RopRegisterNotification
+		- Add preliminary size calculation functions in libmapiserver for the 2 calls above
+		- Fix size bug for serialized requests
+		- Add skeleton case for RopGetPropertiesSpecific on SystemFolders
+		- Make sure the GetProps reply blob is initialized whatever happen
+		- Add a skeleton emsmdbp folder object init function
+
+2009-02-11
+    jkerihuel
+	[r1143]
+		Remove debug strings for GetPropertiesSpecific Rop
+	[r1142]
+		Enable verbose output in server mode - useful during development
+	[r1141]
+		Implement preliminary server-side RopGetPropertiesSpecific call for mailbox object.
+	[r1140]
+		- Fix GetProps blob for PT_BINARY: use SBinary_short instead of Binary_r
+		- Fix GetProps size: subcontext is not added to the fixed size calculation
+	[r1133]
+		- GetPropsSpecific size calculation function added to libmapiserver
+		- Function to create a GetProps reply property blob added to libmapiserver
+    jelmer
+	[r1139]
+		Add tests for provisioning.
+	[r1138]
+		Several cleanups in python code, add tests for schema use.
+	[r1137]
+		Don't clear PYTHONPATH override.
+	[r1136]
+		Remove unused imports, add extra tests.
+	[r1135]
+		Use member variable for Ldb, rather than subclassing.
+	[r1134]
+		Remove print statements to avoid cluttering test output.
+	[r1130]
+		Add simple and incomplete testcase for OpenChangeDB.
+	[r1129]
+		Move wipe of data to mailbox.py, simplify arguments to add_root_mailbox.
+	[r1128]
+		Move adding a server to mailbox.py.
+	[r1127]
+		Move ldif from oc_provision_openchange.ldif into Python.
+	[r1126]
+		Stop providing setup_path to OpenChangeDB, as it's no longer used.
+	[r1125]
+		Avoid using separate LDIF file when creating folder mailboxes.
+	[r1124]
+		Avoid using separate LDIF file when creating mailboxes.
+	[r1123]
+		Avoid passing full names object.
+	[r1122]
+		Add check-python target.
+
+2009-02-10
+    jelmer
+	[r1120]
+		fix openchange_newuser.
+	[r1119]
+		Use SamDB for actual SAM databases, Ldb otherwise.
+	[r1118]
+		Remove unused parameters, don't make parameters optional if they are mandatory.
+	[r1117]
+		remove unused parameters.
+	[r1116]
+		make mailbox object-oriented, remove creds/lp parameters.
+	[r1115]
+		Fix OpenChangeDB syntax.
+
+2009-02-09
+    jkerihuel
+	[r1113]
+		- Add a systemfolder member to the MAPI handle structure to make a difference
+		  between objects managed by mapistore and those stored within openchange.ldb 
+		  (root mailbox folders).
+		
+		- Add opaque functions to set/get private_data and systemfolder to the MAPI 
+		  handles API.
+	[r1112]
+		Minor doxygen fix/improvement
+	[r1109]
+		Add libmapistore object files to the ignore list
+	[r1108]
+		- Add a very preliminary and light libmapistore implementation.
+		mapistore only supplies init/release and add/del backend contexts.
+		This commit also includes a sqlite3 backend skeleton (open/close sqlite db)
+		- A temporary mapistore testing tool has been added locally for implementation checks.
+    jelmer
+	[r1111]
+		Use convenience function for connecting to openchange.ldb.
+	[r1110]
+		Use standard LDB functions - openchange.ldb is not a SAM database.
+
+2009-02-08
+    bradh
+	[r1106]
+		Implement support the SUMMARY language tag.
+	[r1105]
+		Initial checking of libical based exchange2ical code.
+		
+		This has a long way to go, so think of this as more of a checkpoint
+		than a release.
+		
+		See http://sourceforge.net/projects/freeassociation/ for the library, or
+		see if your distro has a package.
+	[r1104]
+		Reduce warnings.
+	[r1103]
+		Add missing parameter to API documentation.
+		
+		Resolves ticket #130.
+	[r1102]
+		API documentation fixes for OpenEmbeddedMessage()
+	[r1101]
+		Implement OpenEmbeddedMessage ROP (0x46).
+		
+		Resolves Ticket #93
+	[r1100]
+		Factor out message creation and message fill actions.
+		
+		Also remove GetLastError() where appropriate.
+	[r1099]
+		Add some API documentation.
+
+2009-02-07
+    jkerihuel
+	[r1097]
+		Update openchangepfadmin description
+		Fix tool relying on libmapiadmin
+    bradh
+	[r1096]
+		Minor code tweak.
+		
+		Fix ticket #132.
+	[r1095]
+		Add more explanation for README
+	[r1094]
+		Reimplement RTF decompression.
+		
+		Add unit tests from MS-OXRTFCP.
+	[r1093]
+		Fix warnings in example code
+	[r1092]
+		Add description for libmapiadmin
+	[r1091]
+		Add description for libmapi / libmapi++
+	[r1090]
+		Start on the directory descriptions.
+	[r1089]
+		doc/ pointers
+2009-02-06
+    bradh
+	[r1088]
+		Add overview. Extracted from API docs.
+	[r1087]
+		Additional docs.
+	[r1084]
+		Outline of README file.
+		
+		(also using this to test buildbot without changing real code)
+2009-02-05
+    jkerihuel
+	[r1081]
+		Add Version field - avoid breaking pkg-config --list-all
+	[r1080]
+		Fix warnings (gcc 4.2.4)
+    jelmer
+	[r1083]
+		Use variable for package version rather than hardcoding it.
+
+2009-02-04
+    jkerihuel
+	[r1078]
+		Fix pc file libs
+
+2009-02-03
+    jkerihuel
+	[r1070]
+		- Add an implementation of the MAPI handles management API. The API
+		  internally uses an in-memory TDB database to keep object hierarchy
+		  and a doubled chained list to associate private data to handles.
+		
+		The API currently provides add, search and delete facilities. Note
+		that while untested, the delete operation is designed to recursively
+		delete children of the 'meant to be deleted' handle.
+		
+		Finally the API doesn't remove TDB records but mark them as free so
+		they can be reused across MAPI session and prevent from handle counter
+		growing indefinitely.
+		
+		- Add a preliminary implementation of the Release call
+		- Add Release size calculation to libmapiserver
+		- Update EMSMDB provider to use MAPI handles API
+    bradh
+	[r1075]
+		Minor api documentation fix.
+	[r1074]
+		Minor API docs fix.
+	[r1073]
+		Minor API docs fix.
+	[r1072]
+		Minor API docs tweak.
+	[r1071]
+		Token commit of tiny API docs fix.
+    jelmer
+	[r1076]
+		Look for GNU make harder (gmake on BSDs).
+
+2009-02-02
+    jkerihuel
+	[r1068]
+		- Add preliminary EMSMDB provider implementation for RopLogon (0xFE)
+		- Add common routines for OpenChange LDB context init and search
+		  within libmapiproxy
+		- Add libmapiserver skeleton with size calculation routine for RopLogon
+		- Change DSO linking dependencies for mapiproxy shared libraries
+		- Propagate _GNU_SOURCE change from libmapi.h to mapiproxy
+2009-02-01
+    jkerihuel
+	[r1067]
+		Remove .po and .o objects within libmapiproxy subdirectory
+	[r1066]
+		Move libmapiproxy into its own directory and rebase mapiproxy headers accordingly
+		Fix make uninstall for AD and profiles directories
+	[r1064]
+		doxygen typo fix
+	[r1063]
+		Add python code and ldif files needed to create and populate the experimental
+		openchange dispatcher database.
+	[r1062]
+		Add 5-Minute configuration documentation for OpenChange server mode
+	[r1061]
+		- Rebase ldif files into sub directories:
+		  * AD for OpenChange AD modifications
+		  * profiles for OpenChange IProfAdmin interface
+		- Makes it easier figuring out LDIF files scope
+		- Prepare setup folder for LDIF openchangedb files integration
+		- Update install/uninstall Makefile rules for ldif files and
+		  make sure everything got removed
+    bradh
+	[r1060]
+		Add forgotten file.
+	[r1059]
+		Add support for short language names (e.g. en-AU) for lcid.
+
+2009-01-31
+    jkerihuel
+	[r1057]
+		Delete deprecated libmapi setup Perl script
+    bradh
+	[r1056]
+		Add summary report for tests.
+	[r1055]
+		Make mapitest return the number of failed tests.
+
+2009-01-29
+    jkerihuel
+	[r1052]
+		- Add pkg-config pc file for libmapiproxy
+		- Improve mapiproxy rules so libmapiproxy gets installed and cleaned properly
+	[r1051]
+		Free memory allocated by the fake subcontext in
+		ndr_pull_mapi_response.
+		
+		This fix saves 300kb of memory and removes 700 loss records while
+		valgrinding mapitest.
+	[r1050]
+		Fix segfault - Add sanity check - when SPropTagArray is NULL in
+		NspiQueryRows request
+	[r1048]
+		Fix openchange_newuser name typo
+	[r1047]
+		Fix server provisioning command line examples
+	[r1045]
+		Fix several libmapi leaks.
+		
+		mapi_response was allocated using emsmdb_ctx->mem_ctx memory context
+		and was not free'd when libmapi function released their
+		context. Furthermore we need to release mapi_response->mapi_repl and
+		mapi_response->handles which are now automatically free'd when
+		mapi_response destructor is called.
+		
+		However note that this fix is not perfect: mapi_response memory is not
+		free'd properly when calls exit with an error.
+		
+		This commit also make use of talloc_steal where necessary to keep
+		returned fields allocated.
+2009-01-28
+    jkerihuel
+	[r1040]
+		Use named context rather than autofree
+	[r1039]
+		Fix memory leak in emsmdb.c: Use a temporary memory context for
+		request and length allocation in emsmdb_transaction.
+		
+		- This removes 827 loss records and approximatively saves 41kb of
+		  memory while valgrinding mapitest
+	[r1038]
+		- Fix memory leak in GetDefaultProfile and GetProfileTable.
+		- Save from 10 loss records while valgrinding mapitest
+		- Developers are now responsible from freeing the GetDefaultProfile
+		  string the function allocates.
+		- Apply changes to all openchange tools.
+	[r1037]
+		Add blackbox subunit tests for mapiprofile tool
+    bradh
+	[r1043]
+		One more trivial fix.
+	[r1042]
+		Typo fixes.
+		
+		(Yep, more trivial changes)
+	[r1041]
+		Fix incorrect LCID for en-CA.
+		
+		(OK, its token, I admit).
+    jelmer
+	[r1044]
+		Don't define _GNU_SOURCE unconditionally.
+2009-01-27
+    jkerihuel
+	[r1036]
+		Prevent mapiproxy from multiple init and modules/server register
+		when an smb client connect to the server (e.g. windows browser or smbclient)
+2009-01-26
+    bradh
+	[r1033]
+		According to [MS-OXOCAL] Section 2.2.1.44.1 
+		"RecurrencePattern Structure", a monthly recurrence
+		also has a Day specific parameter.
+		
+		Add that here.
+    jelmer
+	[r1035]
+		Simply run autogen.sh rather than replicating it inside the Makefile.
+	[r1034]
+		need to run aclocal before autoconf for the pkg-config macros.
+2009-01-25
+    jkerihuel
+	[r1032]
+		Use a autofree context rather than a named one - makes sure memory is free'd when we exit the test.
+		Saves from 4 loss records while valgrind'ing mapitest.
+	[r1031]
+		Use temporary memory context for EcDoConnect.
+		Saves from 20 loss records when valgrind'ing mapitest.
+	[r1030]
+		Free PropertyProblem structures returned by CopyTo.
+	[r1029]
+		Replace deprecated talloc_init calls with talloc_named
+		This commit removes some valgrind loss records talloc_init was responsible for
+	[r1028]
+		Free everything
+		Free everything when running mapitest --list-all.
+		Valgrind however shows a loss record related to talloc_init ...
+    bradh
+	[r1027]
+		Minor Intel C compiler warning fixes.
+	[r1026]
+		Minor apidocs cleanups.
+2009-01-24
+    jkerihuel
+	[r1024]
+		Use double pointer for lp_ctx in GetLoadparmContext assessor
+	[r1023]
+		Fix memory leak in utf8 lexer.
+	[r1022]
+		- Remove custom iconv_convenience from pull_emsmdb_property and use 
+		lp_iconv_convenience on loadparm_context argument instead. 
+		
+		- Change OpenChange libmapi API to reflect this change
+		
+		- Introduce a lp_ctx assessor in libmapi/cdo_mapi.c 
+		(mostly for mapitest modules). libmapi/mapiproxy developers
+		should never have to make use of it.
+		
+		- Remove pointless duplicated call to lp_load_default in MAPIInitialize.
+	[r1021]
+		Free lpProps returned by GetProps, Fix context error in valgrind
+	[r1020]
+		- Fix memory leak bug: release ndr context in pull_emsmdb_property before returning
+		- Terminate SPropValue and SPropTagArray using an element with ulPropTag = 0. This
+		prevent from "invalid read size of 4" messages from valgrind and remove context errors.
+    jelmer
+	[r1025]
+		Don't install mapiproxy if python wasn't found, since 
+		we wouldn't know where to install the provisioning scripts or be able 
+		to use them.
+2009-01-20
+    jkerihuel
+	[r1018]
+		Merge libmapi-0.8 branch r1015 to 1017 into trunk
+	[r1015]
+		** Start libmapi-0.9 COCHRANE development **
+	[r1014]
+		Merge libmapi-0.8 branch changes into trunk
+2009-01-18
+    jkerihuel
+	[r1007]
+		Add python install/uninstall rules to provision rather than mapiproxy-servers
+	[r1006]
+		- Remove server Makefile rules
+		- Remove dead code
+		
+		Note: server and providers have been merged within mapiproxy,
+		so there is no reason keeping this deprecated code.
+2009-01-17
+    jkerihuel
+	[r1005]
+		Undoing change committed in r1004.
+	[r1004]
+		Use .po files instead of .o files for openchange tools
+	[r1003]
+		Add --version to openchange tools
+	[r1002]
+		Add COPYING file with GPLv3 license
+2009-01-16
+    jkerihuel
+	[r1001]
+		- Add RenameProfile function to IProfAdmin API
+		- Remove pointless CopyProfile from IProfAdmin API
+		- Add --rename option to mapiprofile tool
+		- Update man page to reflect this addition
+		
+		(close trac ticket #124)
+	[r1000]
+		Fix libmapi from crashing when mapi_repl is NULL.
+	[r999]
+		Update Samba4 git rev to fix the charcnv segfault met in openchange
+		tools
+    jelmer
+	[r998]
+		Try to find the Samba python modules if they're not installed in the system 
+		python directory.
+2009-01-15
+    jkerihuel
+	[r997]
+		- Fix Subscribe semantic bug and add WholeStore boolean parameter
+		- propagate API change to tools/torture callers
+	[r996]
+		- Add assessor functions to set dumpdata and debug level in libmapi
+		  (SetMAPIDumpData and SetMAPIDebugLevel)
+		- OpenChange tools modified to use these function rather than set these
+		  parameters on their own
+	[r995]
+		- Fix --debuglevel segfault in openchange tools
+		- Enable logging to stdout in MAPIInitialize
+2009-01-14
+    jkerihuel
+	[r994]
+		* OpenChange libmapi function now returns MAPI error instead of -1
+		- use OPENCHANGE_RETVAL_IF instead of MAPI_RETVAL_IF
+		- add doxygen documentation for some missing functions/files
+	[r993]
+		- Missed this event->tevent change in previous commit
+	[r992]
+		- Update openchange to use latest Samba4 master git rev (990491d)
+		- Fix references to tevent_context structures
+		- Fix iconv_convenience init in MAPIInitialize
+		- Remove errorchecks mapitest module warning
+    jelmer
+	[r991]
+		Use tevent_context_init.
+	[r990]
+		Ignore binaries.
+2009-01-13
+    jkerihuel
+	[r989]
+		Some Exchange server (stand-alone) return MAPI_E_LOGON_FAILED when setting EssDN with username rather than
+		using profile's mailbox string directly. This commit fixes the bug.
+	[r988]
+		- Add EcDoConnect and EcDoDisconnect preliminary support to
+		  dcesrv_exchange_emsmdb.c
+		- Add internal session management mechanism to EMSMDB server
+		- Add init and unbind modules function to EMSMDB server
+		- Add emsmdbp_context and session to dcesrv_exchange_emsmdb.h
+    bradh
+	[r987]
+		Fix valgrind errors caused by using free'd memory.
+2009-01-12
+    jkerihuel
+	[r986]
+		Implement 'mapiproxy downgrade' behavior in EMSMDB server and force
+		Outlook to use EcDoConnect (0x0) and EcDoRpc (0x2) rather than 0xA and
+		0xB (opnums using LZ based compression).
+	[r985]
+		- Add Preliminary implementation for RfrGetFQDNFromLegacyDN DS RFR server
+2009-01-11
+    jkerihuel
+	[r984]
+		- Preliminary implementation of NspiGetProps NSPI server function
+		- Makes sure emsabp_tdb_traverse_MId uses the correct dbuf size
+		- Use correct ldb context (users or conf) depending on where MId is
+		  located (on-memory or on-disk)
+		- Add PR_EMS_AB_NETWORK_ADDRESS mapping to emsabp_property
+		
+		*** Outlook is now able to create MAPI profile using OpenChange Server ONLY! ***
+	[r983]
+		- Preliminary implementation of NspiDNToMId NSPI server function
+		- Add emsabp_search_legacyExchangeDN to search for a record given its
+		  legacyExchangeDN attribute.
+	[r982]
+		- Preliminary implementation of NspiQueryRows NSPI server function added
+		- fix a bug in the MID TDB traversal routine: cut dptr to dsize length
+		  rather assuming it is NULL terminated
+		- Add support for "referenced" property tags
+		- Add support for PR_MV_STRING8
+		- Add emsabp_search_dn which search for a DN within AD and return the
+		  associated LDB message
+		- Add PR_EMS_AB_HOME_MDB and PR_EMS_AB_PROXY_ADDRESSES to
+		  emsabp_property array
+	[r981]
+		Prevent from trying to add a NULL element to profile database and segfault on strlen
+	[r980]
+		Prevent x500_get_dn_element from segfaulting when an incorrect DN string parameter is supplied
+	[r979]
+		- Preliminary implementation of NspiGetMatches NSPI server function
+		- Make use of a on-memory TDB database for Ephemeral Entry IDs
+		- Add TDB traversal routines to retrieve DN associated to MId
+		- Move lp_ctx within emsabp_ctx for convenience
+		- Add EphemeralEntryID to Binary_r routine
+		- add emsabp_query (Find attribute matching given property tag and
+		  return associated data)
+		- add emsabp_fetch_attrs which builds a SRow array given a MId and
+		  requested property tags.
+		- add emsabp_search which searches AD given input search criteria
+		- add a preliminary Property Tag to AD attribute mapping + associated
+		  functions in emsabp_property.c
+		
+		Note: This NspiGetMatches is limited to MAILUSER which means we only
+		look for users (located within users.ldb). This limitation will be
+		removed when we have a preliminary working emsmdb server, so we can do
+		more extensive NSPI server tests.
+	[r978]
+		Add sanity check to get_SPropValue_SRowSet, prevents the function
+		from segfault when RowSet is NULL (e.g. crafted NspiQueryRows replies)
+	[r977]
+		Prevent IProfAdmin based code from crashing when a crafted NspiGetMatches reply
+		with NULL ppOutMIds is returned.
+		 
+2009-01-10
+    jkerihuel
+	[r976]
+		- Preliminary NspiGetSpecialTable implementation added to NSPI
+		  server/EMSABP provider: Hierarchy Table supported (required during
+		  profile creation)
+		- add PT_BINARY support for mapidump_SPropValue
+		- fix a bug when PT_STRING8 or PT_UNICODE pointer is set to
+		  MAPI_E_NOT_FOUND
+
+2009-01-06
+    jkerihuel
+	[r974]
+		Add new Display Type values (used by EMSABP provider)
+	[r973]
+		Change DEBUGLEVEL for RfrGetNewDSA
+	[r972]
+		- preliminary implementation of RFR server (RfrGetNewDSA): makes Outlook happy
+		- mapiproxy-servers-install now installs openchange python scripts and ldif file
+2009-01-05
+    jkerihuel
+	[r971]
+		Move auth_serversupplied_info structure from dcesrv_exchange_nsp.h to libmapiproxy.h
+		This structure is required for NTLM_AUTH_IS_OK macro
+	[r969]
+		- Add doxygen comments for all OpenChange server modules
+		- Fix doxygen return value for exchange_nsp
+	[r968]
+		- Add mapiproxy server unbind function and hook in dcesrv_mapiproxy.c
+		- Add exchange handle enum to dcesrv_mapiproxy.h
+		- Add authentication verifier macro to libmapiproxy.h
+		- Add preliminary EMSABP Address Book Provider implementation:
+		  * supports initialization, destructor (talloc)
+		  * implements user and codepage check routines
+		  * retrieve NSPI server GUID
+		- Add NspiBind and NspiUnbind support to dcesrv_exchange_nsp.c
+		- Add internal session mechanism management to NSPI server
+		- Add init and unbind modules function to NSPI server
+		- Add doxygen comments to all dcesrv_exchange_nsp.c functions
+		- Add emsabp_context, session and non-exported Samba structure to dcesrv_exchange_nsp.h
+	[r967]
+		OpenChange configuration schema updated with Addressing schema
+		(Address-Templates, Address-Types and Display-Templates - Exchange 2003 based)
+	[r966]
+		Execute server modules init function when loaded
+    bradh
+	[r965]
+		A few API documentation fixes.
+
+2009-01-04
+    jkerihuel
+	[r963]
+		Add documentation for MAPIProxy 'server mode'
+
+2009-01-02
+    jkerihuel
+	[r961]
+		- Implement mapiproxy server mode architecture
+		- Add server modules management API
+		- Add skeletons for default OpenChange servers (nspi, emsmdb, ds_rfr)
+		- Add temporary provision Makefile rule
+
+2008-12-30
+    jkerihuel
+	[r959]
+		Initial text was correct - rollback
+	[r958]
+		Fix path typo
+    bradh
+	[r957]
+		Ensure that GetLastError() also returns the correct value.
+	[r956]
+		Start changing the MAPI_RETVAL_IF() usage to two new macros:
+		OPENCHANGE_RETVAL_IF() and OPENCHANGE_RETVAL_ERR().
+		
+		simple_mapi.c is the only one converted at this stage.
+		
+		Also added a set of unit tests that verify at least some initial
+		sanity checks.
+	[r955]
+		Remove unreachable code.
+		
+		Partly resolves ticket #124
+
+2008-12-29
+    jkerihuel
+	[r953]
+		Remove references to ldap.h header file - not installed anymore with samba4 git rev openchange uses
+	[r952]
+		mapiproxy documentation update: 3 questions added to FAQ section
+	[r951]
+		Patch from Corentin Chary:
+			- Add PR_CONTENT_FILTER_SCL property to libmapi
+	[r950]
+		- Update openchange to work with samba4 master git rev f308c2f
+		- Replace reference to events.h with tevent.h
+		- Update installsamba4.sh script to reflect latest samba4 compilation changes/requirements 
+
+2008-12-27
+    jkerihuel
+	[r948]
+		Fix mapidump date/month when freebusy period covers end of one year - beginning of next year
+		Update openchangeclient to reflect these changes.
+
+2008-12-24
+    jelmer
+	[r946]
+		Export PKG_CONFIG_PATH if it wasn't exported yet. Patch by Metze
+	[r945]
+		Fix PIC object flags for SWIG build. Patch by metze.
+
+2008-12-21
+    bradh
+	[r943]
+		User %u format specifier for unsigned integer.
+	[r942]
+		Make return value match signature.
+	[r941]
+		Miscellaneous minor cleanups. Mainly making return types
+		match signatues, format conversion (%u for unsigned values) and
+		matching up result variable types (bool instead of enum MAPISTATUS).
+	[r940]
+		Return an enum MAPISTATUS, instead of a bool, to match function signature.
+	[r939]
+		Use %u instead of %d for unsigned values.
+
+2008-12-20
+    bradh
+	[r937]
+		Another minor APIdox edit.
+	[r936]
+		API documentation tweak.
+	[r935]
+		API dox fix.
+	[r934]
+		API dox fix.
+	[r933]
+		Minor apidox fixes.
+	[r932]
+		More apidox triviality.
+	[r931]
+		Trivial APIdox edits.
+	[r930]
+		Supplement the user's PKG_CONFIG_PATH rather than 
+		overriding it.
+    jelmer
+	[r929]
+		Add bindings for GetBestBody(), GetDefaultFolder(), GetDefaultPublicFolder(), AddUserPermission(), ModifyUserPermission().
+	[r928]
+		Add bindings for create_message, delete_messages, get_message_status, set_read_flags.
+	[r927]
+		Add Python bindings for Unsubscribe(), get_task_status(), get_importance(), get_proptag_name(), get_proptag_value(), DeleteFolder(), CreateFolder(), EmptyFolder(), RemoveUserPermissions(), IsMailboxFolder().
+
+2008-12-19
+    jelmer
+	[r925]
+		Actually use pymapi variables in Makefile.
+	[r924]
+		Add configure flags for building and installing Python MAPI bindings (disabled by default).
+
+2008-12-18
+    bradh
+	[r922]
+		Add namespace prefix to scanner.
+
+2008-12-16
+    jkerihuel
+	[r920]
+		- spnego / gssapi_krb5 authentication now available for mapiprofile
+		- add the --realm | -R option
+		- update mapiprofile man page
+
+2008-12-14
+    bradh
+	[r912]
+		Remove entries for --properties and --priority, which have been removed from the openchangeclient utility.
+		
+		Partly fixes #113.
+	[r911]
+		Don't generate / install man3 pages for libmapi++ or mapitest.
+		
+		Resolves ticket #121.
+		
+		Also don't install man3 pages that are just copies of the C implementation files, or just document bugs / todo items.
+    jelmer
+	[r918]
+		Allow retrieving id and session of MAPI objects.
+	[r917]
+		Add MessageStore and Object Python classes, add bindings for OpenMsgStore, OpenUserMailbox, OpenPublicFolder.
+	[r916]
+		Add stubs for Session class.
+	[r915]
+		Add infrastructure for MAPI python module.
+	[r914]
+		Look for python and python-config binaries.
+	[r913]
+		Remove empty directory.
+2008-12-13
+    jkerihuel
+	[r910]
+		Remove obsolete --properties option and related code
+
+2008-12-10
+    jkerihuel
+	[r908]
+		Fix RecipientRow member's order
+
+2008-12-09
+    jkerihuel
+	[r906]
+		- Update to latest samba4 git master revision (3508a66)
+		- Fix references to samr info24 struct
+		- Add support for assoc_group_id proxy
+		- Add support in mapiproxy for bind/alter connections using assoc_group_id
+		- Update mapiproxy documentation
+
+2008-12-07
+    bradh
+	[r904]
+		Improve building. Partially addresses #94.
+		
+		More work required on this as we work on the 
+		portability in the future.
+	[r903]
+		Expose the underlying session.
+
+2008-11-30
+    bradh
+	[r901]
+		Remove unused --priority option.
+	[r900]
+		These offsets / values can be negative, so we shouldn't
+		use unsigned int type to represent them.
+
+2008-11-29
+    jkerihuel
+	[r898]
+		Fix Logon problem for users running Exchange 2k7 in a clustered Exchange environment.
+		
+		This patch first tries to forge EssDN Logon string from "o" and "ou" 
+		attributes stored in the profile. If Logon fails with ecUnknownUser,
+		then try to open the mailbox using the mailbox attribute stored in 
+		the profile.
+
+2008-11-28
+    bradh
+	[r896]
+		Document the --label option.
+
+2008-11-26
+    jkerihuel
+	[r893]
+		Make openchange compile and work against latest samba4 master git rev (58db2be)
+    jelmer
+	[r894]
+		Remove check for unused type 'uint_t'.
+
+2008-11-22
+    bradh
+	[r888]
+		More tweaks on the openchangeclient man1 page.
+	[r887]
+		More updates for man1 page for openchangeclient.
+		Still doesn't fully address #113.
+	[r886]
+		Update the openchangeclient man1 page.
+		
+		Partly addresses ticket #113.
+		
+		There is still some work to do on this.
+	[r885]
+		Fix a typo, and try to make the descriptions more
+		consistent.
+
+2008-11-21
+    bradh
+	[r883]
+		Initial version of man1 page for mapitest
+	[r882]
+		Initial man1 page for exchange2ical utility.
+
+2008-11-14
+    bradh
+	[r879]
+		Update man1 page for openchangepfadmin
+	[r878]
+		Minor updates for the man pages.
+
+2008-11-13
+    jkerihuel
+	[r875]
+		Fix build errors: wrong number of arguments for ocpf_propvalue
+	[r874]
+		Fix warnings when compiling with -Wextra
+	[r873]
+		Fix warnings when compiling with -Wextra
+	[r872]
+		Fix warnings when compiling with -Wextra
+    bradh
+	[r876]
+		Complete initializers here.
+
+2008-11-10
+    bradh
+	[r870]
+		Update to reflect latest state of mapiprofile.
+
+2008-11-09
+    bradh
+	[r868]
+		Prevent segfault when running mapitest. Looks like the we can
+		return MAPI_E_SUCCESS even if one of the property values is
+		MAPI_E_NOTFOUND. That error then get turned into a char*, and
+		strncmp faults.
+		
+		Also fix a possible bug relating to operator precedence, and 
+		a couple of warnings (one for signed / unsigned comparison, and
+		the other for an unsigned value never being less than zero).
+
+2008-11-08
+    bradh
+	[r866]
+		Enable output to stdout.
+		
+		Resolves ticket #106.
+		
+		Thanks to raboof for the report and fix.
+
+2008-11-07
+    bradh
+	[r864]
+		Fix missing initialisers (issue #110).
+		
+		Also fix some signed/unsigned warnings.
+	[r863]
+		Fix problems with incorrect initialisers (#110) and
+		operator precedence.
+		
+		Also fix a couple of places with signed/unsigned confusion.
+	[r862]
+		Partial fix for issue #110, and a couple of very minor cleanups.
+
+2008-11-06
+    bradh
+	[r860]
+		Minor cleanups.
+	[r859]
+		We probably want to return here, not do nothing.
+
+2008-11-05
+    jkerihuel
+	[r855]
+		Fix empty patch function problem: add a retval
+    bradh
+	[r857]
+		Typo fix.
+	[r856]
+		Explain the boost-thread trick.
+	[r854]
+		Minor documentation tweaks.
+
+2008-11-04
+    jkerihuel
+	[r852]
+		- remove usage of global_loadparm in libmapiadmin
+		- make use of session context rather than global_mapi_ctx in libmapiadmin
+		- use local context rather than mapiadmin context in libmapiadmin
+		- libmapiadmin now uses ldb helper rather than raw implementation (ldb async code)
+		- libmapiadmin and openchangepfadmin now works again (user creation/deletion) !! ;-)
+		- remove global_loadparm in torture test and replace it with torture context
+		- fix dcerpc_init to match latest samba4 API
+		- update samba4 version required to build openchange
+    bradh
+	[r850]
+		More API documentation tweaks.
+	[r849]
+		More API documentation tweaks.
+	[r848]
+		Some API dox fixes for libmapi++.
+    jelmer
+	[r851]
+		Remove unnecessary patching of lib/events/events.h.
+
+2008-11-03
+    bradh
+	[r846]
+		Update to a more recent Samba4.
+    jelmer
+	[r845]
+		Remove some usages of deprecated global_loadparm.
+	[r844]
+		Cope with new argument to dcerpc_log_packet().
+
+2008-11-01
+    jelmer
+	[r842]
+		Fix includes for DEBUG(), fix some more warnings.
+	[r841]
+		Use same_net_v4 rather than deprecated same_net().
+	[r840]
+		Fix Samba 4 git revision.
+	[r839]
+		Fix includes - debug.h can only be included once.
+	[r838]
+		Include debug header.
+	[r837]
+		Cope with API changes in Samba functions.
+	[r836]
+		Use new function is_zero_ip_v4 rather than removed is_zero_ip.
+
+2008-10-31
+    jkerihuel
+	[r833]
+		Fix OpenMsgStore binding in swig perl and fetchmail script
+
+2008-10-21
+    jkerihuel
+	[r824]
+		Fix pointless const definition for GetFreeBusyYear return type
+2008-10-20
+    jkerihuel
+	[r823]
+		- Add the IsFreeBusyConflict convenient function which checks if a
+		  given date conflicts with existing FreeBusy Busy/OOF events
+		
+		- Modify openchangeclient --sendappointment behavior to check whether
+		  start or end date conflicts with FreeBusy published data for the
+		  user.
+		
+		- Add the --force option to openchangeclient to override this behavior
+		
+		- Fix a counter bug in mapidump_freebusy_events
+	[r821]
+		Fix doxygen typo error
+	[r820]
+		- Add GetUserFreeBusyData convenient function which retrieves FreeBusy
+		  data in public folders for a given user. Note: Ambiguous name is not
+		  supported at the moment.
+		
+		- Add convenient FreeBusy mapidump routines
+		
+		- Add FreeBusy read support to openchangelient
+		
+		- Add PT_MV_LONG and PT_MV_BINARY support to pull_emsmdb_property and
+		  property.c functions
+		
+		- Add OpenUserMailbox which let developers open other mailboxes
+		  instead of the default profile one.
+		
+		- Add GetABRecipientInfo: convenient function which retrieves Address
+		  Book information for a given recipient
+
+2008-10-17
+    jkerihuel
+	[r818]
+		- Add libmapi implementation for DeletePropertiesNoReplicate
+		- Add mapitest test units for DeleteProps and DeletePropertiesNoReplicate
+	[r817]
+		Fix doxygen documentation
+
+2008-10-16
+    jkerihuel
+	[r815]
+		- Implement multisession into libmapi
+		- Update openchange tools and suite to reflect these changes
+		- Fix SRow_addprop behavior
+		
+		NOTE: OpenMsgStore, ResolveNames, GetGALTable and RFR functions
+		now take a mapi_session parameter.
+    jelmer
+	[r814]
+		Use my openchange.org email address.
+
+2008-10-09
+    jkerihuel
+	[r812]
+		- Add a session management API for mapiproxy modules. Similar code
+		  already existed for mpm_cache module. Common functions are now
+		  available to all mapiproxy modules through libmapiproxy
+		
+		- replace smbd with samba in mapiproxy documentation
+	[r811]
+		- Cache calendar, contact, journal, note, task and drafts folders IDs
+		  when GetDefaultFolder call is performed on one of these folders and
+		  keep them until obj_store is released.
+		
+		- Add a reverse lookup routine which says whether a given FID belongs
+		  to a default folder and which olFolderType it is.
+	[r810]
+		- Remove pointless memory context in GetDefaultFolder
+		- Move entryID to FID code into a separated routine (GetFIDFromEntryID)
+	[r809]
+		Restore install rule for mapi profiles ldif files in
+		libmapi-installscript. Fix the MAPI_E_NO_ACCESS bug when mapiprofile
+		tries to create a new mapi profile store.
+2008-10-08
+    jkerihuel
+	[r808]
+		- Ticket #103 resolved. openchangeclient can now perform custom folder lookup, fetch, mkdir and rmdir.
+		- mapi_object_copy routine added to mapi_object.c
+
+2008-10-06
+    jkerihuel
+	[r806]
+		Fix missing Month field in LogonTime structure
+2008-10-05
+    jkerihuel
+	[r805]
+		propagate IDL warning fix to property.idl
+    jelmer
+	[r804]
+		Add target for building python API documentation.
+2008-10-01
+    jkerihuel
+	[r802]
+		Fix samba4 release and git revision
+	[r801]
+		Fix installsamba4.sh script paths
+    jelmer
+	[r803]
+		Avoid warning.
+	[r800]
+		Install OpenChange python modules.
+	[r799]
+		Check for python dir during configure.
+	[r798]
+		ignore generated files.
+	[r797]
+		Stop installing js files.
+	[r796]
+		Use autoconf cache prefix.
+	[r795]
+		Use newer version of Samba 4.
+2008-09-30
+    jkerihuel
+	[r791]
+		Remove dcesrv_exchange.so from server Makefile rule and
+		move mapiproxy from TOOLS to SERVER.
+		
+		dcesrv_exchange and providers Makefile rules are orphan, planned
+		to be removed (with their associated code) when emsabp merge process 
+		into mapiproxy is over.
+2008-09-23
+    bradh
+	[r790]
+		Export the Binary_r structure.
+2008-09-22
+    bradh
+	[r789]
+		Use more descriptive variable names in messages example code.
+	[r788]
+		Add a description of messages to libmapi++ API documentation.
+	[r787]
+		Add messages binary to the ignore list.
+	[r786]
+		Add new example showing libmapi++ message handling, and
+		associated API documentation and build system changes.
+2008-09-21
+    bradh
+	[r785]
+		Update the API documentation main page for libmapi++
+2008-09-19
+    jkerihuel
+	[r784]
+		Add foldertree binary to the ignore list
+	[r783]
+		- Add missing Input parameter
+		- Add sanity check on ppNames
+		- Fix ticket #102
+	[r781]
+		- Fix a bug in NspiUpdateStat: make plDelta mandatory and use it for in,out
+		- Add a NspiGetSpecialTable test for Address Creation Template
+    bradh
+	[r780]
+		Fix valgrind-reported error, per ticket #101.
+	[r779]
+		Make sure we clean up after mapitest runs.
+		
+		Resolves ticket #84
+2008-09-17
+    jkerihuel
+	[r778]
+		- Add msExchUserAccountControl attribute to extended user record
+		- openchange_newuser can now create/enable/disable an OpenChange account
+	[r776]
+		Exit the test if the WriteStream operation fails
+	[r773]
+		Fix ncacn_ip_tcp binding string for OpenChange server object
+	[r772]
+		With new NSPI IDL, using cValues - 1 is incorrect and lead to errors. Use cValues directly instead
+	[r771]
+		Fix pipe function check and use ndr autogenerated defines rather than static strings
+		Fix calls to NspiDNToMId
+    bradh
+	[r774]
+		Make sure we set the body and body format properties, to
+		ensure that the message is shown correctly with 
+		openchangeclient -F.
+2008-09-16
+    jkerihuel
+	[r770]
+		- Fix provisioning
+		- Rename oc_* python scripts to openchange_*
+		- Add Full Exchange 2003 schema (classes and attributes)
+		- Full Exchange 2003 modified classes and attributes support 
+		- Add prefixmap OID for some Exchange classes and attributes
+		- Add missing ADSC classes and attributes
+		- Improve configuration LDIF file with new objects
+		
+		NOTE: provision.py should find a way to handle firstorg properly
+		NOTE: oc_provision_configuration.ldif is still incomplete
+    bradh
+	[r768]
+		API documentation improvements.
+2008-09-15
+    bradh
+	[r767]
+		Add an example to the libmapi++ documentation, and 
+		the right build magic and doxygen linkage.
+	[r766]
+		Minor API documentation fix
+2008-09-14
+    bradh
+	[r765]
+		Add forgotten part of API documentation fixes for mapitest.
+	[r764]
+		Improve mapitest API documentation.
+2008-09-13
+    bradh
+	[r763]
+		Use new DeleteFolder flags to clean up folders on deletion.
+		
+		This doesn't completely resolve ticket #84, but it does help.
+	[r762]
+		Ignore API documentation.
+	[r761]
+		Add Doxyfile to ignore list.
+	[r760]
+		Add initial support for Doxygen API documentation
+		for libmapiadmin.
+2008-09-12
+    bradh
+	[r759]
+		Implement the remainder of the standard public folders.
+2008-09-10
+    bradh
+	[r758]
+		Only do header line removal at the start of the file
+		(lines 20 through 40 seems like a good compromise).
+	[r757]
+		libmapi++ is C++, not C, so we should not optimise
+		Doxygen output for C.
+2008-09-09
+    jkerihuel
+	[r755]
+		- Update the Logon_repl IDL (0xFE) and implementation
+		- Add new folders to the mapi_obj_store for PF folders
+		- rename pf_finder to pf_search 
+    bradh
+	[r756]
+		Suppress some more unwanted headers.
+2008-09-08
+    jkerihuel
+	[r754]
+		- Add GetStoreState (0x7b) IDL, implementation and mapitest unit
+	[r753]
+		Fix typo error
+	[r752]
+		- Update the EmptyFolder IDL
+	[r751]
+		- Update the SearchFlags enum, GetSearchCriteria and SetSearchCriteria IDL
+		- Add mapitest units for GetSearchCriteria and SetSearchCriteria
+	[r750]
+		Link libmapi++ documentation to main apidocs page
+	[r749]
+		Update GetAttachmentTable IDL and remove the unknown field
+	[r748]
+		- Update DeleteFolder IDL and implementation
+		- It now supports DeleteFolderFlags as input parameter and can return the ParticalCompletion state
+		- Sanity checks added at the beginning of the function
+	[r747]
+		- Rename GetRowCount to QueryPosition
+		- IDL, implementation, documentation and openchange code updated
+		- ActionType enum fields prefixed with 'ActionType_'. Original
+		values were causing conflicts while building Perl bindings with
+		'i386-linux-thread-multi/CORE/opnames.h where OP_DELETE was already defined'
+	[r746]
+		Change enum SaveFlags to uint8_t for doxygen documentation to be generated properly
+	[r743]
+		- Update SaveChangesMessage IDL and implementation
+		- Add a SaveFlags parameter to SaveChangesMessage function
+		- update openchange code to reflect this change
+    bradh
+	[r745]
+		Build fix / fix for ticket #99.
+	[r744]
+		Filter out some new #include lines.
+		
+		This needs to be applied to other modules too.
+2008-09-07
+    jkerihuel
+	[r742]
+		Update SRow and SRowSet IDL
+	[r741]
+		Delete obsolete input_locale and instance_key structures
+	[r740]
+		Fix WStringArray_r IDL
+	[r739]
+		- Move from MV_UNICODE_STRUCT and LPWSTR to WStringArray
+		- LPWSTR structure removed
+	[r738]
+		Rename SDateTimeArray to DateTimeArray_r
+	[r737]
+		Rename SGuidArray to FlatUIDArray_r and fix the IDL
+	[r736]
+		Rename MV_LONG_STRUCT to LongArray_r
+	[r735]
+		Rename SBinary to Binary_r
+	[r734]
+		- Add removal of libmapi++ Doxyfile in make distclean rule
+		- Add Doxyfile to svn:ignore 
+	[r733]
+		Rename SShortArray to ShortArray_r
+	[r732]
+		- Move from SLPSTRArray to StringArray_r
+		- LPSTR structure removed
+	[r731]
+		Rename MAPIUID to FlatUID_r
+	[r730]
+		Fix lexer warnings during compilation (ticket #100)
+	[r729]
+		- Update the EcDoConnect IDL (ref. ticket #99)
+		- Add new fields to the emsmdb info structure
+		- Add doxygen comments to libmapi/emsmdb.c
+    bradh
+	[r728]
+		Reduce warnings when compiling with 64-bit arch.
+	[r727]
+		Initial checkin of infrastructure for libmapi++ API documentation.
+2008-09-06
+    jkerihuel
+	[r726]
+		- MAJOR NSPI protocol and libmapi stack update
+		- All NSPI protocol functions implemented
+		- NSPI stack fully documented
+		- NspiGetHierarchyInfo renamed to NspiGetSpecialTable
+		- NspiDNToEph renamed to NspiDNToMId
+		- instance_key removed from nspi_context and set as a parameter to NSPI functions
+		- SPropertyRestriction renamed to PropertyRestriction_r
+		- FlagList structure removed and replaced by a SPropTagArray
+		- MAPI_SETTINGS removed and replaced by a STAT structure
+		- new MAPI property tags added to libmapi/conf/mapi-properties
+		- NSPI module added to mapitest
+    bradh
+	[r725]
+		Clean up on failure.
+	[r724]
+		Clean up on failure.
+	[r723]
+		Minor improvements to ensure cleanup on failure.
+	[r722]
+		API documentation fix
+	[r721]
+		API documentation fix.
+	[r720]
+		API documentation fix.
+	[r719]
+		API documentation fix.
+	[r718]
+		API documentation fixes.
+2008-09-05
+    bradh
+	[r717]
+		API documentation fixes.
+2008-09-04
+    jkerihuel
+	[r716]
+		Fix EMSMDB 0xb function name
+	[r715]
+		- update EcRRegisterPushNotification IDL
+		- update Notify IDL
+		- implement complete MAPI notifications
+		- update libmapi to reflect these changes
+		- make openchangeclient prints a brief summary for each notification found
+		- update ulEventMask used in openchangeclient
+2008-09-03
+    jkerihuel
+	[r714]
+		- Rename Advise MAPI call to RegisterNotification
+		- Update RegisterNotification IDL and implementation
+2008-09-02
+    jkerihuel
+	[r713]
+		- Fix Restrict IDL and implementation
+		- Add a new parameter to the Restrict function
+		- close ticket #32
+	[r712]
+		Add mapi_nameid.h to the ignore list
+	[r711]
+		- Replace libmapi/mapi_nameid.h with a generated mparse file
+		- Add a mapi_nameid.h parser to mparse.pl
+		- Add canonical names for named properties
+		- GetProps and SetProps resolves named properties if they exist
+		- named properties can now be set directly and make mapi_nameid API be
+		  optional.
+		- replace named property tags hex value with their canonimal names
+		- replace several use of the mapi_nameid API with smaller code
+	[r710]
+		- Add new IDL file (property.idl) to push/pull structures from binary
+		  blobs and not directly related to any MAPI calls. Include the
+		  generated property.h file into libmapi.h
+		
+		- Add PT_MV_STRING8 support in pull_emsmdb_property (GetProps reply
+		  parsing) and mapidump_SPropValue
+		
+		- Add functions to property.c to retrieve RecurrencePattern,
+		  TimeZoneStruct and GlobalObjectId structures (see property.idl).
+		
+		- add a preliminary version of exchange2ical tool. This version only
+		  dumps calendar folder appointments into ICS file on standard output.
+2008-08-30
+    jkerihuel
+	[r709]
+		- Update mapi-nameid-properties with a more complete set of properties
+		- Add a header to mapi-nameid-properties for sanity purposes
+		- Move named properties with PT_STRING8 type to PT_UNICODE
+		- update openchange code to reflect these changes
+		- Add PSETID_Attachment to mapidefs.h
+2008-08-28
+    jkerihuel
+	[r707]
+		Add missing check on password for the create command
+	[r706]
+		Fix incorrect usage of realm in mapiproxy
+2008-08-27
+    jkerihuel
+	[r705]
+		Check for provider_rpc_connection retval for RFR functions.
+	[r704]
+		Update Doxyfile to parse mapiproxy/modules files and
+		include documentation on static functions.
+	[r703]
+		- Add NSPI hook on NspiQueryRows and NspiDNToEph and replace the
+		  Exchange server name with mapiproxy one.
+		- documentation updated to reflect these changes
+		- new FAQ question added
+		- developer documentation improved
+	[r702]
+		Add the RFR mapiproxy file.
+	[r701]
+		- Implement RfrGetNewDSA DN replacement in mapiproxy
+		- use lp_realm rather than sockaddr in NspiGetProps (FQDN rather than IP address)
+		- update mapiproxy documentation to reflect these changes
+2008-08-26
+    jkerihuel
+	[r698]
+		- Add implementation of the NSPI Referral protocol (exchangeRFR)
+		- update dcesrv_exchange and mapiproxy prototypes for RFR
+		- add references to the RFR pipe in mapiproxy
+		- prefix NSPI client connections with a RfrGetNewDSA call
+		- add RFR functions implementation in libmapi/IMSProvider.c
+		- add a --getfqdn option to mapiprofile
+		- fix a minor mapiprofile option parsing bug
+2008-08-25
+    jkerihuel
+	[r697]
+		Fix mapiproxy dummy module unbind prototype
+	[r696]
+		- Remove flags in EcDoRpc top function, fix compilation vs latest samba4-git version
+		- EcDoRpc indent updated
+2008-08-15
+    clsk
+	[r694]
+		Get rid of initialization order warning
+2008-08-11
+    jkerihuel
+	[r691]
+		- add unbind hook for mapiproxy
+		- add ahead mapiproxy mode
+		- add read ahead in cache module
+		- add synchronization mechanism in cache module
+		- update mapiproxy documentation to reflect these changes
+2008-08-08
+    bradh
+	[r690]
+		Temporarily comment out installation of files removed
+		in r683.
+2008-08-01
+    jelmer
+	[r685]
+		Fix arguments, paths in provision scripts.
+	[r683]
+		Merge python provision/newuser scripts.
+	[r681]
+		Simplify installation of manpages a bit.
+2008-07-29
+    jkerihuel
+	[r679]
+		Add configure check for libboost-thread. Add libmapi++ to the build
+		only if it is available.
+2008-07-27
+    clsk
+	[r678]
+		- session constructor doesn't login to the server anymore, it calls MAPIInitialize().
+		- Created session::login() members.
+		- test applications use default profile.
+2008-07-26
+    jkerihuel
+	[r676]
+		- Import Alan Alvarez work from libmapi++ into trunk
+		- Add a g++ check in configure.ac: don't call libmapi++ rules if g++
+		  is missing
+		- Add libmapi++ to the build system
+		- Add a patch function to installsamba4.sh: rename private to
+		  private_data in samba4 events.h header file
+		- Change #include directives so it uses <libmapi++ ... rather than
+		  relative paths.
+2008-07-24
+    jkerihuel
+	[r674]
+		- Add a statitic function monitoring streams over OpenStream and Last
+		  ReadStream operations. Monitoring stream Release is not relevant
+		  since Outlook does not close the handle directly after last
+		  ReadStream operation. Should put in evidence difference between
+		  non-cached(1st retrieval) and cached (further retrieval).
+		
+		- Fix a few memory leaks
+2008-07-23
+    jkerihuel
+	[r672]
+		- Commit initial revision for the mapiproxy cache module
+		- Update mapiproxy hook API for the dispatch routine
+		- Introduce the mapiproxy structure for modules to control top-level
+		  mapiproxy behavior.
+		- Update mapiproxy documentation to reflect these changes
+2008-07-21
+    jkerihuel
+	[r670]
+		* Fix remaining ByteRead parameter size for ReadStream operations.
+2008-07-20
+    jkerihuel
+	[r669]
+		* Improve/Update Open/Read/WriteStream IDLs
+		* Fix ByteRead parameter size for ReadStream operation.
+2008-07-19
+    jkerihuel
+	[r668]
+		Improve OpenAttach, CreateAttach and DeleteAttach IDL - remove unknown
+		parameters.
+	[r667]
+		Propagate r666 changes to OpenMsgStore and fix build
+    bradh
+	[r666]
+		Minor rename of bitmap value to avoid conflict with
+		Private as a class name.
+2008-07-17
+    jkerihuel
+	[r663]
+		Minor change: remove old debugging string from mapitest
+	[r660]
+		Fix incorrect header
+	[r658]
+		Remove deprecated mapi_handles API
+    bradh
+	[r665]
+		Initial checkin of some uno (static checker) support
+		files.
+		
+		There will be a script to run uno with the right options,
+		but that requires more work.
+2008-07-16
+    jkerihuel
+	[r655]
+		Fix OXOMSG-ABORT-SUBMIT return value and return success when expected
+		error values (MAPI_E_UNABLE_TO_ABORT, ecNoDelSubmitMsg) are encountered.
+	[r654]
+		- Call mapi_object_release in GetDefaultFolder
+		- Remove pointless references to mapi_object_t
+    bradh
+	[r656]
+		Fix little memory leak.
+2008-07-15
+    jkerihuel
+	[r653]
+		Fix invalid OpenFolder calls in mapitest modules
+	[r652]
+		Remove references to SaveChanges in doxygen see also statement
+	[r651]
+		- Rename SaveChanges to SaveChangesAttachment (0x25)
+		- Update SaveChangesAttachment IDL
+		- Update references to SaveChanges
+	[r650]
+		- Fix the huge memory leak described in Ticket #91
+		- Rewrite the mapitest NameID test to use the mapi_nameid convenient
+		  API
+2008-07-12
+    jkerihuel
+	[r648]
+		- Add mapi_get_errstr auto-generated routine which returns the MAPI
+		  retval as a string
+		- Add print routine for MAPI retval in mapitest
+		- Add a color mode (--color) which prints either green or red MAPISTATUS
+		- Update mapitest modules to use these new routines
+    bradh
+	[r647]
+		Minor API documentation fix.
+2008-07-11
+    jkerihuel
+	[r646]
+		Add all MAPI errors
+	[r645]
+		- Add GetOwningServers (0x42) implementation (IDL + libmapi + mapitest)
+	[r644]
+		- Report and make consistent usage of PropertyProblem in the IDL:
+		  SetProps, DeleteProps and CopyProperties
+		
+		- Remove unknown field in GetProps and GetPropsAll and replace them
+		  with the correct IDL mapping.
+		
+		- Add IDL for SetPropertiesNoReplicate (0x79) MAPI call
+		
+		- Minor typo fix in IMAPIProp.c
+	[r643]
+		Improve CreateMessage request IDL
+	[r642]
+		Improve OpenMessage response IDL
+	[r641]
+		- Add PublicFolderIsGhosted (0x45) MAPI call (IDL + libmapi + mapitest)
+		
+		- Improve OpenFolder, CreateFolder and OpenPublicFolderByName response
+		  IDL: make these call able to check whether the folder is ghosted or
+		  not.
+	[r640]
+		Revert emsmdb pipe version to the hacked one. Makes mapiproxy work with samba4-alpha5 release.
+	[r639]
+		SeekRow and SeekRowBookmark IDL improved
+	[r638]
+		Improve the SetColumns IDL: remove unknown fields
+2008-07-06
+    jkerihuel
+	[r637]
+		Minor code convention fix
+	[r636]
+		Check NTSTATUS return value from dcerpc_ndr_request. Prevent mapiproxy
+		from segfault when invalid dcerpc response is received.
+	[r635]
+		Expose MAPISTATUS error in OXCTABLE-CATEGORY::FreeBookmark. 
+		Requires investigation
+    bradh
+	[r634]
+		Implement GetIdFromLongTermId and GetLongTermIdFromId
+		functions (ROP:0x43 and 0x44), and associated mapitest.
+	[r633]
+		Documentation typo fix.
+	[r632]
+		Change the QueryNamesFromIDs() call to match
+		MSDN, including changing the name to QueryNamedProperties().
+		
+		Also implement mapitest for QueryNamedProperties(),
+		GetNamesFromIDs() and GetIDsFromNames().
+		
+		Update torture test to match.
+2008-07-05
+    jkerihuel
+	[r631]
+		- Build system update: use samba4-alpha5 release with wget method
+		- introduce 'make samba' and 'make samba-git'
+2008-07-04
+    bradh
+	[r630]
+		Make sure we have names[] array large enough.
+		
+		Problem identified using default uno run.
+		
+		Resolves #87.
+2008-07-03
+    jkerihuel
+	[r629]
+		Fix a small errno bug in GetBestBody
+		Add dump-data and debug options to exchange2mbox
+2008-06-30
+    jkerihuel
+	[r627]
+		- Move emsmdb interface version back to 0.81 (patch applied in samba4 trunk)
+		- remove sed hack, modifications applied in samba4 trunk
+		- update required samba4 git rev required
+    bradh
+	[r628]
+		Typo fix.
+2008-06-25
+    jkerihuel
+	[r626]
+		Minor documentation update: remove deprecated reference to ./bin/smbpython
+	[r625]
+		Fix torture suite entry point name
+		Fix torture module installation path
+	[r624]
+		- Add implementation for the BestBody algorithm
+		- Add MAPI_E_NOT_ENOUGH_MEMORY error code
+		- Remove trailing }}\0 from lzfu code
+		- Update openchange tools to use GetBestBody rather than
+		the initial check on PR_MSG_EDITOR_FORMAT
+	[r623]
+		Add a very basic stat module for mapitest: gives a quick overview
+		of tests which failed at the end of the report.
+	[r622]
+		- Defines a global stream size in mapitest.h
+		- Decrease stream size from 0x4000 to 0x3000
+		  Sounds like Exchange 2003 SP2 doesn't support 0x4000, return MAPI_E_CALL_FAILED
+		 
+2008-06-24
+    jkerihuel
+	[r621]
+		Fix OC_CHECK_SAMBA_VERSION string
+	[r620]
+		- Move samba4_ver.sh from top dir to script
+		- update parts of openchange relying on samba4_ver.sh
+	[r619]
+		Add configure check for lib Z
+		 
+	[r618]
+		- Temporary fix ldb.pc problem and patch ldb.pc.in
+		- Update samba4 version to the latest revision
+		- Add libmapiproxy to svn:ignore proplist
+    bradh
+	[r617]
+		Try a different git revision, just for now.
+2008-06-17
+    jkerihuel
+	[r614]
+		- Update Samba4 version needed
+		- Change entry point function from init_module to samba_init_module
+		- update documentation
+2008-06-16
+    jelmer
+	[r613]
+		Fix calls of ldb_init() as required by newer versions of Samba.
+	[r612]
+		Avoid bashisms.
+	[r611]
+		Support newer versions of Samba4.
+2008-06-14
+    bradh
+	[r609]
+		Add some other standard GUIDs
+2008-06-11
+    jelmer
+	[r605]
+		Fix silly typo.
+	[r604]
+		Fix linking.
+	[r603]
+		Use version and soversion in mapiproxy library.
+	[r602]
+		Make modules directory overridable.
+2008-06-10
+    bradh
+	[r601]
+		Change API as identified on devel mailing list.
+		
+		Here is the email:
+		After some investigation into an error reported by valgrind, I'm proposing an
+		API change for the MoveCopyMessages() function.
+		
+		The signature is currently
+		enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,  mapi_object_t 
+		*obj_dst,  mapi_id_t *message_id,  bool WantCopy)
+		
+		The problem is the message_id array. The subtle part is that it needs to be 
+		terminated with a null mapi_id_t*, because of this:
+		for (request.count = 0; message_id[request.count]; request.count++);
+		
+		That is a bit error prone - enough so to be wrong in the mapitest.
+		
+		Now we could just fix the mapitest and document the requirements, or we could 
+		change the signature.
+		
+		Two ideas for a different signature:
+		1. We could add a uint16_t count to the signature, that says how long the 
+		array is.
+		2. We could use a better data structure than mapi_id_t*. I'm suggesting
+		mapi_id_array_t:
+		enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,
+		                                          mapi_object_t *obj_dst,
+		                                          mapi_id_array_t *message_id,
+		                                          bool WantCopy)
+2008-06-09
+    bradh
+	[r600]
+		Add mapitest coverage for CopyTo operations on 
+		folders and attachments, and update API docs.
+		
+		Also fix one place where we inadvertently used
+		CopyProps instead of CopyTo...
+2008-06-08
+    bradh
+	[r597]
+		Typo fixes in comments.
+	[r596]
+		Minor documentation updates.
+	[r595]
+		Clean up created message for SpoolerLockMessage() test.
+2008-06-07
+    bradh
+	[r594]
+		Update samba4 version test.
+	[r593]
+		typo fix.
+	[r592]
+		Make sure properties are copies into the last valid 
+		location in the extended array (i.e. count-1) not the
+		count location.
+		
+		Also, make sure we cast the data to a uint8_t for
+		conversion to boolean.
+		
+		Also fix compile warning about returning integer instead
+		of pointer.
+	[r591]
+		We may read up to 0x1000 bytes, so ensure there is
+		enough room to add the terminating null.
+	[r590]
+		Minor cleanup of the talloc context for FreeBookmark().
+		
+		Also change around some code to protect things a bit
+		better against null pointer inputs.
+2008-06-06
+    bradh
+	[r588]
+		Implement a bit more mapitest for CopyTo (0x39), in
+		support of #83.
+		
+		Also make it clean up and report failures properly.
+2008-06-05
+    bradh
+	[r587]
+		Implement the CopyTo operation (0x39), including initial mapitest.
+		JK previously committed the IDL for this.
+		
+		Also make CopyProps (0x67) use an appropriate data structure for
+		its IDL and update implementation to match.
+2008-06-04
+    bradh
+	[r586]
+		Minor documentation updates/corrections.
+2008-06-02
+    jkerihuel
+	[r583]
+		Introduce a default case for MAPI Restriction. In some circumstances -
+		while Outlook creates an OOF Rules - it sets a PT_SRESTRICT mapi
+		property tag which value is set to 0xFF. However 0xFF doesn't match
+		any restriction case.
+2008-06-01
+    jkerihuel
+	[r582]
+		- Add IDL for OpenEmbeddedMessage (0x46) MAPI call
+	[r581]
+		- Add IDL for ReloadCachedInformation (0x10) MAPI call
+	[r580]
+		- Add IDL for CopyTo (0x39) MAPI call
+	[r573]
+		- Update the Samba4 GIT revision needed to run openchange properly
+	[r572]
+		- import mapiproxy project from mapiproxy branch
+		- add custom proxypack MAPI call
+		- remove deprecated dcesrv_exchange_remote
+    bradh
+	[r579]
+		Add missing part of mapitest for SetReadFlags
+		
+		This should have been part of r578.
+	[r578]
+		mapitest for SetReadFlags
+	[r577]
+		Implement SetReadFlags (operation 0x66).
+		
+		Also minor API docs fix.
+	[r576]
+		Move some test infrastructure from the oxctable.c module
+		into the common area.
+	[r575]
+		Fix IDL error for SetReadFlags, and use existing flags
+		define (MSGFLAGS_READ) instead of creating a new set.
+	[r574]
+		Build fix for relocation of mapiproxy/ to be under the
+		top level directory (instead of under the utils/
+		directory)
+2008-05-31
+    jkerihuel
+	[r571]
+		merge from mapiproxy branch:
+		      * ndr_push Logon_req manually
+	[r568]
+		merge from mapiproxy branch:
+		      * Add IDL and server boiler template for EcDoConnectEx (0xA)
+		        EMSMDB RPC function
+		
+		      * Fix ndr_push_mapi_response code in ndr_mapi.c
+		
+		      * Add the ndr_push_EcDoRpc_MAPI_REPL function in
+		        ndr_mapi.c. Handles special Notify and Pending cases
+		
+		      * Handle op_MAPI_Pending case properly in
+		        ndr_pull_EcDoRpc_MAPI_REPL
+		
+		      * Add code to ndr_push QueryRows in ndr_mapi.c: Do not push any
+		        DATA_BLOB if there is no RowCount
+	[r565]
+		merge from mapiproxy branch:
+		      * Fix GetReceiveFolder [out] IDL
+		      * Fix some naming convention typo
+	[r564]
+		merge from mapiproxy branch:
+		      * Fix SetMessagReadFlag [out] IDL
+	[r563]
+		- Add [flag(NDR_REMAINING)] to SetMessageReadFlag. This is not
+		  perfect, but it will prevent mapiproxy from ndr_pull error while
+		  setting message read flag on public folders messages.
+	[r562]
+		merge from mapiproxy branch:
+		      * Fix CreateMessage [out] IDL
+	[r561]
+		merge from mapiproxy branch:
+		      * rename OpenModeFlags to OpenFolder_OpenModeFlags in OpenFolder
+		      * rewrite OpenMessage [in] IDL and report changes in
+		        libmapi/IStoreFolder.c
+	[r560]
+		merge from mapiproxy branch:
+		      * Add IDL for Pending (0x6e) MAPI call
+		      * Reorder some MAPI calls in EcDoRpc_MAPI_REPL_UNION
+	[r559]
+		- Add SetReadFlags to EcDoRpc_MAPI_{REQ,REPL}_UNION
+	[r558]
+		merge from mapiproxy branch:
+		      * Add IDL for SetSyncNotificationGuid (0x88) MAPI call
+	[r557]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncGetTransferState (0x82) MAPI call
+	[r556]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncImportReadStateChanges (0x80) MAPI call
+		
+		Note: This IDL is temporary and should be improved after completion of
+		the merging process.
+	[r555]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncOpenCollector (0x7e) MAPI call
+	[r554]
+		merge from mapiproxy branch:
+		      * Add IDL for DeletePropertiesNoReplicate (0x7a) MAPI call
+	[r553]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncImportMessageMove (0x78) MAPI call
+	[r552]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncUploadStateStreamBegin (0x75) MAPI call
+		      * Add IDL for SyncUploadStateStreamContinue (0x76) MAPI call
+		      * Add IDL for SyncUploadStateStreamEnd (0x77) MAPI call
+	[r551]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncImportDeletes (0x74) MAPI call
+	[r550]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncImportHierarchyChange (0x73) MAPI call
+	[r549]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncImportMessageChange (0x72) MAPI call
+	[r548]
+		merge from mapiproxy branch:
+		      * Add IDL for SyncConfigure (0x70) MAPI call
+	[r547]
+		merge from mapiproxy branch:
+		      * Add IDL for RegisterOptions (0x6f) MAPI call
+		
+		Note: This call is undocumented in Microsoft documentation, but MSDN
+		RegisterOptions function generates this call on the wire.
+	[r546]
+		merge from mapiproxy branch:
+		      * Add IDL for Progress (0x50) MAPI call
+	[r545]
+		merge from mapiproxy branch:
+		      * Add IDL for FastTransferSourceGetBuffer (0x4a) MAPI call
+	[r544]
+		merge from mapiproxy branch:
+		      * Add IDL for GetPerUserLongTermIds (0x60) MAPI call
+		      * Add IDL for GetPerUserGuid (0x61) MAPI call
+		      * Add IDL for ReadPerUserInformation (0x63) MAPI call
+	[r543]
+		merge from mapiproxy branch:
+		      * Add IDL for LongTermIdFromId (0x43) MAPI call
+		      * Add IDL for IdFromLongTermId (0x44) MAPI call
+	[r542]
+		merge from mapiproxy branch:
+		      * Add IDL for ModifyRules (0x41) MAPI call
+	[r541]
+		merge from mapiproxy branch:
+		      * Add PT_SRESTRICT support in mapi_SPropValue_CTR
+		
+		      * Add PT_ACTIONS and RuleAction support in mapi_SPropValue_CTR
+		
+		      * Fix mapi_SNotRestriction NDR push routine - add a wrapper to
+		        work around the no-pointer deep recursion pb and remove
+		        existing nopull,nopush,noprint code from ndr_mapi.c
+		
+		      * Fix mapi_SComment_Restriction IDL
+		      
+	[r540]
+		- Introduce PT_MV_UNICODE support in mapi_SPropValue_CTR (IDL only)
+		- use mapi_LPWSTR for PT_MV_UNICODE
+		- rename mapi_LPWSTR structure to mapi_name in Kind structure and
+		  change its field names.
+	[r536]
+		- Fix emsmdb version
+		- Change MAPI opnum enum identation -- Helps to fine down merging from
+		  mapiproxy branch
+    bradh
+	[r539]
+		API docs typo fix.
+	[r538]
+		Minor API documentation fixes.
+	[r537]
+		Update label to reflect SetReadFlags -> SetMessageReadFlag 
+		renaming.
+		
+		This should have been part of r529 - missed it.
+2008-05-30
+    jkerihuel
+	[r535]
+		merging from mapiproxy branch:
+			- Fix MV_UNICODE_STRUCT and unicode strings
+			- Keep LPWSTR for exchange_nsp and move from LPWSTR to
+		          mapi_LPWSTR for exchange_emsmdb
+			- Add the NspiGetTemplateInfo IDL
+			- Fix the NspiUpdateStat IDL
+	[r534]
+		Fix build: SetMessageReadFlag function name was not propagated in the
+		module_oxcmsg.c
+    bradh
+	[r529]
+		Initial merge of changes for rename of SetReadFlags to
+		SetMessageReadFlags (op 0x11) and IDL for SetReadFlags 
+		(op 0x66).
+	[r528]
+		Use private_data instead of private, for C++ happiness.
+	[r527]
+		Minor cleanup. Using "try" confuses my c++ compiler...
+	[r526]
+		This is really part of r525. It moved to IMAPITable.c
+	[r525]
+		Update the table operations:
+		 - implement ExpandRow and CollapseRow
+		 - implement GetCollapseState and SetCollapseState
+		 - add mapitest coverage for the above, plus the Restrict call
+		 - implement ResetTable
+		 - implement FreeBookmark
+		 - add mapitest coverage for SRowSet parsing code
+		 - minor IDL fixes
+		 - various API documentation bits
+    jelmer
+	[r533]
+		Use right directory for samba4_ver.sh script.
+	[r532]
+		Use common location for Samba 4 git revision.
+2008-05-27
+    bradh
+	[r522]
+		Use PT_ERROR where appropriate.
+	[r521]
+		Update the SRowSet parser, fixing breakage I introduced.
+2008-05-26
+    bradh
+	[r518]
+		Update examples to reflect recent API changes.
+    jelmer
+	[r520]
+		Don't rely on absolute file paths since the distribution may be installing 
+		in other locations.
+	[r519]
+		make scripts executable.
+2008-05-25
+    bradh
+	[r515]
+		Avoid segfaulting if you ask for a specific test or tests and 
+		forgot to start the server.
+		
+		Here is an example:
+		[bradh at conferta trunk]$ ./bin/mapitest --mapi-calls=OXCTABLE-CATEGORY --mapi-calls=OXCTABLE-RESTRICT --mapi-calls=NOSERVER-LZFU
+		Failed to connect host 192.168.11.77 on port 135 - NT_STATUS_HOST_UNREACHABLE
+		Failed to connect host 192.168.11.77 (192.168.11.77) on port 135 - NT_STATUS_HOST_UNREACHABLE.
+		    MapiLogonEx              : MAPI_E_RESERVED (0xFFFFFFFF)
+		#############################[mapitest report]#################################
+		        [*] Date                     : Sun May 25 11:45:29 2008
+		        [*] Confidential mode        : [no]
+		        [*] Samba Information        : 4.0.0alpha4-GIT-44d8b70
+		        [*] OpenChange Information   : 0.8-SVN-build-510 (Romulus)
+		
+		        [*] System Information       :
+		                Kernel name          : Linux
+		                Kernel release       : 2.6.23.17-88.fc7
+		                Processor            : x86_64
+		###############################################################################
+		
+		
+		[*] NOSERVER-LZFU
+		[TEST] NOSERVER-LZFU
+		------------------------------------------------------------------------
+		        * uncompress_rtf2                    : 0x00000000
+		        * uncompress_rtf2                    : PASSED
+		------------------------------------------------------------------------
+		[RESULT] NOSERVER-LZFU: [SUCCESS]
+		========================================================================
+		
+		[*] OXCTABLE-RESTRICT
+		Server is offline, skipping test: "OXCTABLE-RESTRICT"
+		[*] OXCTABLE-CATEGORY
+		Server is offline, skipping test: "OXCTABLE-CATEGORY"
+2008-05-24
+    bradh
+	[r510]
+		ignores objects that contain invalid handlers in mapi_object_release().
+		
+		Patch by Alan Alvarez. Compile tested, passes mapitest on SBS2003.
+2008-05-23
+    bradh
+	[r507]
+		Fix API documentation to match signature.
+2008-05-20
+    bradh
+	[r504]
+		Update QueryRows IDL and implementation to match
+		msdn documentation.
+		
+		The main work here is reworking the SRowSet parsing
+		routine.
+2008-05-18
+    bradh
+	[r501]
+		Typo fix - allow cleanup to work properly.
+2008-05-17
+    bradh
+	[r497]
+		Make sure it has a return value.
+2008-05-11
+    bradh
+	[r495]
+		Rename GetColumns remote operation to GetColumnsAll, and 
+		fix up IDL and implementation to match.
+		
+		Add some more unit test coverage, and pretty-up the
+		output a little.
+	[r494]
+		Fix up breakage introduced in r493.
+    jelmer
+	[r496]
+		Make sure nagios directory gets created if it didn't exist yet.
+2008-05-10
+    bradh
+	[r493]
+		Refactor the unit tests.
+		
+		Extract out the setup and some of the cleanup code.
+2008-05-08
+    jkerihuel
+	[r490]
+		- Update openchange code to work with Samba4 4.0.0alpha4-GIT-44d8b70
+		- Use event_context structure
+		- update installsamba4.sh script to revert to this revision.
+		- update torture modulesdir reference
+    jelmer
+	[r492]
+		Look a little bit harder for the Samba installation.
+2008-05-05
+    jkerihuel
+	[r489]
+		- Add GetLocalReplicaIds MAPI call (IDL + implementation + mapitest)
+		- Add OXCFXICS mapitest module
+2008-05-03
+    jkerihuel
+	[r488]
+		- Fix "the very secret" openchange coding style
+		- Add Copyright for our humble new libmapi developer ;-)
+    bradh
+	[r487]
+		Implement the CopyProperties operation, including
+		a mapitest for this.
+2008-05-02
+    jkerihuel
+	[r485]
+		- Add TransportSend MAPI call (IDL + implementation + mapitest). This
+		code maybe needs some review regarding memory.
+	[r484]
+		- Add the GetTransportFolder MAPI call (IDL + implementation +
+		  mapitest)
+	[r483]
+		- Add SpoolerLockMessage MAPI call (IDL + implementation + mapitest)
+	[r482]
+		- Add SetSpooler MAPI call (IDL + implementation + mapitest)
+	[r481]
+		- Add GetRulesTable (IDL + implementation + mapitest)
+		- Add the OXORULE mapitest suite
+    bradh
+	[r480]
+		Typo fix.
+    jelmer
+	[r486]
+		Make sure config.mk is the last file removed during distclean.
+2008-05-01
+    jkerihuel
+	[r479]
+		- Add the Abort MAPI call (IDL + implementation)
+		
+		OpenChange doesn't support yet asynchronous operation which explains
+		why no associated mapitest test has been implemented. This should be
+		done in the future.
+	[r478]
+		- Add the MoveFolder MAPI call (IDL + implementation + mapitest)
+		- Fix some typo in mapitest doxygen
+	[r477]
+		- Add MoveFolder MAPI call (IDL + implementation + mapitest)
+		- Fix some doxygen stuff
+		- add a common function within mapitest which looks for a folder name
+		  within a container and return the opened folder object on success.
+	[r476]
+		Add auto-generated Doxyfile to the svn ignore list
+	[r475]
+		- Add AbortSubmit MAPI call (IDL + implementation + mapitest)
+	[r473]
+		- Uninitialize MAPI and general memory context at the end of mapitest
+    bradh
+	[r474]
+		Clean up / flush the stream after use. 
+		
+		Saves a bit more "still reachable" in valgrind too.
+2008-04-30
+    jkerihuel
+	[r470]
+		- Rename CopyMessages to MoveCopyMessages
+		- Improve IDL + implementation and mapitest added
+    bradh
+	[r471]
+		Make sure the version shown for mapitest documentation
+		is automatically set to match the package version.
+	[r468]
+		complete the rest of the API documentation autonumbering.
+    jelmer
+	[r472]
+		Remove duplicate use of $(SHLIBEXT).
+	[r469]
+		Avoid parallel builds for now.
+2008-04-29
+    jkerihuel
+	[r467]
+		Fix GetContentsTable binding in perl swig
+	[r466]
+		- Improve the GetHierarchyTable and GetContentsTable IDL and public
+		  IDL implementation (new parameters in,out)
+    bradh
+	[r465]
+		Initial part of automatic list numbering for doxygen comments.
+		
+		This doesn't work correctly with the current apidocs.css, which
+		turns the list numbers into bullet points for reasons I don't 
+		understand.
+2008-04-28
+    jkerihuel
+	[r464]
+		- Improve the DeleteMessages IDL request
+	[r463]
+		- Update libmapi version from 0.7 to 0.8
+		
+		- Public API change for the GetReceiveFolder function; now takes a
+		  message class as 3rd parameter.
+	[r458]
+		- Improve GetSearchCriteria request IDL (unknown removed)
+		- update libmapi copyright headers 2007 -> 2007-2008.
+	[r457]
+		- Improve the SubmitMessage IDL
+		- minor indentation fixed in IMessage.c
+	[r456]
+		- Add CopyToStream MAPI call (IDL + implementation + mapitest)
+	[r455]
+		- Add SeekStream MAPI call (IDL + implementation + mapitest)
+		- Add SetStreamSize MAPI call (IDL + implementation + mapitest)
+	[r454]
+		- Add CommitStream MAPI call (IDL + implementation + mapitest)
+		- Add GetStreamSize MAPI call (IDL + implementation + mapitest)
+		- refactor the stream test to include all stream related operations
+		- add a common function which generates a random ASCII blob of data
+    bradh
+	[r453]
+		Add doxygen support for the mapitest examples.
+    jelmer
+	[r459]
+		Allow cleaning individual parts.
+2008-04-27
+    jkerihuel
+	[r452]
+		- Add GetStatus call (IDL + implementation + mapitest)
+	[r451]
+		- Fix format string problem in mapitest headers
+	[r450]
+		Run offline suites by default.
+	[r449]
+		- Introduce the online/offline mode for suite
+		- Fix Exchange headers print bug when server is offline
+		- reset errno to 0 before running new test
+    bradh
+	[r447]
+		Install the libmapiadmin.h header.
+	[r446]
+		Fix a compile-time warning on amd64, for the second
+		argument to the getline() call - incompatible pointer
+		type.
+		
+		I'm assuming that size_t is equivalent to uint32_t
+		on a 32-bit architecture, but not on a 64-bit arch.
+		
+		A quick test showed no difference in actual output.
+    jelmer
+	[r448]
+		Remove bashisms in installsamba4.sh
+2008-04-26
+    jkerihuel
+	[r445]
+		- Add ReadRecipients MAPI call (IDL + implementation + mapitest)
+		- Improve some ModifyRecipients and Recipients structure naming
+2008-04-25
+    jkerihuel
+	[r444]
+		- Add RemoveAllRecipients call (IDL + implementation + mapitest)
+	[r443]
+		- Add OpenPublicFolderByName call added (IDL and implementation).
+		
+		- Note: the reply IDL doesn't handle Server and ServerCount yet.
+		
+		- Note: this call only refers to NNTP folders (e.g: folders located
+		within "Internet Newsgroups". If developers use this call within "All
+		Public Folders", then the call with return MAPI_E_NOT_FOUND.
+		
+		- Call not added to mapitest cause it require RightsAuthor permissions
+		on Internet Newsgroups which is not the case by default.
+		
+		- dump-data and debug options added to mapitest
+		- FOLDER suite renamed to OXCFOLD (naming convention)
+	[r441]
+		Rename module folder to oxcfold
+	[r440]
+		Replace the existing mapitest tool with a new implementation. It is
+		less complete but more modular.
+    jelmer
+	[r442]
+		Add proto headers to ignore file.
+2008-04-20
+    jkerihuel
+	[r438]
+		OpenFolder request: replace unknown field with OpenModeFlags
+	[r437]
+		- Rename 0xFE opnum from OpenMsgStore to Logon
+		- Update the Logon request IDL
+    bradh
+	[r439]
+		Add BEGIN_DECLS for private_proto.h.
+	[r436]
+		Add forgotten part of rev435.
+	[r435]
+		Add unit test framework for compressed RTF decoding.
+		
+		Refactor lzfu.c to improve testability.
+2008-04-19
+    jkerihuel
+	[r434]
+		Fix openchangeclient --mailbox --pf with wasn't launched anymore due
+		to some incorrect sanity check tests.
+	[r433]
+		- Remove deprecated fuzzer_msgstore torture test
+		- replace mapi_flags with logon_id in EcDoRpc_MAPI_REQ
+2008-04-16
+    bradh
+	[r432]
+		A couple of minor fixes to make it read better.
+    jelmer
+	[r431]
+		properly clean up sofiles
+	[r430]
+		Import exchange nagios check script by Bill Edmunds.
+	[r429]
+		Add support for creating libocpf soname symlink.
+	[r428]
+		Use standard include for uint64_t definition.
+	[r427]
+		Cleanup talloc and tdb before building samba4.
+2008-04-14
+    jkerihuel
+	[r426]
+		Check for ocpf_set_Recipients retval (MAPI_E_NOT_FOUND)
+	[r425]
+		- Reset ocpf to NULL after release so the ocpf_init/release couple can be called more than once.
+		- Sanity check on recipient, avoid parsing if no recipient is set. Return MAPI_E_NOT_FOUND instead.
+	[r424]
+		Add reference to the ocpf lib within the pc file.
+2008-04-09
+    jelmer
+	[r423]
+		Remove duplicate SWIG instructions (already covered by stdint.i).
+	[r422]
+		Ignore files created by swig.
+	[r421]
+		Use config.mk in swig/perl/Makefile.
+	[r420]
+		Allow sambaprefix and prefix to be different. Allow building with unknown 
+		Samba git revisions (will still warn though).
+	[r419]
+		Add --with-samba argument to configure so samba and openchange can be installed in different directories.
+2008-04-08
+    jkerihuel
+	[r418]
+		Add domain to the mapiprofile dump output.
+	[r417]
+		Fix OpenMessage IDL and GetRecipientTable fetched data
+		
+		-This line, and those below, will be ignored--
+		
+		_M   trunk
+		M    trunk/exchange.idl
+		M    trunk/libmapi/IStoreFolder.c
+		M    trunk/libmapi/emsmdb.c
+		M    trunk/libmapi/IMessage.c
+2008-04-07
+    jelmer
+	[r416]
+		Fix typo, change samba-config -> samba-hostconfig.
+2008-04-06
+    jkerihuel
+	[r415]
+		- Add openchangepfadmin to make install
+		- Add openchangemapidump and locale_codepage to make clean
+2008-04-05
+    jelmer
+	[r413]
+		Merge the samba4-latest branch.
+2008-04-03
+    jkerihuel
+	[r408]
+		Revert so version number to 0.7
+	[r407]
+		Fix Perl bindings: update mapidump_message
+	[r405]
+		** Start libmapi-0.8 ROMULUS development **
+	[r402]
+		Add ChangeLog and apidocs to the releases
+	[r400]
+		- Delete unmaintained regression suite
+		- Fix typo error in torture-clean rule
+	[r399]
+		Add modified release script originally from abartlett/samba4
+	[r398]
+		- Check for specific Samba4 git revision in configure.ac
+		- Prefix locale functions with lcid and make them _PUBLIC_
+    bradh
+	[r406]
+		API documentation update.
+    jelmer
+	[r403]
+		Fix some typos.
+2008-04-02
+    jkerihuel
+	[r397]
+		Add installation script for samba4
+	[r396]
+		- Apply the nspi pointer patch - make openchange works with
+		samba4-alpha3 git 41309dc
+		
+		- update howto.txt
+    bradh
+	[r390]
+		Move the top level API documentation to an "overview"
+		section and add a redirect to that overview.
+		
+		This keeps the doxygen output more nicely separated for
+		packaging.
+		
+		Also, generate the man pages where the install expects
+		to find them.
+2008-04-01
+    jkerihuel
+	[r388]
+		- Fix strsep bug in openchangeclient
+		- Add RECIPIENT support to libocpf
+	[r383]
+		- escape/unescape strings support added
+		- PT_MV_STRING8 type added to OCPF write API
+2008-03-31
+    jkerihuel
+	[r382]
+		- return MAPI_E_NOT_FOUND if NspiGetMatches doesn't return any results
+		  (based upon patch from lofi at mountproc.org)
+		- makes the workstation parameter of mapiprofile optional (use
+		  gethostname if not defined by the user on command line)
+	[r381]
+		- Fix an allocation memory problem in cast_SPropValue
+		- update svn:ignore proplist
+2008-03-30
+    jkerihuel
+	[r380]
+		Update the documentation build so it keeps generating an embedded
+		website in with apidocs/html as root directory.
+	[r378]
+		- Add support for PT_UNICODE and PT_SHORT to libocpf
+		- Initial implementation of the libocpf write API
+		- Update libocpf documentation
+		- add --ocpf-dump option in openchangeclient
+		- Fix realdistclean rules for server
+		- add cast_SPropValue function to libmapi/property.c which cast
+		  mapi_SPropValue to SPropValue
+    bradh
+	[r379]
+		Split API documentation into two separate sections - one
+		for libmapi and one for libocpf.
+		
+		Also add in a top level intro page.
+2008-03-27
+    jkerihuel
+	[r376]
+		New build system which gathers a list of things that can be built with
+		the libraries/utilities the user has installed and build that when
+		"make all" is run.
+2008-03-26
+    jkerihuel
+	[r375]
+		Add missing allocation for OLEGUID
+	[r373]
+		--ocpf-syntax doesn't require MAPI to be initialized. Furthermore
+		  makes ocpf-syntax "exclusive" (quit after performing the operation).
+    bradh
+	[r372]
+		r371 was bad. What was I thinking with that nonsense!
+		
+		Revert to something sane.
+	[r371]
+		Make the ./bin/ directory if it doesn't exist.
+		
+		This should resolve ticket #33.
+2008-03-23
+    bradh
+	[r370]
+		Improve language handling when creating profiles.
+		
+		You can now get a list of valid languages and use either
+		the language code ID or the language name to specify what
+		language later versions of Exchange should reply with.
+	[r369]
+		Typo fix - duplicate ; at the end of the structure.
+	[r368]
+		Match format to unsigned int argument.
+	[r367]
+		Make the format specifier match the unsigned argument.
+2008-03-22
+    jkerihuel
+	[r366]
+		propset svn:ignore update
+	[r365]
+		Update propset svn:ignore on doc/examples and libocpf targets
+	[r364]
+		- Fix ticket #29: http://trac.openchange.org/ticket/29
+		
+		- use access(2) to see if the database already exists
+		- test if the profile already exists prior trying to add it
+		- add descriptive error messages
+		- catch CTRL-C signal and run a profile deletion routine
+    bradh
+	[r363]
+		Update API documentation for ocpf_nproperty_add().
+	[r362]
+		Typo fix.
+2008-03-16
+    jkerihuel
+	[r361]
+		Fix mapidump_message call parameters
+2008-03-13
+    jkerihuel
+	[r360]
+		Add fid/mid parameters to mapidump_message and changed
+		openchangeclient_fetchitems to reflect these changes.
+	[r359]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+		updates the OCPF doxygen file.
+	[r358]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+		adds the doc/examples into the build system and enables make examples.
+	[r357]
+		Patch From Brad Hards, <bradh at frogmouth.net>:
+		API documentation update and minor fix for the error value change.
+2008-03-09
+    jelmer
+	[r355]
+		Update bzr ignores.
+2008-03-06
+    jkerihuel
+	[r354]
+		- Add PT_BINARY property support to OCP
+		- Add stream support to OCPF for large PT_BINARY blobs.
+		- Fix a bug which prevented from having no/empty PROPERTY or NPROPERTY
+		  sections.
+2008-03-05
+    jkerihuel
+	[r353]
+		- Prevent from assigning a value which type doesn't match with
+		  the property one.
+		- Add missing substitution variable support for some named properties
+		  declaration
+		- Improve sample_appointment.ocpf example
+		- Add PT_MV_STRING8 keyword to the list of supported property type
+		  identifiers.
+2008-03-04
+    jkerihuel
+	[r352]
+		Improve OCPF PT_MV_STRING8 support.
+	[r351]
+		- Initial revision for libocpf and its documentation
+		- YACC support added to the build system
+		- custom lid and string support in mapi_nameid
+		- lookup functions added for OOM, lid and string
+		- OCPF commands added to openchangeclient (ocpf-file, ocpf-syntax,
+		  ocpf-sender)
+		- PR_FID displayed in openchangeclient --mailbox
+		- PT_MV_STRING8 support added to cast_mapi_SPropValue
+2008-03-02
+    jkerihuel
+	[r350]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+			updates code to build with current API
+	[r349]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+			little update for some API dox
+2008-02-21
+    jkerihuel
+	[r348]
+		- Add --update option to openchangeclient and allow users to modify
+		  existing messages (calendar, task, contact, note)
+		- Add --delete option to openchangeclient and allow users to delete
+		  existing messages (calendar, task, contact, note)
+		- Add some folder/message unique ID to mapidump outputs and send*
+		  openchangeclient functions.
+		- Fix a bug in set_SPropValue: add sanity check on unicode
+		  string. Thanks to Suman Manjunath for this patch.
+		- Fix mapidump_task function and identifiers of named properties used.
+2008-02-19
+    jkerihuel
+	[r347]
+		Fix missing sanity check on priority
+	[r346]
+		Fix a bug in openchangeclient when tasks are created without body
+	[r345]
+		private flag added to openchangeclient appointments
+	[r344]
+		Fix folder IDs problem for Exchange 2007 SP1
+2008-02-09
+    jkerihuel
+	[r343]
+		Fix names IDL against Samba4 4.0.0alpha3-GIT-41309dc
+2008-01-24
+    jkerihuel
+	[r342]
+		- Fix a bug in IStoreFolder.c:OpenMessage which was also affecting
+		  GetRecipientTable. We were extending SPropTagArray prior calling
+		  emsmdb_get_SRow. This was causing ndr_pull_error in OpenMessage_repl
+		  and erroneous data to be inserted in the SRow.
+		
+		- Fix libmapi/socket/interface.c:
+		     - Use the latest version from Samba4 which removes reference to
+		       global_loadparm.
+		     - Moves struct interface declaration to netif.h
+		     - Report changes to emsmdb.c notification functions.
+		
+		- Change GetGALTable prototype to match general libmapi policy. Remove
+		  the usage of bool and replace it with uint8_t. Possible values added
+		  to mapidefs.h
+2008-01-22
+    jkerihuel
+	[r341]
+		- Improve NspiQueryRows IDL and implementation
+		- Add GetGALTable implementation: fetch all the Global Address List
+		  recipients
+		- Add --userlist option to openchangeclient
+		- Add a convenient and basic dumping function for Global Address List
+		  recipients.
+	[r340]
+		- Improve OpenMessage reply IDL
+		- Fetch mapi recipients from OpenMessage reply
+		- Add GetRecipientTable convenient function
+		- Add OPENCHANGE-MAPI-RECIPIENT torture test to test
+		  GetRecipientTable implementation.
+		- Add convenient SPropTagArray_add function
+		- Add internal emsmdb_get_SRow routine
+2008-01-21
+    jkerihuel
+	[r339]
+		Patch from Suman Manjunath <msuman at novell.com>:
+		
+		- Adds named-properties which define recurrence patterns for
+		  appointment and task. 
+		- Adds named properties for appointment timezone
+	[r338]
+		- Fix the SNotRestriction IDL and write custom push,pull,print
+		  functions
+		- Add 2 new MAPI calls to the IDL: 
+		  * GetSearchCriteria,
+		  * SetSearchCriteria
+		- add sample {Get,Set}SearchCriteria torture test
+		- add convenient mapi_id_array implementation
+		- add GetDefaultFolder support for CommonView and Finder folders
+2008-01-20
+    jelmer
+	[r337]
+		Make sure directory exists.
+2008-01-18
+    jkerihuel
+	[r336]
+		- Fix tiny 'nail down samba4 version' bug
+		- update the minimal Samba4 required version
+	[r335]
+		- Add FindRow call to the IDL
+		- Improve mapi_Restriction support
+		- Remove deprecated ndr_print_QueryRows function
+		- Add a print function for fuzzyLevel
+		- Add preliminary FindRow implementation test to MAPI-RESTRICTIONS
+		  torture test
+		- Add couple of new MAPI tags to mapi-properties
+		- change initial bookmark index to 3
+2008-01-16
+    jkerihuel
+	[r334]
+		- Add 2 new MAPI calls to the IDL and mapitest:
+		  * SetReceiveFolder
+		  * GetReceiveFolderTable
+		
+		- Fix a bug in the SortTable test when no messages are returned by
+		  QueryRows
+	[r333]
+		- Add SeekRowApprox to the IDL and mapitest
+		- Fix some doxygen typo
+	[r332]
+		- New calls added to the IDL, torture suite and mapitest:
+		    * CreateBookmark
+		    * SeekRowBookmark
+		- Internal mapi_object_bookmark_t implementation added to
+		  mapi_object_table_t
+		- SBinary_short default ndr_print function changed to custom
+2008-01-14
+    jkerihuel
+	[r331]
+		Temporary fixes unexpected segfault in SortTable test. Emails sent
+		during the Submit test have sometimes not yet been dispatched when the
+		SortTable test begins. This fix adds a sleep(1) and an arbitrary
+		number of attempts (5).
+	[r330]
+		Add 2 new MAPI calls to the IDL and libmapi:
+		    * AddressTypes
+		    * SortTable
+		
+		Tests for SortTable added to mapitest and the torture suite
+		Test  for AddressTypes added to mapitest.
+2008-01-13
+    jkerihuel
+	[r329]
+		Fix perl bindings and fetchmail test
+	[r328]
+		2 new MAPI call added to the IDL and mapitest: 
+		  * GetMessageStatus
+		  * SetMessageStatus
+2008-01-11
+    jkerihuel
+	[r327]
+		- Add DeleteAttach MAPI call
+		- Add new mapi unit tests:
+		  * QueryColumns
+		  * CreateAttach
+		  * SaveChanges
+		  * GetAttachmentTable
+		  * DeleteAttach
+		- Update mapitest README
+		- Add some convenient functions to mapitest_common.c
+2008-01-10
+    jkerihuel
+	[r326]
+		Add a preliminary draft of the mapitest standalone MAPI test suite.
+2008-01-05
+    jkerihuel
+	[r324]
+		Add missing files
+	[r323]
+		- Fix the build with the latest Samba4 version.
+		
+		- Add a basic libmapi/version.h auto-generated 
+		  file (based on Samba4 one)
+		- Remove some warnings when compiling the utf8 
+		  lexer
+		- Add a emsmdb_info structure to fetch some 
+		  information from the Exchange server
+		
+		WARNING: Please note that EMSABP is definitely broken and 
+		         requires a review and update.
+    jelmer
+	[r325]
+		DESTDIR should never get into any source files, that would defeat its purpose.
+2008-01-04
+    jkerihuel
+	[r322]
+		Fix the torture suite.
+2007-12-28
+    jelmer
+	[r321]
+		provide extra required argument.
+	[r320]
+		Store a loadparm context in the global mapi context.
+	[r319]
+		Deal with samba version.h's that don't contain the Subversion revision.
+2007-12-15
+    jelmer
+	[r318]
+		Use SWIG-provided typemaps for stdint.
+2007-11-29
+    ali
+	[r317]
+		Fix Content-Type field in exchange2mbox
+		Reported by Yuriy Filatov <yuriy.filatov at gmail.com>
+2007-11-28
+    jkerihuel
+	[r316]
+		- Improve the CreateMessage IDL
+		- Add new parameters to IMAPIFolder CreateMessage libmapi function
+		- Add --mkdir --rmdir options to openchangeclient
+		- Update the CreateFolder API and openchangeclient documentation
+		- Fix CreateFolder calls in openchange tools and torture suite
+		- Fix gendb_search warning
+2007-11-25
+    jkerihuel
+	[r315]
+		Add new PSETID_Address named properties 
+	[r314]
+		Fix a few code convention typos 
+		
+		Patch from Suman Manjunath <msuman at novell.com> applied:
+		converts a 'struct timeval' to 'NTTIME'.
+		minor extension of 'set_SPropValue_proptag', used while setting PT_SYSTIME properties.
+2007-11-21
+    jkerihuel
+	[r313]
+		update Samba4 first revision to 26100
+    jelmer
+	[r312]
+		Cope with ndr updates.
+2007-11-12
+    jkerihuel
+	[r311]
+		Patch from Brad Hards: Fix possible Heap overflow in lzfu code
+2007-11-07
+    jkerihuel
+	[r310]
+		Fix profile creation in a clustered Exchange 2007 environment.
+2007-11-02
+    jkerihuel
+	[r309]
+		Fix QueryColumns req size.
+2007-11-01
+    jkerihuel
+	[r308]
+		** Start libmapi-0.7 PHASER development **
+		
+		add --dump-data option to mapiprofile for debugging purpose
+2007-10-31
+    jkerihuel
+	[r306]
+		openchangepfadmin (1) man page added
+	[r305]
+		Store messageID in the object when SaveChangesMessage is called
+	[r304]
+		Nail down Samba4 version for libmapi-0.6
+2007-10-30
+    jkerihuel
+	[r303]
+		- Add PR_MSG_EDITOR_FORMAT property to the sendmail operation
+		- Fix body dump bug when PR_MSG_EDITOR_FORMAT property is missing (default set to PLAINTEXT)
+		- Continue to process the mailbox when a problem is encountered with mesage contents (not attachment)
+		- Fix a typo bug in openchangeclient body help string
+	[r302]
+		Update doxygen section
+2007-10-29
+    jkerihuel
+	[r301]
+		- Add doxygen man (3) pages to installman and uninstallman rules
+		- do not run doxygen if apidocs already exists
+2007-10-28
+    jkerihuel
+	[r300]
+		Move documentation to doxygen 
+2007-10-25
+    jkerihuel
+	[r299]
+		Add convenient date related functions for implementors:
+		returns a timeval struct matching a PT_SYSTIME property
+		for improved date manipulation in 3rd party softwares
+2007-10-24
+    jkerihuel
+	[r298]
+		Fix build to work with latest Samba4 revision (4.0.0alpha2-SVN-build-25722)
+	[r297]
+		Fix make realdistclean when swig perl is enabled
+	[r296]
+		Fix swig perl bindins compilation: move *.o to *.po
+	[r295]
+		use talloc_memdup to copy const data in the body DATA_BLOB
+		Should only provide valid pointer to talloc_free 
+2007-10-23
+    jkerihuel
+	[r294]
+		Fix the DeleteMessages [out] IDL.
+		
+		The remaining bytes were not part of DeleteMessages but
+		MAPI notification (0x2a)
+2007-10-22
+    jkerihuel
+	[r293]
+		- Add RTF support in exchange2mbox
+		- Use openchange-tools public functions
+		- Replace GetPropsAll calls with GetProps
+	[r292]
+		- fetchmail: 
+			* Use GetProps rather than GetPropsAll for message dump
+			* Rely on PR_MSG_EDITOR_FORMAT to select the type of body
+			* Open a stream for PR_BODY and PR_HTML if the size exceeds max property size
+		
+		-This line, and those below, will be ignored--
+		
+		M    trunk/Makefile.in
+		A    trunk/utils/openchange-tools.c
+		M    trunk/utils/openchangeclient.c
+		M    trunk/utils/openchange-tools.h
+		M    trunk/utils/openchangeclient.h
+		M    trunk/libmapi/mapidefs.h
+2007-10-20
+    jelmer
+	[r291]
+		Fix ignores.
+2007-10-19
+    ali
+	[r290]
+		Remove useless svn:ignore
+    jkerihuel
+	[r289]
+		Add WrapCompressedRTFStream function for PR_RTF_COMPRESSED content.
+		
+		Original lzfu decompress routine fetched from libpst-0.5.2
+	[r288]
+		make enum MAPISTATUS variables naming uniform in libmapi
+2007-10-16
+    jkerihuel
+	[r287]
+		Add PT_CLSID case to get_SPropValue_data
+	[r286]
+		Add/Fix pull property support for PT_UNICODE and PT_CLSID (used by GetProps)
+	[r285]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+		Fix compilation for x86_64 platforms.
+2007-10-14
+    ali
+	[r284]
+		More svn:ignore updates
+	[r283]
+		Update of svn:ignore
+2007-10-10
+    jkerihuel
+	[r282]
+		added the IDL license
+	[r281]
+		Convert OpenChange to GPLv3
+	[r280]
+		- Add .po files to make clean 
+		- Fix a couple of warnings in the utf8 conversion lexer 
+		- Prefer long filenames to truncated one for attachments in openchangeclient
+2007-10-09
+    jkerihuel
+	[r279]
+		Prevent exchange2mbox from segfault when PR_MESSAGE_DELIVERY_DATE is unset
+	[r278]
+		Add PT_CLSID and PT_MV_CLSID support to the IDL
+	[r274]
+		- Add new named properties
+		- Convenient function for MNID_STRING props lookup added
+    jelmer
+	[r277]
+		Make .po a recognized suffix.
+	[r276]
+		Fix compile error.
+	[r275]
+		Use -fPIC for library objects.
+2007-10-08
+    jkerihuel
+	[r273]
+		- Rename GetAllNamesFromIDs to QueryNamesFromIDs (better naming)
+		- fix SPropValue_CTR boolean to uint8_t in the IDL and emsmdb.c
+		
+		- add mapi_nameid convenient interface and headers
+		- mapi-named-properties populated, parser added to mparse.pl, file
+		  added to the build system
+		
+		- remove any incorrect reference to named properties in openchange
+		  tree
+		
+		- remove deprecated libmapi/mapi.h file
+		- remove unused ulFlag parameter from IProfAdmin functions
+		- remove unused memory context from libmapi/x500.c
+		
+		- support sendnote operation in openchangeclient
+		- optimize check/list oc_element functions in openchangeclient
+		
+		- update swig interface
+2007-10-05
+    jkerihuel
+	[r272]
+		- New MAPI calls: Named properties support
+		      	 * GetNamesFromIDs
+		  	 * GetIDsFromNames
+		  	 * GetAllNamesFromIDs
+		
+		- Modified MAPI calls:
+		  	 * OpenMessage
+			 * SaveChanges
+		These calls now have more granularity in libmapi with flags support
+		
+		- sample mapi-named-properties file introduced in libmapi/conf
+		
+		- Torture test suite:
+			* suite temporary fixed (import torture_rpc_* functions from
+		          Samba4)
+			* torture_namedprops test added
+		
+		- SWIG Perl bindings fixed according to changes described above
+		- minor improvements in libmapi/mapidump.c
+2007-10-02
+    jkerihuel
+	[r271]
+		- Decrease MAX_READ_SIZE to 0x1000
+		- Clean-up Read/WritreStream related code
+		- add dump-data option to openchangepfadmin (debugging purpose)
+2007-10-01
+    jkerihuel
+	[r270]
+		Fix build: 
+			- remove reference to core/nterr.h
+			- add global_loadparm reference where missing
+			- add reference to core/error.h where needed
+    jelmer
+	[r269]
+		Improve output during build.
+	[r268]
+		Fix lp_load().
+	[r267]
+		Pass loadparm contexts, should fix the build with newer Samba revisions.
+2007-09-28
+    jkerihuel
+	[r266]
+		- WriteStream API changed: now returns the number of bytes written
+		- WriteStream man page updated
+		- 16 bytes extra-data bug fixed when sending attachments in openchangeclient
+		- Set open mode to 0600 when attachments are stored on the filesystem
+		 
+2007-09-19
+    jkerihuel
+	[r265]
+		Fix preliminary Perl bindings so it works with Samba4 alpha2
+		and latest libmapi revision.
+	[r264]
+		Patch from Andrew Gaylard <ag at computer.org>:
+		
+		- When calling openchangeclient with the --dump-data switch, it will
+		dump core, since the global_mapi_ctx pointer isn't initialised yet.
+		The fix is to wait until it's set before accessing it.
+	[r263]
+		Patch from Andrew Gaylard <ag at computer.org>:
+		- Leaving any blank lines before .TH directives appears to cause a blank page
+		to be output when converting man pages to DVI files (which is a step to converting
+		them to PDF). The following patch remove the blank line above the .TH in each man page file. 
+		
+		- mapiprofile doesn't understand the -A switch, as mentioned in it's man page.
+		It should be -I.
+2007-09-13
+    jkerihuel
+	[r262]
+		- Add objectClass to the object: container, message or attachment
+		- Rename content to message in openchangebackup functions
+		- add objectClass parameter to ocb_record_init
+2007-09-12
+    jkerihuel
+	[r261]
+		- Move debug options to their correct location (after MAPIInitialize)
+		- Improve code related to LDB transactions
+		- Add convenient error checking macros
+2007-09-11
+    jkerihuel
+	[r260]
+		- Add preliminary openchangemapidump draft
+		- Fix lp_parm_* 1st parameter in the torture suite
+		- New functions in property.c for MAPI data retrieval
+2007-09-09
+    jelmer
+	[r259]
+		Use configure definition for mandir.
+2007-09-08
+    dan
+	[r258]
+		Activate debugs this time
+	[r257]
+		Replaced remaining gotos with MAPI_RETVAL_IF so errno is set correctly
+	[r256]
+		MAPI_RETVAL_IF missing ";" could cause surprises ;-)
+	[r255]
+		Add error check for samr call.
+		set errno with MAPI_RETVAL_IF.
+2007-09-06
+    dan
+	[r254]
+		Make required packaged more clear (LinuxMagazin input)
+2007-09-05
+    jelmer
+	[r253]
+		Remove invalid comment.
+2007-09-04
+    jkerihuel
+	[r252]
+		- Clean-up function prototypes
+		- Dump email when NEWMAIL notification is received
+2007-08-31
+    jelmer
+	[r251]
+		Proper dependencies.
+	[r250]
+		Don't regenerate proto headers unless necessary.
+	[r249]
+		Add 'make check'.
+	[r248]
+		Use install for installing files/directories.
+	[r247]
+		Actually use replacement variable for libmagic.
+2007-08-30
+    jkerihuel
+	[r246]
+		Remove forgotten BOOL
+	[r245]
+		Remove mapi_session pointer in mapi_objects
+		Add public function to IProfAdmin: retrieve default ldif path location outside the OC tree
+2007-08-28
+    jkerihuel
+	[r244]
+		Prevent users from creation of *undeletable* folders in Outlook and
+		perform sanity check on dirclass + display possible values. 
+	[r243]
+		Provides a way to modify Default and Anonymous permissions for a given folder.
+	[r242]
+		Fix errno in getdir function + add sanity check on opt_rmdir
+	[r241]
+		- Fix a memory related bug in mapiadmin_add_user
+		- Add latest howto.txt modifications from Dan
+	[r240]
+		- Fix bug in *UserPermission function: return when user is not found
+		- Add sanity checks to mapi_object API functions
+		- mapi_object_release reset errno to 0: need to release object
+		after displaying the potential error message.
+	[r239]
+		Fix a mapidump_appointment bug
+		Add PF folder support to fetch-items operation
+2007-08-27
+    jkerihuel
+	[r238]
+		openchangeclient now support send/read/delete operation on custom PF directories.
+	[r233]
+		- Add libmapiadmin library draft: Add/Remove Exchange user
+		- openchangepfadmin tool added: Public Folders management
+		- Add Sanity check to CreateFolder
+    jelmer
+	[r237]
+		Update ignore list.
+	[r236]
+		Fix last references to BOOL, True and False.
+	[r235]
+		Fix more references to BOOL, False and True.
+	[r234]
+		Use standard type and values for booleans since Samba no longer exports 
+		BOOL, True and False.
+2007-08-21
+    jkerihuel
+	[r232]
+		- Add OpenPublicFolder function to libmapi, Open Public Folder store
+		- change torture suite API to match latest Samba4 pidl changes
+		- utf8_convert regexp improved
+		- minor changes: printf to DEBUG
+		- howto.txt patch from Dan included
+		- Samba4 torture code related to user account creation included in the
+		  torture suite.
+2007-08-06
+    jkerihuel
+	[r231]
+		Fix segmentation fault when running update prior populating the database.
+2007-07-31
+    jkerihuel
+	[r230]
+		Remove obsolete file from the torture suite 
+	[r229]
+		- Add Exchange Administration test to the torture suite: Create Exchange user
+	[r228]
+		Dan update on howto.txt
+2007-07-10
+    jkerihuel
+	[r227]
+		- Add Exchange ACLs support to MAPI library
+		- Add 2 new MAPI opnum: GetTable and ModifyTable
+		- Improve mapidump functions
+2007-07-04
+    jkerihuel
+	[r226]
+		- Improve aclocal check in autogen.sh
+		- Fix flex binary detection in configure.ac
+2007-06-22
+    jkerihuel
+	[r225]
+		Same player ...
+	[r224]
+		Fix libmapi symlink
+	[r223]
+		Create libmapi.so symlink
+2007-06-21
+    jkerihuel
+	[r222]
+		Fix mandir installation path
+		Add ldconfig intructions to openchange installation documentation
+	[r221]
+		Fix build.
+2007-06-20
+    jkerihuel
+	[r220]
+		RES_AND and RES_OR preliminary implementation.
+2007-06-19
+    jkerihuel
+	[r218]
+		- doc patch from Brad Hards
+		- rename PROFILE_NOPASSWORD to OC_PROFILE_NOPASSWORD
+		- fix a warning in property.c
+2007-06-16
+    jelmer
+	[r210]
+		Add some 'const' (fixes compile warnings).
+	[r209]
+		Use sonames (required for the Debian packages).
+	[r208]
+		Add .bzrignore file.
+	[r207]
+		Update version number and use globally defined version number in libmapi.pc.
+2007-06-15
+    jkerihuel
+	[r205]
+		- Add IDL implementation for restrictions Content, Property,
+		CompareProps, Bitmask, Size, Exist.
+		- Add Restrict MAPI call handling the restrictions above
+		- OPENCHANGE-MAPI-RESTRICTIONS torture test added to the suite.
+		- convenient sendmail function added to mapi_common.c
+		- get property size function for mapi_SPropValue added to property.c
+		
+		test --This line, and those below, will be ignored--
+		
+		M    Makefile.in
+		M    exchange.idl
+		M    torture/openchange.c
+		A    torture/mapi_restrictions.c
+		M    torture/mapi_common.c
+		M    libmapi/property.c
+		M    libmapi/IMAPITable.c
+2007-06-11
+    jkerihuel
+	[r204]
+		Documentation update: Perl bindings installation
+2007-06-10
+    jkerihuel
+	[r203]
+		- Add mapitags and mapicode support to Perl SWIG bindings
+		- SPropTagArray support
+		- SRowSet preliminary support
+		- new constructor/destructor for mapi objects
+2007-06-09
+    jkerihuel
+	[r202]
+		- IProfAdmin patch applied: having password outside of the profile
+		
+		- Perl bindings draft added to the trunk and to the build system:
+		  --enable-swig-perl=yes
+		
+		- datarootdir fixed in libmapi.pc.in
+2007-06-06
+    jkerihuel
+	[r201]
+		- Add CopyMessages IDL and COPYMAIL torture implementation
+		- Fix man page install dir according to latest Samba4 changes
+		- Add datarootdir var to libmapi.pc.in and fix configure warning
+2007-06-01
+    jkerihuel
+	[r199]
+		convenient function which retrieve a value from a SPropValue array
+		given its property tag name, otherwise NULL
+2007-05-31
+    jkerihuel
+	[r198]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+		openchangeclient man page updated
+	[r197]
+		- Add Windows UTF8 to classic UTF8 conversion through a lexer
+		- openchangeclient --mailbox option changed to use it
+		- flex and bison support added to configure.ac
+		- windows_to_utf8 function added: wrapper over yyparse_utf8 routine
+2007-05-29
+    jkerihuel
+	[r196]
+		- features added to openchangeclient:
+			* --send-appointment
+			* --send-contact
+			* --send-task
+			* custom parameters
+		- openchangeclient man page updated
+		- new properties added to mapi-properties
+	[r195]
+		- Add man pages for simple_mapi.c functions:
+		 * GetDefaultFolder
+		 * GetFolderItemsCount
+	[r194]
+		- Remove deprecated functions from IMsgStore.c
+		- Update man pages documentation
+	[r193]
+		Fix install rule in Makefile: add missing headers
+		Move callback retval from uint32_t to int
+	[r192]
+		Fix notification callback retval
+	[r191]
+		- Advise opnum added to the IDL
+		- Parts of the Notify response IDL implementation
+		- Add Notification support to libmapi
+		- Add --notifications option to openchangeclient
+2007-05-28
+    jkerihuel
+	[r190]
+		Patch from Brad Hards <bradh at frogmouth.net>:
+			- PR_BUSINESS_FAX_NUMBER 
+			- improves the information provided on a contact by 
+		  	  mapidump_contact()
+2007-05-25
+    jkerihuel
+	[r189]
+		- Fix the release call in,out
+		- Call Release from mapi_release_object
+		- Add sanity check to OpenMsgStore
+		- clean up parts of the mapi_newmail test
+	[r188]
+		EcDoDisconnect code now sounds to work properly
+		Tested against Exchange 2000 / Exchange 2003
+	[r187]
+		- Fix SpropValue property pull problem when GetProps layout is set
+		- Add a dumpdata boolean to mapi_ctx_t so tools can dump hex data
+		- Add PR_CONTAINER_CLASS fetch to openchangeclient --mailbox
+		- Add debuglevel and dumpdata options support to openchangeclient
+2007-05-24
+    jkerihuel
+	[r186]
+		- Remove useless memory allocation in mapidump.c
+		- Improve mapidump_appointment
+		- Add sample mapidump_note
+		- Add --fetchitems option to openchangeclient:
+		This command offers an easy way to fetch calendar, contacts,
+		tasks, notes and mails from the Exchange server.
+		- Add IPF container class defines to mapidefs.h
+		- Add and Fix property tags
+2007-05-22
+    jkerihuel
+	[r185]
+		- Commit the EcDoRpc max_data patch proposed on the devel list
+		- Clean up folders related functions from the torture suite 
+		(GetDefaultFolder makes this code obsolete)
+2007-05-21
+    jkerihuel
+	[r184]
+		Add the --mailbox option to openchangeclient which recursively
+		lists the full mailbox folder hierarchy
+	[r183]
+		- Add PT_SYSTTIME support to get_SPropValue_data
+		- Add mapidump_SPropValue_date dumping function
+		- Add PT_SYSTIME support to mapidump_SPropValue
+	[r182]
+		- Add multi-valued SBinary_short support to mapi_SPropValue_CTR in the
+		IDL
+		
+		- Add GetDefaultFolder implementation to simple_mapi.c. This function
+		provides a convenient way to retrieve default folders ID. const
+		olFolder values are stored in libmapi/mapidefs.h
+		
+		- Modify the torture test suite to reflect these changes.
+		
+		- OpenMsgStore now decodes all the fid returned in the response
+		
+		- fix a bug size in libmapi/property.c
+2007-05-18
+    jkerihuel
+	[r181]
+		- Fix SMTP recipient in libmapi
+		- Add SMTP recipient support to openchangeclient
+		and the torture test suite
+		- Fix a bug in SRow_addprop
+2007-05-17
+    jkerihuel
+	[r180]
+		- OpenMessage IDL changed: we have a permission field.
+		It is now set by default to 0x3 (read/write) until we 
+		change OpenMessage prototype.
+		
+		- Add a sanity check to MAPIInitialize when no profdb
+		is specified
+2007-05-15
+    jkerihuel
+	[r179]
+		Remove remaining MAPISTATUS and replace them with enum MAPISTATUS
+	[r178]
+		- SetReadFlags IDL and implementation added to libmapi
+		- Warning fixed in emsabp.h
+	[r177]
+		Fix a bug in openchangeclient when attachments are using
+		PR_ATTACH_LONG_FILENAME rather than PR_ATTACH_FILENAME to store
+		attachment filename.
+	[r176]
+		Patch supplied by Brad Hards <bradh at frogmouth.net> which renames 
+		private structure member to private_data for C++ compatibility.
+	[r175]
+		Add libmapi/simple_mapi.c designed to hold convenient 
+		functions for application development.
+		
+		- GetFolderItemsCount added which returns the number of
+		total and unread messages for a given folder.
+2007-05-14
+    jkerihuel
+	[r174]
+		- Fix a body openchangeclient bug which now prevent openchangeclient
+		from segfault when no body is specified.
+		- Add GetDefaultProfile call to exchange2mbox for the default
+		operation.
+		- Improve fuzzer_msgtore output
+2007-05-13
+    jkerihuel
+	[r173]
+		Add a fuzzer torture test on OpenMsgStore which
+		test all the possible max_data value.
+		
+		Should help to understand if libmapi fails because
+		of max_data or not. 
+2007-05-12
+    jkerihuel
+	[r171]
+		exchange2mbox improved:
+		- tdb dependency removed
+		- message-id are now stored in the profile database
+		- it now mirrors deletion operation from the mbox file back to the
+		Exchange server.
+		- man page updated to reflect these changes
+	[r170]
+		- GetProfileAttr function prototype modified. It now returns the
+		results count for the given attribute and store values in a string
+		array.
+		- GetProfileAttr man page updated to reflect these changes
+		- Fix mapiprofile attribute search command
+		- migrate from open/write calls to stream ones in exchange2mbox
+    texane
+	[r172]
+		newmail torture + notifications implementation
+		
+		-- texane
+2007-05-11
+    jkerihuel
+	[r169]
+		Fix the SambaXP live demo segfault: When an ambiguous recipient is
+		specified, it now skips the name properly and maintain a correct
+		SRowSet.
+	[r168]
+		- Fix a bug when storing attachments into mbox
+		- Add default path support to exchange2mbox
+2007-05-10
+    jkerihuel
+	[r167]
+		- Update libmapi version according to the roadmap
+		- Fix nspi_resolvenames to use default profile database and profile
+2007-05-09
+    jkerihuel
+	[r166]
+		- Add default profile database and profile support in the torture suite.
+		- Fix a bug in mapidump_task
+2007-05-08
+    jkerihuel
+	[r165]
+		- Change MAPILogonEx to MAPILogonProvider and avoid potential
+		emsmdb endpoint related problem
+		- add sanity check on global session pointer
+2007-05-06
+    ali
+	[r164]
+		Merged MAILOOK-branch changes r64:163 into the trunk.
+2007-03-04
+    jkerihuel
+	[r79]
+		Remove ChangeLog, use svn log instead ;p
+2007-02-13
+    jkerihuel
+	[r63]
+		- libmapi includes moved from libmapi/include to libmapi
+		- Remove arguments from prototype definitions generation in mkproto.pl
+		- __BEGIN_DECLS __END_DECLS support in header files
+		- united libmapi/libmapi.h header file
+		- openchange.h header removed
+		- PIDL generated files moved to gen_ndr
+		- compilation rule for libmapi header installation added
+		- useless torture tests removed
+		
+		jkerihuel.
+2007-02-12
+    jkerihuel
+	[r62]
+		Replace OpenProperty and ReadAttach calls with OpenStream and ReadStream call
+		Add GetAttachmentTable call
+		
+		jkerihuel.
+2007-02-09
+    jkerihuel
+	[r58]
+		Remove -Werror CFLAGS until I figure out how to fix
+		our problem definitively.
+		
+		Remove static from dcesrv_exchange.c functions definition
+		
+		jkerihuel.
+    texane
+	[r61]
+		. reimplement GetProps
+		. retrieve attachment size
+		. modify fetchmail and fetchattach torture
+		
+		-- texane
+	[r60]
+		
+		. add GetPropList to exchange.idl
+		. add GetPropList implementation to IMAPIProp.c
+		-- texane
+	[r59]
+		- Add fetchattach torture; Attachment size is not yet
+		defined and 42 is used.
+		- add 3 new EcDoRpc opnums:
+			- OpenAttach
+			- ReadAttach
+			- OpenProperty
+		
+		-- texane
+2007-02-08
+    jkerihuel
+	[r57]
+		Forgot to add IMAPISession.c
+		
+		jkerihuel.
+2007-02-07
+    jkerihuel
+	[r56]
+		Remove spurious warnings at compile time and
+		add -Werror -Wstrict-prototypes to CC.
+		
+		jkerihuel.
+	[r55]
+		Dispatch libmapi functions into filenames matching
+		the MAPI interface they belong to.
+		
+		jkerihuel.
+	[r54]
+		Fix the attach issue by value and add torture test to
+		the openchange torture suite.
+		
+		jkerihuel.
+    texane
+	[r53]
+		attachment torture test implementation
+		
+		-- texane
+2007-02-06
+    jkerihuel
+	[r52]
+		Add a null element at the end of MAPI_REQ array
+		so we can exit from the loop in ndr_print_mapi_request
+		
+		jkerihuel.
+	[r49]
+		- Add the DeleteMessages IDL
+		- New torture tests added:
+			* OPENCHANGE-MAPI-SENDMAIL
+			* OPENCHANGE-MAPI-DELETEMAIL
+		
+		These are experimental implementation
+		
+		jkerihuel.
+    texane
+	[r51]
+		subject option for delete message torture test
+		
+		-- texane
+	[r50]
+		added (recipients == null) check
+		added default body
+		added default subject
+		-- texane
+2007-02-03
+    jkerihuel
+	[r48]
+		Add NspiResolveNames and the associated torture test.
+		
+		jkerihuel.
+2007-02-01
+    jkerihuel
+	[r47]
+		Fix nspi decoding problem due to the usage of
+		a hyper instead of a dlong.
+		
+		jkerihuel.
+	[r46]
+		- Add a preliminary NspiUpdateStat IDL
+		- Fix the new server code convention naming 
+		(function prefixed with dcesrv_)
+		- Fix a security bug in emsabp provider code
+		
+		jkerihuel.
+	[r45]
+		Fix the allocation memory for the EcDoRpc_{MAPI_REQ,MAPI_REPL} pointer.
+		
+		jkerihuel.
+	[r44]
+		Add SetProps [out] support.
+		
+		Temporary allocation pb fixed in ndr_pull_mapi_response.
+		Final fix in next commit.
+		
+		jkerihuel.
+2007-01-31
+    jkerihuel
+	[r43]
+		Fix the SetProps [in] IDL
+		
+		New mapi call support added:
+		- ModifyRecipients [in,out]
+		- SubmitMessage [in,out]
+		
+		jkerihuel.
+	[r42]
+		Add IDL support for the following mapi calls:
+		
+		[in] CreateMessage
+		[in] SetProps
+		
+		The SetProps IDL is still experimental and the
+		content blob should be decoded more than the current 
+		IDL does.
+		
+		jkerihuel.
+2007-01-30
+    jkerihuel
+	[r41]
+		Fix the align problem in QueryRows reply blob
+		Add some printing output and clean useless DEBUG.
+		
+		jkerihuel.
+2007-01-29
+    jkerihuel
+	[r40]
+		Fix the OpenMessage IDL and add ndr_print support
+		to the MAPI-FETCHMAIL torture test so we can
+		read information.
+		
+		jkerihuel.
+	[r39]
+		Commit of the first experimental but working implementation
+		of the MAPI-FETCHMAIL torture test able to retrieve mails
+		from an Exchange Server.
+		
+		jkerihuel.
+	[r38]
+		- Add a preview implementation of cached data system for multi MAPI calls requests
+		- Add SetColumns and QueryRows calls to mapi.c + mapi_fetchmail torture test
+		- Enhance some MAPI calls IDL
+		- Fix some pull/print functions according to error_code and row_count values
+		
+		jkerihuel.
+2007-01-28
+    jkerihuel
+	[r37]
+		Manual handling of EcDoRpc_MAPI_REPL pull and print function.
+		When a mapi call returns an error_code different from MAPI_E_SUCCESS,
+		we have to stop processing the function IDL since no parameters follow.
+		
+		jkerihuel.
+	[r36]
+		add MAPISTATUS to EcDoRpc_MAPI_REPL
+		add mapi library code for:
+		- OpenFolder
+		- Release
+		- GetContentsTable
+		- GetReceiveFolder
+		
+		add mapi calls described above to MAPI-FETCHMAIL torture test
+		
+		jkerihuel.
+	[r35]
+		add mapi_response to emsmdb_transaction so we can get the results
+		check the mapi call error core in OpenMsgStore
+		
+		jkerihuel.
+	[r34]
+		Add MAPISTATUS field in each mapi calls
+		Add new MAPICODE (MAPI_E_CALL_FAILED)
+		
+		jkerihuel.
+	[r33]
+		Fix the mapi_request push function
+		Add a first approach to the MAPI client side library
+		Add a first approach of the MAPI-FETCHMAIL torture test
+		Fix the smb.conf.example with new fields and remove Samba4 unused ones
+		
+		jkerihuel.
+2007-01-27
+    jkerihuel
+	[r32]
+		Initial mapidump commit
+		OpenMessage IDL fixed
+		
+		jkerihuel.
+2007-01-24
+    jkerihuel
+	[r31]
+		Unused and dummy code removed
+		
+		jkerihuel
+	[r30]
+		- Remove the MAPI decoding TDR layer and associated functions
+		- Add MAPI decoding in exchange.idl at NDR layer
+		- mapi_request / mapi_response pull/print ok
+		- implement subcontext for async response decoding in
+		some EcDoRpc IDLs.
+		- new MAPITAGS added related to Message envelope properties
+		- clean up the code and remove unused files
+		
+		- Add new MAPI opnums and associated IDL:
+			* [in]     Release          (opnum=0x1)
+			* [in,out] OpenFolder       (opnum=0x2)
+			* [in,out] OpenMessage      (opnum=0x3)
+			* [in,out] GetContentsTable (opnum=0x5)
+			* [in,out] GetProps         (opnum=0x7)
+			* [in,out] Secolumns        (opnum=0x12)
+			* [in,out] QueryRows        (opnum=0x15)
+			* [in,out] GetReceiveFolder (opnum=0x27)
+			* [in,out] OpenMsgStore     (opnum=0xFE)
+		
+		** WARNING  **
+		
+		1. Assumption
+		==============
+		For IDL with unknown fields followed the IDL may 
+		change and the mapping of these unknown bytes incorrect. 
+		It's just based on assumptions and results of the different
+		wireshark captures.
+		
+		2. Broken Code
+		==============
+		- The mapi_request / mapi_response pull function
+		- emsmdb torture tests and libmapi/emsmdb.c
+		
+		All this code is currently broken and will be fixed
+		when we start writing the new emsmdb torture suite
+		using the new API.
+		
+		
+		jkerihuel
+2007-01-22
+    jkerihuel
+	[r29]
+		Fix ndr_pull_MAPI_DATA function
+		
+		jkerihuel.
+	[r28]
+		- Add new mapi opnums
+		- Add a first IDL implementation for OpenMsgStore out
+		
+		jkerihuel.
+	[r27]
+		- Enhance the handles id support in MAPI_DATA
+		- Remove unused code
+		
+		EMSMDB encoding/decoding is currently broken.
+		It will be fixed when we start the client side
+		mapi library implementation.
+		
+		jkerihuel.
+2007-01-21
+    jkerihuel
+	[r26]
+		- Change IMAPISession.idl to mapi.idl
+		- enhance mapi content payload decoding (multiple calls supported)
+		- add sub EcDoRpc opnums and IDL for setcolumns (in)
+		
+		jkerihuel
+    pkhun
+	[r25]
+		
+		- memory leak fixed
+		- new function on emsabp provider for entry id generation
+		
+		pkhun
+2006-12-27
+    jkerihuel
+	[r24]
+		Old mapitables code deleted and merge of the samdb
+		code used in openchange (emsabp_result_guid function).
+		
+		The following revision compiles and work fine with
+		Samba4 revision 20341
+		
+		jkerihuel.
+2006-12-17
+    pkhun
+	[r23]
+		
+		Instance keys management changed (we now use struct instance_key and uint32_t instead of an array of 4 uint8_t)
+		
+		pkhun
+2006-12-15
+    jkerihuel
+	[r22]
+		- Fix compilation warnings based on patches provided 
+		by Stefan Huehner <stefan at huehner.org>
+		- Fix the DSO issue for x64 platforms
+		- Add the evolution plugin in the compilation process
+		- remove the mapidump code (obsolete and replaced with ndrdump usage)
+		
+		jkerihuel.
+2006-12-13
+    jkerihuel
+	[r21]
+		evolution plugin moved into client/evolution for
+		a correct and extensible naming convention.
+		
+		EcDoRpc IDL modified:
+		- opnum are now 8 bits
+		- action enum added 
+		- EcDoRpc ndrdump output enhanced
+		
+		IMAPISession IDL modified:
+		- Change OpenMsgStore function name to MAPI_RPC_LOGON
+		for the 0xFE opnum operation.
+		
+		Fix warnings in the code.
+		
+		jkerihuel.
+2006-12-09
+    loic
+	[r20]
+		Openchange-Evolution plugin commit
+		I reorganized openchange evolution plugin source tree.
+		Now we have one directory for the camel-openchange provider, and one for the openchange eplugin.
+		Everything can be found in the oc-evolution directory.
+		This is code a minimalist implementation of the camel provider for evolution.
+		It will make appears an openchange server type in the server list handled by evolution.
+		Still have to fix the ./configure to create a Makefile though.
+2006-12-05
+    jkerihuel
+	[r19]
+		Fix the memory allocation problems in the emsmdb torture test
+2006-12-03
+    jkerihuel
+	[r17]
+		Removed ascstr and directly add it to the IDL
+	[r16]
+		Fix the NspiQueryRows response where strings
+		containing the user email address have to be
+		NULL terminated.
+		
+		The EMSABP provider is working ;-)
+    pkhun
+	[r18]
+		
+		The emsabp provider is now able to return multiple users
+		when searching for part of a username.
+		
+		pkhun
+2006-11-30
+    jkerihuel
+	[r15]
+		Fix the networkAddress binding strings for the
+		Exchange object in the configuration db. The
+		SERVER variable based on exchange:server had
+		been added while we needed the NETBIOSNAME one
+		
+		Fix a segmentation fault in emsabp.c due to an
+		unchecked pointer res->msgs. This was causing
+		smbd to segfault when the supplied legacyExchangeDN
+		sent by the user wasn't present in the database.
+		
+		jkerihuel
+2006-11-27
+    jkerihuel
+	[r14]
+		Remove unused files and directory.
+		Update Makefile.in and remove storedb compilation
+		rules.
+    pkhun
+	[r13]
+		
+		Fixed :
+		- NspiQueryRows
+		- NspiDNToEph
+		- NspiGetProps
+		- provisioning (for the legacyExchangeDN of the server entry)
+2006-11-26
+    jkerihuel
+	[r11]
+		Fix the build and remove dynconfig samba lib
+		dependency.
+		
+		jkerihuel
+    pkhun
+	[r12]
+		Unused ldif files removed + Schemas definitions updated
+		
+		pkhun
+	[r10]
+		Provisionning fixed (old ldif files cleaned)
+		
+		pkhun
+2006-11-22
+    jkerihuel
+	[r9]
+		add tags rules to the Makefile
+		
+		jkerihuel.
+	[r8]
+		add the \\pipe\\protected_storage named pipe
+		to exchange_nsp bindings
+		
+		jkerihuel.
+2006-11-21
+    jkerihuel
+	[r7]
+		Add a dcerpc_server module in charge of the 
+		exchange interfaces registration. When this module
+		is loaded prior the remote endpoint, it let us proxify 
+		the exchange_nsp and exchange_emsmdb ones.
+		
+		Change the exchange_nsp ncacn_np binding string to
+		reflect how Exchange server is currently using it.
+		
+		Conform the IDL with latest pidl requirements and
+		move the MAPI_DATA structure from exchange_nsp to
+		exchange_emsmdb.
+		
+		jkerihuel
+2006-11-14
+    jkerihuel
+	[r6]
+		Create the $prefix/modules/{dcerpc_server,torture}
+		directories.
+		
+		This fix openchange make install rule.
+		
+		jkerihuel.
+	[r5]
+		This commit conforms openchange with the Samba4
+		trunk and fix the autotools checks.
+		
+		I've modified the openchange torture file to
+		match the current smbtorture API and the
+		OPENCHANGE-NSPI-PROFILE test was successful.
+		
+		The NSPI ndrdump suite has fully been tested and
+		works correctly.
+		
+		jkerihuel.
+2006-11-05
+    jkerihuel
+	[r3]
+		This commit fix the build system:
+		- add the -ldynconfig dependency to LDFLAGS
+		- add header checks in configure.ac. We need them
+		for the moment cause Samba4 doesn't install some headers
+		required by openchange core
+		- fix the make install
+		
+		- remove autotools generated files and definitively
+		ignore them with the .svnignore file
+		
+		- keepref keyword removed from exchange_nsp interface
+		
+		jkerihuel.
+    pkhun
+	[r4]
+		+ aclocal.m4 removed from repository
+		+ provisionning fixed
+		
+		pkhun.

Modified: trunk/openchange/Makefile
===================================================================
--- trunk/openchange/Makefile	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/Makefile	2010-02-11 11:16:26 UTC (rev 3288)
@@ -37,7 +37,9 @@
 		$(OC_TORTURE)		\
 		$(OC_SERVER)		\
 		$(SWIGDIRS-ALL)		\
-		$(PYMAPIALL)
+		$(PYMAPIALL)		\
+		$(COVERAGE_INIT)	\
+		$(OPENCHANGE_QT4)
 
 install: 	all 			\
 		installlib 		\
@@ -73,6 +75,7 @@
 	rm -f libmapi++/Doxyfile
 	rm -f mapiproxy/Doxyfile
 	rm -f config.status config.log
+	rm -f config.h
 	rm -f stamp-h1
 	rm -f utils/mapitest/Doxyfile
 	rm -f intltool-extract intltool-merge intltool-update
@@ -94,7 +97,7 @@
 # Suffixes compilation rules
 #################################################################
 
-.SUFFIXES: .c .o .h .po .idl
+.SUFFIXES: .c .o .h .po .idl .cpp
 
 .idl.h:
 	@echo "Generating $@"
@@ -108,7 +111,13 @@
 	@echo "Compiling $< with -fPIC"
 	@$(CC) $(CFLAGS) -fPIC -c $< -o $@
 
+.cpp.o:
+	@echo "Compiling $< with -fPIC"
+	@$(CXX) $(CXXFLAGS) $(QT4_CXXFLAGS) -fPIC -c $< -o $@
 
+.cpp.po:
+	@echo "Compiling $< with -fPIC"
+	@$(CXX) $(CXXFLAGS) -fPIC -c $< -o $@
 
 #################################################################
 # IDL compilation rules
@@ -160,14 +169,14 @@
 
 libmapi-clean::
 	rm -f libmapi/*.o libmapi/*.po
-	rm -f libmapi/tests/*.o, libmapi/tests/*.po
+	rm -f libmapi/*.gcno libmapi/*.gcda libmapi/*.gcov
 	rm -f libmapi/socket/*.o libmapi/socket/*.po
-	rm -f libmapi/util/*.o, libmapi/util/*.po
+	rm -f libmapi/socket/*.gcno libmapi/socket/*.gcda
 	rm -f libmapi/version.h
 ifneq ($(SNAPSHOT), no)
-	rm -f libmapi/utf8_convert.yy.c
 	rm -f libmapi/mapicode.c libmapi/mapicode.h
 	rm -f libmapi/mapitags.c libmapi/mapitags.h
+	rm -f libmapi/codepage_lcid.c
 	rm -f libmapi/mapi_nameid.h libmapi/mapi_nameid_private.h
 	rm -f libmapi/proto.h
 	rm -f libmapi/proto_private.h
@@ -179,6 +188,7 @@
 	rm -f gen_ndr/ndr_property*
 	rm -f gen_ndr/property.h
 	rm -f ndr_mapi.o ndr_mapi.po
+	rm -f ndr_mapi.gcno ndr_mapi.gcda
 	rm -f *~
 	rm -f */*~
 	rm -f */*/*~
@@ -202,13 +212,15 @@
 	$(INSTALL) -d $(DESTDIR)$(libdir)
 	$(INSTALL) -m 0755 libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
 	ln -sf libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapi.$(SHLIBEXT)
+ifeq ($(MANUALLY_CREATE_SYMLINKS), yes)
+	ln -sf libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION)
+endif
 
 libmapi-installheader:
 	@echo "[*] install: libmapi headers"
 	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapi 
 	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapi/socket 
 	$(INSTALL) -d $(DESTDIR)$(includedir)/gen_ndr
-	$(INSTALL) -m 0644 libmapi/dlinklist.h $(DESTDIR)$(includedir)/libmapi/
 	$(INSTALL) -m 0644 libmapi/libmapi.h $(DESTDIR)$(includedir)/libmapi/
 	$(INSTALL) -m 0644 libmapi/proto.h $(DESTDIR)$(includedir)/libmapi/
 	$(INSTALL) -m 0644 libmapi/nspi.h $(DESTDIR)$(includedir)/libmapi/
@@ -272,12 +284,11 @@
 	libmapi/mapitags.po				\
 	libmapi/mapidump.po				\
 	libmapi/mapicode.po 				\
+	libmapi/codepage_lcid.po			\
 	libmapi/mapi_nameid.po				\
 	libmapi/emsmdb.po				\
 	libmapi/nspi.po 				\
 	libmapi/simple_mapi.po				\
-	libmapi/util/lcid.po 				\
-	libmapi/util/codepage.po			\
 	libmapi/freebusy.po				\
 	libmapi/x500.po 				\
 	ndr_mapi.po					\
@@ -285,10 +296,9 @@
 	gen_ndr/ndr_exchange_c.po			\
 	gen_ndr/ndr_property.po				\
 	libmapi/socket/interface.po			\
-	libmapi/socket/netif.po				\
-	libmapi/utf8_convert.yy.po
+	libmapi/socket/netif.po				
 	@echo "Linking $@"
-	@$(CC) $(DSOOPT) -Wl,-soname,libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) -o $@ $^ $(LIBS)
+	@$(CC) $(DSOOPT) $(CFLAGS) $(LDFLAGS) -Wl,-soname,libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) -o $@ $^ $(LIBS)
 
 
 libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION): libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
@@ -297,13 +307,6 @@
 libmapi/version.h: VERSION
 	@./script/mkversion.sh 	VERSION libmapi/version.h $(PACKAGE_VERSION) $(top_builddir)/
 
-libmapi/utf8_convert.yy.c: 	libmapi/utf8_convert.l
-	@echo "Generating $@"
-	@$(FLEX) -Plibmapi_utf8_convert_ -t $< > $@
-
-# Avoid warnings:
-libmapi/utf8_convert.yy.o: CFLAGS=
-
 libmapi/proto.h libmapi/proto_private.h:		\
 	libmapi/nspi.c					\
 	libmapi/emsmdb.c				\
@@ -311,6 +314,7 @@
 	libmapi/simple_mapi.c				\
 	libmapi/mapitags.c				\
 	libmapi/mapicode.c				\
+	libmapi/codepage_lcid.c				\
 	libmapi/mapidump.c				\
 	libmapi/mapi_object.c				\
 	libmapi/mapi_id_array.c				\
@@ -336,8 +340,6 @@
 	libmapi/x500.c 					\
 	libmapi/lzfu.c					\
 	libmapi/utils.c 				\
-	libmapi/util/lcid.c 				\
-	libmapi/util/codepage.c 			\
 	libmapi/socket/interface.c			\
 	libmapi/socket/netif.c		
 	@echo "Generating $@"
@@ -345,10 +347,11 @@
 
 libmapi/emsmdb.c: libmapi/emsmdb.h gen_ndr/ndr_exchange_c.h
 
-libmapi/mapitags.c libmapi/mapicode.c mapitags_enum.h mapicodes_enum.h: \
-	libmapi/conf/mapi-properties 					\
-	libmapi/conf/mapi-codes 					\
-	libmapi/conf/mapi-named-properties 				\
+libmapi/mapitags.c libmapi/mapicode.c libmapi/codepage_lcid.c mapitags_enum.h mapicodes_enum.h: \
+	libmapi/conf/mapi-properties								\
+	libmapi/conf/mapi-codes									\
+	libmapi/conf/mapi-named-properties							\
+	libmapi/conf/codepage-lcid								\
 	libmapi/conf/mparse.pl
 	@./libmapi/conf/build.sh
 
@@ -356,16 +359,44 @@
 # libmapi++ compilation rules
 #################################################################
 
-libmapixx: libmapi libmapixx-tests libmapixx-examples
+LIBMAPIPP_SO_VERSION = 0
 
+libmapixx: libmapi \
+	libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
+	libmapixx-tests \
+	libmapixx-examples
+
+libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION): 	\
+	libmapi++/src/attachment.po 		\
+	libmapi++/src/folder.po 		\
+	libmapi++/src/mapi_exception.po		\
+	libmapi++/src/message.po		\
+	libmapi++/src/object.po			\
+	libmapi++/src/session.po
+	@echo "Linking $@"
+	@$(CXX) $(DSOOPT) $(CXXFLAGS) $(LDFLAGS) -Wl,-soname,libmapipp.$(SHLIBEXT).$(LIBMAPIPP_SO_VERSION) -o $@ $^ $(LIBS)
+
 libmapixx-installpc:
+	@echo "[*] install: libmapi++ pc files"
+	$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+	$(INSTALL) -m 0644 libmapi++.pc $(DESTDIR)$(libdir)/pkgconfig
 
-libmapixx-clean: libmapixx-tests-clean
+libmapixx-distclean:
+	rm -f libmapi++.pc
 
-libmapixx-install: libmapixx-installheader
+libmapixx-uninstallpc:
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapi++.pc
 
-libmapixx-uninstall: libmapixx-uninstallheader
+distclean::libmapixx-distclean
 
+libmapixx-clean: libmapixx-tests-clean libmapixx-libs-clean
+
+clean:: libmapixx-clean
+
+libmapixx-install: libmapixx-installheader libmapixx-installlib libmapixx-installpc
+
+libmapixx-uninstall: libmapixx-uninstallheader libmapixx-uninstalllib libmapixx-uninstallpc
+
 libmapixx-installheader:
 	@echo "[*] install: libmapi++ headers"
 	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapi++
@@ -380,18 +411,33 @@
 	$(INSTALL) -m 0644 libmapi++/profile.h $(DESTDIR)$(includedir)/libmapi++/
 	$(INSTALL) -m 0644 libmapi++/property_container.h $(DESTDIR)$(includedir)/libmapi++/
 	$(INSTALL) -m 0644 libmapi++/session.h $(DESTDIR)$(includedir)/libmapi++/
-	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapi++/impl
-	$(INSTALL) -m 0644 libmapi++/impl/* $(DESTDIR)$(includedir)/libmapi++/impl/
 
+libmapixx-libs-clean:
+	rm -f libmapi++/src/*.po
+	rm -f libmapipp.$(SHLIBEXT)*
+
+libmapixx-installlib:
+	@echo "[*] install: libmapi++ library"
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(INSTALL) -m 0755 libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapipp.$(SHLIBEXT)
+ifeq ($(MANUALLY_CREATE_SYMLINKS), yes)
+	ln -sf libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapipp.$(SHLIBEXT).$(LIBMAPIPP_SO_VERSION)
+endif
+
 libmapixx-uninstallheader:
 	rm -rf $(DESTDIR)$(includedir)/libmapi++
 
+libmapixx-uninstalllib:
+	rm -f $(DESTDIR)$(libdir)/libmapipp.*
 
 libmapixx-tests:	libmapixx-test		\
-			libmapixx-attach
+			libmapixx-attach 	\
+			libmapixx-exception
 
 libmapixx-tests-clean:	libmapixx-test-clean	\
-			libmapixx-attach-clean	
+			libmapixx-attach-clean	\
+			libmapixx-exception-clean 
 
 libmapixx-test: bin/libmapixx-test
 
@@ -402,9 +448,10 @@
 clean:: libmapixx-tests-clean
 
 bin/libmapixx-test:	libmapi++/tests/test.cpp	\
+		libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
 		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking sample application $@"
-	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+	@$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) 
 
 clean:: libmapixx-test-clean
 
@@ -412,16 +459,30 @@
 
 libmapixx-attach-clean:
 	rm -f bin/libmapixx-attach
-	rm -f libmapi++/tests/*.o
+	rm -f libmapi++/tests/*.po
 
-bin/libmapixx-attach: libmapi++/tests/attach_test.cpp	\
-		  libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+bin/libmapixx-attach: libmapi++/tests/attach_test.po	\
+		libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking sample application $@"
 	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
 
 clean:: libmapixx-attach-clean
 
+libmapixx-exception: bin/libmapixx-exception
+ 
+bin/libmapixx-exception: libmapi++/tests/exception_test.cpp \
+		libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking exception test application $@"
+	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
 
+libmapixx-exception-clean:
+	rm -f bin/libmapixx-exception
+	rm -f libmapi++/tests/*.o
+
+clean:: libmapixx-exception-clean
+
 libmapixx-examples: libmapi++/examples/foldertree \
 		  libmapi++/examples/messages
 
@@ -434,14 +495,16 @@
 	rm -f libmapi++/examples/*.o
 
 libmapi++/examples/foldertree: libmapi++/examples/foldertree.cpp	\
-		  libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+		libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking foldertree example application $@"
 	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
 
 clean:: libmapixx-foldertree-clean
 
 libmapi++/examples/messages: libmapi++/examples/messages.cpp	\
-		  libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+		libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION) \
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking messages example application $@"
 	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
 
@@ -466,6 +529,7 @@
 
 libmapiadmin-clean::
 	rm -f libmapiadmin/*.o libmapiadmin/*.po
+	rm -f libmapiadmin/*.gcno libmapiadmin/*.gcda
 ifneq ($(SNAPSHOT), no)
 	rm -f libmapiadmin/proto.h
 	rm -f libmapiadmin/proto_private.h
@@ -490,6 +554,9 @@
 	$(INSTALL) -d $(DESTDIR)$(libdir)
 	$(INSTALL) -m 0755 libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
 	ln -sf libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiadmin.$(SHLIBEXT)
+ifeq ($(MANUALLY_CREATE_SYMLINKS), yes)
+	ln -sf libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiadmin.$(SHLIBEXT).$(LIBMAPI_SO_VERSION)
+endif
 
 libmapiadmin-installheader:
 	@echo "[*] install: libmapiadmin headers"
@@ -511,7 +578,7 @@
 	libmapiadmin/mapiadmin.po 		\
 	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking $@"
-	@$(CC) $(DSOOPT) -Wl,-soname,libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) -o $@ $^ $(LIBS) $(LIBMAPIADMIN_LIBS) 
+	@$(CC) $(DSOOPT) $(LDFLAGS) -Wl,-soname,libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) -o $@ $^ $(LIBS) $(LIBMAPIADMIN_LIBS) 
 
 libmapiadmin/proto.h libmapiadmin/proto_private.h: 	\
 	libmapiadmin/mapiadmin.c 			\
@@ -540,6 +607,7 @@
 
 libocpf-clean::
 	rm -f libocpf/*.o libocpf/*.po
+	rm -f libocpf/*.gcno libocpf/*.gcda
 ifneq ($(SNAPSHOT), no)
 	rm -f libocpf/lex.yy.c
 	rm -f libocpf/ocpf.tab.c libocpf/ocpf.tab.h
@@ -566,6 +634,9 @@
 	$(INSTALL) -d $(DESTDIR)$(libdir)
 	$(INSTALL) -m 0755 libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
 	ln -sf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libocpf.$(SHLIBEXT)
+ifeq ($(MANUALLY_CREATE_SYMLINKS), yes)
+	ln -sf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION)
+endif
 
 libocpf-installheader:
 	@echo "[*] install: libocpf headers"
@@ -591,7 +662,7 @@
 	libocpf/ocpf_write.po			\
 	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking $@"
-	@$(CC) $(DSOOPT) -Wl,-soname,libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) -o $@ $^ $(LIBS)
+	@$(CC) $(DSOOPT) $(LDFLAGS) -Wl,-soname,libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) -o $@ $^ $(LIBS)
 
 libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION): libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)
 	ln -fs $< $@
@@ -638,7 +709,7 @@
 ifneq ($(SNAPSHOT), no)
 	rm -f torture/torture_proto.h
 endif
-	rm -f torture/*.o torture/*.po
+	rm -f torture/*.o torture/*.po torture/*.gcno torture/*.gcda
 
 clean:: torture-clean
 
@@ -744,6 +815,7 @@
 			libmapiserver-clean			\
 			libmapistore-clean
 	rm -f mapiproxy/*.o mapiproxy/*.po
+	rm -f mapiproxy/*.gcno mapiproxy/*.gcda
 	rm -f mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT)
 
 clean:: mapiproxy-clean
@@ -776,6 +848,7 @@
 
 libmapiproxy-clean:
 	rm -f mapiproxy/libmapiproxy/*.po mapiproxy/libmapiproxy/*.o
+	rm -f mapiproxy/libmapiproxy/*.gcno mapiproxy/libmapiproxy/*.gcda
 ifneq ($(SNAPSHOT), no)
 	rm -f mapiproxy/libmapiproxy/openchangedb_property.c
 endif
@@ -824,6 +897,7 @@
 
 libmapiserver-clean:
 	rm -f mapiproxy/libmapiserver/*.po mapiproxy/libmapiserver/*.o
+	rm -f mapiproxy/libmapiserver/*.gcno mapiproxy/libmapiserver/*.gcda
 	rm -f mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)
 	rm -f mapiproxy/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION)
 
@@ -871,6 +945,7 @@
 
 libmapistore-clean:	$(OC_MAPISTORE_CLEAN)
 	rm -f mapiproxy/libmapistore/*.po mapiproxy/libmapistore/*.o
+	rm -f mapiproxy/libmapistore/*.gcno mapiproxy/libmapistore/*.gcda
 	rm -f mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
 	rm -f mapiproxy/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION)
 
@@ -888,7 +963,7 @@
 							mapiproxy/libmapistore/mapistore_processing.po	\
 							mapiproxy/libmapistore/mapistore_backend.po	\
 							mapiproxy/libmapistore/mapistore_tdb_wrap.po
-	@$(CC) -o $@ $(DSOOPT) -Wl,-soname,libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION) $^ -L. $(LIBS) $(TDB_LIBS)
+	@$(CC) -o $@ $(DSOOPT) $(LDFLAGS) -Wl,-soname,libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION) $^ -L. $(LIBS) $(TDB_LIBS)
 
 mapiproxy/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION): libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
 	ln -fs $< $@
@@ -909,6 +984,8 @@
 mapistore_sqlite3-clean:
 	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.o
 	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.po
+	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.gcno
+	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.gcda
 
 clean:: mapistore_sqlite3-clean
 
@@ -919,7 +996,7 @@
 
 mapiproxy/libmapistore/backends/mapistore_sqlite3.$(SHLIBEXT): mapiproxy/libmapistore/backends/mapistore_sqlite3.po
 	@echo "Linking mapistore module $@"
-	@$(CC) $(SQLITE_CFLAGS) -o $@ $(DSOOPT) $^ -L. $(LIBS) $(SQLITE_LIBS) 	\
+	@$(CC) $(SQLITE_CFLAGS) -o $@ $(DSOOPT) $(LDFLAGS) $^ -L. $(LIBS) $(SQLITE_LIBS) 	\
 	-Lmapiproxy mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
 
 #######################
@@ -935,6 +1012,8 @@
 
 mapistore_clean:
 	rm -f mapiproxy/libmapistore/tests/*.o
+	rm -f mapiproxy/libmapistore/tests/*.gcno
+	rm -f mapiproxy/libmapistore/tests/*.gcda
 	rm -f bin/mapistore_test
 
 clean:: mapistore_clean
@@ -960,6 +1039,7 @@
 
 mapiproxy-modules-clean::
 	rm -f mapiproxy/modules/*.o mapiproxy/modules/*.po
+	rm -f mapiproxy/modules/*.gcno mapiproxy/modules/*.gcda
 	rm -f mapiproxy/modules/*.so
 
 clean:: mapiproxy-modules-clean
@@ -994,6 +1074,7 @@
 	$(INSTALL) -d $(DESTDIR)$(datadir)/setup/AD
 	$(INSTALL) -m 0644 setup/AD/oc_provision* $(DESTDIR)$(datadir)/setup/AD/
 	$(INSTALL) -m 0644 setup/AD/prefixMap.txt $(DESTDIR)$(datadir)/setup/AD/
+	$(INSTALL) -m 0644 setup/AD/provision_schema_basedn_modify.ldif $(DESTDIR)$(datadir)/setup/AD/
 	$(INSTALL) -d $(DESTDIR)$(datadir)/setup/openchangedb
 	$(INSTALL) -m 0644 setup/openchangedb/oc_provision* $(DESTDIR)$(datadir)/setup/openchangedb/
 
@@ -1021,8 +1102,11 @@
 
 mapiproxy-servers-clean::
 	rm -f mapiproxy/servers/default/nspi/*.o mapiproxy/servers/default/nspi/*.po
+	rm -f mapiproxy/servers/default/nspi/*.gcno mapiproxy/servers/default/nspi/*.gcda
 	rm -f mapiproxy/servers/default/emsmdb/*.o mapiproxy/servers/default/emsmdb/*.po
+	rm -f mapiproxy/servers/default/emsmdb/*.gcno mapiproxy/servers/default/emsmdb/*.gcda
 	rm -f mapiproxy/servers/default/rfr/*.o mapiproxy/servers/default/rfr/*.po
+	rm -f mapiproxy/servers/default/rfr/*.gcno mapiproxy/servers/default/rfr/*.gcda
 	rm -f mapiproxy/servers/*.so
 
 clean:: mapiproxy-servers-clean
@@ -1051,7 +1135,7 @@
 
 mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT):	mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.po
 	@echo "Linking $@"
-	@$(CC) -o $@ $(DSOOPT) $^ -L $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
 
 #################################################################
 # Tools compilation rules
@@ -1073,7 +1157,11 @@
 openchangeclient-clean::
 	rm -f bin/openchangeclient
 	rm -f utils/openchangeclient.o
-	rm -f utils/openchange-tools.o	
+	rm -f utils/openchangeclient.gcno
+	rm -f utils/openchangeclient.gcda
+	rm -f utils/openchange-tools.o
+	rm -f utils/openchange-tools.gcno
+	rm -f utils/openchange-tools.gcda
 
 clean:: openchangeclient-clean
 
@@ -1082,7 +1170,7 @@
 			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)		\
 			libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking $@"
-	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+	@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
 
 
 ##############
@@ -1101,6 +1189,8 @@
 mapiprofile-clean::
 	rm -f bin/mapiprofile
 	rm -f utils/mapiprofile.o
+	rm -f utils/mapiprofile.gcno
+	rm -f utils/mapiprofile.gcda
 
 clean:: mapiprofile-clean
 
@@ -1108,7 +1198,7 @@
 			utils/openchange-tools.o 		\
 			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking $@"
-	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+	@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
 
 
 ###################
@@ -1127,6 +1217,8 @@
 openchangepfadmin-clean::
 	rm -f bin/openchangepfadmin
 	rm -f utils/openchangepfadmin.o
+	rm -f utils/openchangepfadmin.gcno
+	rm -f utils/openchangepfadmin.gcda
 
 clean:: openchangepfadmin-clean
 
@@ -1154,7 +1246,11 @@
 exchange2mbox-clean::
 	rm -f bin/exchange2mbox
 	rm -f utils/exchange2mbox.o
-	rm -f utils/openchange-tools.o	
+	rm -f utils/exchange2mbox.gcno
+	rm -f utils/exchange2mbox.gcda
+	rm -f utils/openchange-tools.o
+	rm -f utils/openchange-tools.gcno
+	rm -f utils/openchange-tools.gcda
 
 clean:: exchange2mbox-clean
 
@@ -1180,18 +1276,49 @@
 
 exchange2ical-clean::
 	rm -f bin/exchange2ical
-	rm -f utils/exchange2ical/exchange2ical.o
-	rm -f utils/exchange2ical/exchange2ical_utils.o
-	rm -f utils/exchange2ical/exchange2ical_component.o
-	rm -f utils/exchange2ical/exchange2ical_property.o
-	rm -f utils/openchange-tools.o	
+	rm -f utils/exchange2ical_tool.o
+	rm -f utils/exchange2ical_tool.gcno
+	rm -f utils/exchange2ical_tool.gcda
+	rm -f libexchange2ical/libexchange2ical.o
+	rm -f libexchange2ical/libexchange2ical.gcno
+	rm -f libexchange2ical/libexchange2ical.gcda
+	rm -f libexchange2ical/exchange2ical.o
+	rm -f libexchange2ical/exchange2ical.gcno
+	rm -f libexchange2ical/exchange2ical.gcda
+	rm -f libexchange2ical/exchange2ical_utils.o
+	rm -f libexchange2ical/exchange2ical_utils.gcno
+	rm -f libexchange2ical/exchange2ical_utils.gcda
+	rm -f libexchange2ical/exchange2ical_component.o
+	rm -f libexchange2ical/exchange2ical_component.gcno
+	rm -f libexchange2ical/exchange2ical_component.gcda
+	rm -f libexchange2ical/exchange2ical_property.o
+	rm -f libexchange2ical/exchange2ical_property.gcno
+	rm -f libexchange2ical/exchange2ical_property.gcda
+	rm -f libexchange2ical/libical2exchange.o
+	rm -f libexchange2ical/libical2exchange.gcno
+	rm -f libexchange2ical/libical2exchange.gcda
+	rm -f libexchange2ical/ical2exchange.o
+	rm -f libexchange2ical/ical2exchange.gcno
+	rm -f libexchange2ical/ical2exchange.gcda
+	rm -f libexchange2ical/ical2exchange_property.o
+	rm -f libexchange2ical/ical2exchange_property.gcno
+	rm -f libexchange2ical/ical2exchange_property.gcda
+	rm -f libexchange2ical/openchange-tools.o
+	rm -f libexchange2ical/openchange-tools.gcno
+	rm -f libexchange2ical/openchange-tools.gcda
 
+
 clean:: exchange2ical-clean
 
-bin/exchange2ical:	utils/exchange2ical/exchange2ical.o		\
-			utils/exchange2ical/exchange2ical_component.o	\
-			utils/exchange2ical/exchange2ical_property.o	\
-			utils/exchange2ical/exchange2ical_utils.o	\
+bin/exchange2ical:	utils/exchange2ical_tool.o	\
+			libexchange2ical/libexchange2ical.o		\
+			libexchange2ical/exchange2ical.o		\
+			libexchange2ical/exchange2ical_component.o	\
+			libexchange2ical/exchange2ical_property.o	\
+			libexchange2ical/exchange2ical_utils.o		\
+			libexchange2ical/libical2exchange.o	\
+			libexchange2ical/ical2exchange.o	\
+			libexchange2ical/ical2exchange_property.o	\
 			utils/openchange-tools.o			\
 			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
 	@echo "Linking $@"
@@ -1216,7 +1343,11 @@
 mapitest-clean:
 	rm -f bin/mapitest
 	rm -f utils/mapitest/*.o
+	rm -f utils/mapitest/*.gcno
+	rm -f utils/mapitest/*.gcda
 	rm -f utils/mapitest/modules/*.o
+	rm -f utils/mapitest/modules/*.gcno
+	rm -f utils/mapitest/modules/*.gcda
 ifneq ($(SNAPSHOT), no)
 	rm -f utils/mapitest/proto.h
 	rm -f utils/mapitest/mapitest_proto.h
@@ -1244,6 +1375,7 @@
 		utils/mapitest/modules/module_noserver.o	\
 		utils/mapitest/modules/module_errorchecks.o	\
 		utils/mapitest/modules/module_lcid.o		\
+		utils/mapitest/modules/module_mapidump.o	\
 		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)		
 	@echo "Linking $@"
 	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
@@ -1266,7 +1398,8 @@
 	utils/mapitest/modules/module_nspi.c		\
 	utils/mapitest/modules/module_noserver.c	\
 	utils/mapitest/modules/module_errorchecks.c	\
-	utils/mapitest/modules/module_lcid.c
+	utils/mapitest/modules/module_lcid.c		\
+	utils/mapitest/modules/module_mapidump.c
 	@echo "Generating $@"
 	@./script/mkproto.pl --private=utils/mapitest/mapitest_proto.h --public=utils/mapitest/proto.h $^
 
@@ -1287,7 +1420,11 @@
 openchangemapidump-clean::
 	rm -f bin/openchangemapidump
 	rm -f utils/backup/openchangemapidump.o
+	rm -f utils/backup/openchangemapidump.gcno
+	rm -f utils/backup/openchangemapidump.gcda
 	rm -f utils/backup/openchangebackup.o
+	rm -f utils/backup/openchangebackup.gcno
+	rm -f utils/backup/openchangebackup.gcda
 
 clean:: openchangemapidump-clean
 
@@ -1314,37 +1451,16 @@
 schemaIDGUID-clean::
 	rm -f bin/schemaIDGUID
 	rm -f utils/schemaIDGUID.o
+	rm -f utils/schemaIDGUID.gcno
+	rm -f utils/schemaIDGUID.gcda
 
 clean:: schemaIDGUID-clean
 
 bin/schemaIDGUID: utils/schemaIDGUID.o
 	@echo "Linking $@"
-	@$(CC) -o $@ $^ $(LIBS)
+	@$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
 
 
-##################
-# locale_codepage
-##################
-
-locale_codepage:	bin/locale_codepage
-
-locale_codepage-install:	locale_codepage
-	$(INSTALL) -m 0755 bin/locale_codepage $(DESTDIR)$(bindir)
-
-locale_codepage-uninstall:
-	rm -f bin/locale_codepage
-	rm -f $(DESTDIR)$(bindir)/locale_codepage
-
-locale_codepage-clean::
-	rm -f bin/locale_codepage
-	rm -f libmapi/tests/locale_codepage.o
-
-clean:: locale_codepage-clean
-
-bin/locale_codepage: libmapi/tests/locale_codepage.o libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
-	@echo "Linking $@"
-	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
-
 ###################
 # python code
 ###################
@@ -1387,6 +1503,13 @@
 
 check:: check-python
 
+clean-python:
+	rm -f pymapi/*.o
+	rm -f $(pythonscriptdir)/mapi.$(SHLIBEXT)
+	rm -f $(pythonscriptdir)/openchange/*.pyc
+
+clean:: clean-python
+
 ###################
 # nagios plugin
 ###################
@@ -1486,6 +1609,84 @@
 	LD_LIBRARY_PATH=`pwd` $(SMBTORTURE) --load-module torture/openchange.$(SHLIBEXT) ncalrpc: OPENCHANGE
 	./bin/mapitest --mapi-calls 
 
+####################################
+# coverage tests
+#
+# this could be better integrated...
+####################################
+coverage-init:
+	lcov --base-directory . --directory . --capture --initial --output-file oc_cov.info
+
+coverage::
+	rm -f libmapi/\<stdout\>.gcov
+	rm -f ./libocpf/lex.yy.gcda
+	rm -f libocpf/\<stdout\>.gcov
+	rm -f ./\<stdout\>.gcov
+	lcov --base-directory .  --directory . --output-file oc_cov.info --capture
+	genhtml -o covresults oc_cov.info
+
+coverage-clean::
+	rm -rf oc_cov.info
+	rm -rf covresults
+	rm -f test.gcno
+
+clean:: coverage-clean
+
+####################################
+# Qt4 widgets
+####################################
+openchange_qt4:	qt-lib qt-demoapp
+
+qt-lib: libqtmapi
+
+qt-demoapp: qt/demo/demoapp.moc qt/demo/demoapp 
+
+# No install yet - we need to finish this first
+
+qt-clean::
+	rm -f qt/demo/demoapp
+	rm -f qt/demo/*.o
+	rm -f qt/lib/*.o
+	rm -f qt/demo/*.moc
+	rm -f qt/lib/*.moc
+	rm -f libqtmapi*
+
+clean:: qt-clean
+
+qt/demo/demoapp.moc:	qt/demo/demoapp.h
+	@$(MOC) -i qt/demo/demoapp.h -o qt/demo/demoapp.moc
+
+qt/lib/foldermodel.moc:	qt/lib/foldermodel.h
+	@$(MOC) -i qt/lib/foldermodel.h -o qt/lib/foldermodel.moc
+
+qt/lib/messagesmodel.moc:	qt/lib/messagesmodel.h
+	@$(MOC) -i qt/lib/messagesmodel.h -o qt/lib/messagesmodel.moc
+
+libqtmapi: libmapi 					\
+	qt/lib/foldermodel.moc				\
+	qt/lib/messagesmodel.moc			\
+	libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+LIBQTMAPI_SO_VERSION = 0
+
+libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION): 	\
+	qt/lib/foldermodel.o			\
+	qt/lib/messagesmodel.o
+	@echo "Linking $@"
+	@$(CXX) $(DSOOPT) $(CXXFLAGS) $(LDFLAGS) -Wl,-soname,libqtmapi.$(SHLIBEXT).$(LIBQTMAPI_SO_VERSION) -o $@ $^ $(LIBS)
+
+
+qt/demo/demoapp: qt/demo/demoapp.o 				\
+	qt/demo/main.o 					\
+	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) 		\
+	libmapipp.$(SHLIBEXT).$(PACKAGE_VERSION)	\
+	libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CXX) $(CXXFLAGS) -o $@ $^ $(QT4_LIBS) $(LDFLAGS) $(LIBS)
+	# we don't yet install this...
+	ln -sf libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libqtmapi.$(SHLIBEXT)
+	ln -sf libqtmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libqtmapi.$(SHLIBEXT).$(LIBQTMAPI_SO_VERSION)
+
 # This should be the last line in the makefile since other distclean rules may 
 # need config.mk
 distclean::

Modified: trunk/openchange/README
===================================================================
--- trunk/openchange/README	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/README	2010-02-11 11:16:26 UTC (rev 3288)
@@ -59,6 +59,11 @@
 build time. The main input file is exchange.idl (see top level
 directory).
 
+- libexchange2ical  This directory provides functionality for 
+converting between Exchange calendar appointments and ICalendar (RFC2445 /
+RFC5545) format. Exchange -> ICalendar is fairly mature, ICalendar to 
+Exchange is in work.
+
 - libmapi/  This directory contains the main client-side library,
 called libmapi. libmapi closely reflects the underlying protocol
 operations (Exchange RPC) being performed between the client and the
@@ -101,6 +106,11 @@
 ("provision") the server side. They are not required for the client
 side.
 
+- qt/   This directory contains Qt4 bindings (lib/ subdirectory) and
+a sample application (demo/ subdirectory). The sample application 
+is intended for research and development use, not as a complete
+end-user application.
+
 - samba4/  This directory will be created during the build process if
 you call "make samba" or execute the ./script/installsamba4.sh
 script. It is used to build samba4, if required.
@@ -125,7 +135,7 @@
 applications / utilities that can be used to interact with an exchange
 server. They include:
  - utils/backup/  	backup and restore tools
- - utils/exchange2ical/ converts Exchange calendar into an ICal file
+ - utils/exchange2ical  converts Exchange calendar into an ICal file
  - utils/exchange2mbox	two way conversion between Exchange mail and mbox
  - utils/mapiprofile	set up client side profiles (login information)
  - utils/mapitest/	test tools for libmapi functionality

Modified: trunk/openchange/VERSION
===================================================================
--- trunk/openchange/VERSION	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/VERSION	2010-02-11 11:16:26 UTC (rev 3288)
@@ -26,7 +26,7 @@
 # e.g. OPENCHANGE_VERSION_RELEASE_NICKNAME=Nicky Nickname   #
 #  ->  "0.7 (Nicky Nickname)"                               #
 #############################################################
-OPENCHANGE_VERSION_RELEASE_NICKNAME=Cochrane
+OPENCHANGE_VERSION_RELEASE_NICKNAME=Nomad
 
 
 #############################################################
@@ -35,4 +35,4 @@
 # e.g. OPENCHANGE_VERSION_RELEASE_VERSION=0.8.2             #
 #  ->  "0.8.2 (Nicky Nickname)"                             #
 #############################################################
-OPENCHANGE_VERSION_RELEASE_NUMBER=
\ No newline at end of file
+OPENCHANGE_VERSION_RELEASE_NUMBER=0.10

Modified: trunk/openchange/config.mk.in
===================================================================
--- trunk/openchange/config.mk.in	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/config.mk.in	2010-02-11 11:16:26 UTC (rev 3288)
@@ -29,7 +29,7 @@
 sambaprefix=@sambaprefix@
 
 DSOOPT=-shared -fPIC
-CFLAGS=@CFLAGS@ -Wmissing-prototypes -Wstrict-prototypes     \
+CFLAGS=@CFLAGS@ @COMPILER_OPTIONS_C@ @ASSERT_DEFINITION@ \
        -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\"						\
        -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\"				\
        -DMAPISTORE_MAPPING_PATH=\"$(prefix)/private/mapistore\"
@@ -38,9 +38,6 @@
 SHLIBEXT=so
 PACKAGE_VERSION=@PACKAGE_VERSION@
 
-# Portability hack...
-CFLAGS+=-Duint_t="unsigned int" 
-
 SAMBA_CFLAGS=@SAMBA_CFLAGS@
 SAMBA_LIBS=@SAMBA_LIBS@
 
@@ -58,7 +55,7 @@
 LDFLAGS+=@LDFLAGS@
 
 # Assign CFLAGS to CXXFLAGS
-CXXFLAGS=@CFLAGS@ -I. $(SAMBA_CFLAGS) $(LDB_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS)
+CXXFLAGS=@CFLAGS@ @COMPILER_OPTIONS_CXX@ $(SAMBA_CFLAGS) $(LDB_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS)
 
 # OPENCHANGE LIBRARIES
 OC_IDL=@OC_IDL@
@@ -118,3 +115,13 @@
 
 PYCDIR=@PYCDIR@
 
+# Coverage
+COVERAGE_INIT=@COVERAGE_INIT@
+
+MANUALLY_CREATE_SYMLINKS=@MANUALLY_CREATE_SYMLINKS@
+
+# Qt support
+QT4_CXXFLAGS=@Qt4_CFLAGS@
+QT4_LIBS=@Qt4_LIBS@
+MOC=@MOC@
+OPENCHANGE_QT4=@OPENCHANGE_QT4@

Modified: trunk/openchange/configure.ac
===================================================================
--- trunk/openchange/configure.ac	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/configure.ac	2010-02-11 11:16:26 UTC (rev 3288)
@@ -2,14 +2,14 @@
 # Written by Jelmer Vernooij <jelmer at openchange.org>
 
 AC_PREREQ(2.57)
-AC_INIT(openchange, 0.8, [openchange at openchange.org])
+AC_INIT(openchange, 0.10, [openchange at openchange.org])
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE
 AC_DEFINE(_GNU_SOURCE, 1, [Use GNU extensions])
 
 PKG_PROG_PKG_CONFIG([0.20])
 
-CFLAGS="-I. -O3 -Wall -g3 -fstrict-aliasing $CFLAGS"
+CFLAGS="-I. $CFLAGS"
 
 dnl #################################################################
 dnl Check for OS dependent options
@@ -17,15 +17,25 @@
 AC_CANONICAL_HOST
 
 case "${host}" in
-     *freebsd*) BUILD_FOR_FREEBSD=yes ;;
+     *freebsd*) 
+		BUILD_FOR_FREEBSD=yes
+		AC_SUBST(BUILD_FOR_FREEBSD)
+		MANUALLY_CREATE_SYMLINKS=yes
+		;;
+     *solaris*) 
+		BUILD_FOR_SOLARIS=yes
+		AC_SUBST(BUILD_FOR_SOLARIS)
+		MANUALLY_CREATE_SYMLINKS=yes
+		;;
 esac
+AC_SUBST(MANUALLY_CREATE_SYMLINKS)
 
 #
 # OC_CHECK_SAMBA_PATH([PATH],[action-if-found],[action-if-not-found])
 # -------------------------------------------------------------------
 AC_DEFUN([OC_CHECK_SAMBA_PATH],
 [
- 	old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
+	old_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
 	PKG_CONFIG_PATH="$1/lib/pkgconfig"
 	export PKG_CONFIG_PATH
 	PKG_CHECK_EXISTS([samba-hostconfig], [found=1], [found=0])
@@ -88,27 +98,27 @@
 if test "x$1_set" != "xset"; then
    case "$2" in
    	LIBS)
-		OC_$2+=" $1"
-   		OC_$2_INSTALL+=" $1-install"
-   		OC_$2_UNINSTALL+=" $1-uninstall"
-   		OC_$2_INSTALLPC+=" $1-installpc"
-   		OC_$2_INSTALLHEADER+=" $1-installheader"
-   		OC_$2_INSTALLLIB+=" $1-installlib"
+		OC_$2="$OC_$2 $1"
+   		OC_$2_INSTALL="$OC_$2_INSTALL $1-install"
+   		OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall"
+   		OC_$2_INSTALLPC="$OC_$2_INSTALLPC $1-installpc"
+   		OC_$2_INSTALLHEADER="$OC_$2_INSTALLHEADER $1-installheader"
+   		OC_$2_INSTALLLIB="$OC_$2_INSTALLLIB $1-installlib"
 
 		AC_SUBST(OC_$2_INSTALLPC)
 		AC_SUBST(OC_$2_INSTALLHEADER)
 		AC_SUBST(OC_$2_INSTALLLIB)
 	;;
 	TOOLS|TORTURE)
-		OC_$2+=" $1"
-		OC_$2_INSTALL+=" $1-install"
-   		OC_$2_UNINSTALL+=" $1-uninstall"
+		OC_$2="$OC_$2 $1"
+		OC_$2_INSTALL="$OC_$2_INSTALL $1-install"
+   		OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall"
 	;;
 	SERVER|MAPISTORE)
-		OC_$2+=" $1"
-		OC_$2_CLEAN+="$1-clean"
-		OC_$2_INSTALL+=" $1-install"
-   		OC_$2_UNINSTALL+=" $1-uninstall"
+		OC_$2="$OC_$2 $1"
+		OC_$2_CLEAN="$OC_$2_CLEAN $1-clean"
+		OC_$2_INSTALL="$OC_$2_INSTALL $1-install"
+   		OC_$2_UNINSTALL="$OC_$2_UNINSTALL $1-uninstall"
 	;;
    esac
 
@@ -122,6 +132,14 @@
 fi[]
 ])
 
+dnl ##################################################################
+dnl Some general portability stuff
+dnl ##################################################################
+AC_CHECK_HEADERS( sys/cdefs.h string.h sys/sockio.h)
+AC_CHECK_FUNCS( strcasestr )
+
+
+
 dnl ###########################################################################
 dnl _AC_LANG_COMPILER_ICC
 dnl Check whether the compiler for the current language is really ICC.
@@ -139,14 +157,31 @@
 ])])
 
 dnl ###########################################################################
+dnl _AC_LANG_COMPILER_SUNCC
+dnl Check whether the compiler for the current language is really Sun compiler.
+dnl ###########################################################################
+m4_define([AC_LANG_COMPILER_SUNCC],
+[AC_CACHE_CHECK([whether we are really using the Sun _AC_LANG compiler],
+		[ac_cv_[]_AC_LANG_ABBREV[]_compiler_suncc],
+[_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef __SUNPRO_C
+       choke me
+#endif
+]])],
+		   [ac_compiler_suncc=yes],
+		   [ac_compiler_suncc=no])
+ac_cv_[]_AC_LANG_ABBREV[]_compiler_suncc=$ac_compiler_suncc
+])])
+
+dnl ###########################################################################
 dnl FreeBSD installs some libraries such as libpopt in the non default
 dnl search path /usr/local/{include,lib}. This nasty hack ensures
 dnl configure.ac will find the library if available and additional
 dnl flags be correctly added while compiling.
 dnl ###########################################################################
 if test x"$BUILD_FOR_FREEBSD" = x"yes"; then
-   CFLAGS+=" -I/usr/local/include"
-   LDFLAGS+=" -L/usr/local/lib"
+   CFLAGS="$CFLAGS -I/usr/local/include"
+   LDFLAGS="$LDFLAGS  -L/usr/local/lib"
+   CXXFLAGS="$CXXFLAGS -I/usr/local/include"
 fi
 
 dnl ----------------------------------------------------------------------------
@@ -167,19 +202,65 @@
 AC_PROG_CC
 
 dnl ---------------------------------------------------------------------------
-dnl Check for ICC
+dnl coverage testing
 dnl ---------------------------------------------------------------------------
+AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage],
+                                        [Compile the library with code coverage support (default is NO)]),
+                                        [use_cov=$enableval], [use_cov=no])
+
+
+if test "x$use_cov" = x"yes"; then
+   COVERAGE_INIT="coverage-init"
+fi
+AC_SUBST(COVERAGE_INIT)
+
+dnl ---------------------------------------------------------------------------
+dnl Set up the right compiler options
+dnl ---------------------------------------------------------------------------
+AC_LANG_COMPILER_SUNCC 
 AC_LANG_COMPILER_ICC
 
-dnl if it isn't icc, then use the gcc options
-dnl otherwise suppress some noise from icc
-if test x"$ac_cv_c_compiler_icc" != x"yes"; then
-    CFLAGS="$CFLAGS -Wp,-D_FORTIFY_SOURCE=2"
+if test x"$ac_cv_c_compiler_suncc" = x"yes"; then
+dnl Sun Studio Compiler
+    COMPILER_OPTIONS_SHARED="-D__FUNCTION__=__func__"
+    COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED"
+    COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED"
+    LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN/../lib'"
+elif test x"$ac_cv_c_compiler_icc" = x"yes"; then
+dnl Intel Compiler
+    COMPILER_OPTIONS_SHARED="-O3 -Wall -g3 -fstrict-aliasing -Wmissing-prototypes -Wstrict-prototypes -wd2259,188,593,869,981,181,1419,2218"
+    COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED"
+    COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED"
 else
-    CFLAGS="$CFLAGS -wd2259,188,593,869,981,181,1419,2218"
+dnl GNU Compiler
+    COMPILER_OPTIONS_SHARED="-Wall -g3 -fstrict-aliasing -Wp,-D_FORTIFY_SOURCE=2"
+    if test "x$use_cov" = "xyes"; then
+        COMPILER_OPTIONS_SHARED="-O0 $COMPILER_OPTIONS_SHARED"
+    else
+        COMPILER_OPTIONS_SHARED="-O3 $COMPILER_OPTIONS_SHARED"
+    fi
+    COMPILER_OPTIONS_C="$COMPILER_OPTIONS_SHARED -Wmissing-prototypes -Wstrict-prototypes"
+    if test "x$use_cov" = "xyes"; then
+        COMPILER_OPTIONS_C="$COMPILER_OPTIONS_C -fprofile-arcs -ftest-coverage"
+        LDFLAGS="$LDFLAGS -lgcov --coverage"
+    fi
+    COMPILER_OPTIONS_CXX="$COMPILER_OPTIONS_SHARED"
 fi
+AC_SUBST(COMPILER_OPTIONS_C)
+AC_SUBST(COMPILER_OPTIONS_CXX)
 
 dnl ---------------------------------------------------------------------------
+dnl Define an assert macro if this is a development release
+dnl ---------------------------------------------------------------------------
+. `dirname $0`/VERSION
+AC_SUBST(OPENCHANGE_VERSION_IS_SVN_SNAPSHOT)
+
+if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then
+   ASSERT_DEFINITION="-DENABLE_ASSERTS"
+fi
+AC_SUBST(ASSERT_DEFINITION)
+
+dnl ---------------------------------------------------------------------------
 dnl Check for install
 dnl ---------------------------------------------------------------------------
 AC_PROG_INSTALL
@@ -187,9 +268,6 @@
 dnl ---------------------------------------------------------------------------
 dnl Check for Perl
 dnl ---------------------------------------------------------------------------
-. `dirname $0`/VERSION
-AC_SUBST(OPENCHANGE_VERSION_IS_SVN_SNAPSHOT)
-
 AC_PATH_PROG(PERL, perl)
 
 if test x"$PERL" = x""; then
@@ -402,7 +480,6 @@
 	OC_RULE_ADD(mapiprofile, TOOLS)
 	OC_RULE_ADD(openchangemapidump, TOOLS)
 	OC_RULE_ADD(schemaIDGUID, TOOLS)
-	OC_RULE_ADD(locale_codepage, TOOLS)
 fi
 
 dnl --------------------------------------------------------------------------
@@ -444,6 +521,8 @@
 
 if test x"$SQLITEFOUND" = x"yes"; then
    OC_RULE_ADD(mapistore_sqlite3, MAPISTORE)
+else
+   enable_mapistore_sqlite3="no"
 fi
 
 
@@ -487,9 +566,9 @@
 	AC_MSG_ERROR(Please install swig)
    fi
 
-   SWIGDIRSALL+="swigperl-all"
-   SWIGDIRSINSTALL+="swigperl-install"
-   SWIGDIRSUNINSTALL+="swigperl-uninstall"
+   SWIGDIRSALL="swigperl-all"
+   SWIGDIRSINSTALL="swigperl-install"
+   SWIGDIRSUNINSTALL="swigperl-uninstall"
 fi
 
 PERL5DIR=`$PERL -e 'use Config; my $dir = $Config{sitelib}; print $dir'`
@@ -507,9 +586,9 @@
 			   enable_pymapi="$enableval",
 			   enable_pymapi=no)
 if test "x${enable_pymapi}" = xyes; then
-   PYMAPIALL+="pymapi"
-   PYMAPIINSTALL+="pymapi-install"
-   PYMAPIUNINSTALL+="pymapi-uninstall"
+   PYMAPIALL="pymapi"
+   PYMAPIINSTALL="pymapi-install"
+   PYMAPIUNINSTALL="pymapi-uninstall"
 fi
 
 PYCDIR=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='\\$(prefix)')"`
@@ -531,15 +610,42 @@
 	AC_SUBST(DOXYGEN)
 fi
 
+dnl ##########################################################################
+dnl Qt4 support
+dnl ##########################################################################
+AC_ARG_ENABLE(openchange-qt4,
+              AC_HELP_STRING([--enable-openchange-qt4],
+                             [Compile OpenChange Qt4 wrapper.]),
+              enable_openchange_qt4=$enableval,
+              enable_openchange_qt4="no")
+if test x$enable_openchange_qt4 = xyes; then
+  PKG_CHECK_MODULES(Qt4,
+                    QtCore >= 4.3.0 QtGui >= 4.3.0)
+  MOC=`$PKG_CONFIG --variable=moc_location QtCore`
+elif test x$enable_openchange_qt4 = xtry; then
+  PKG_CHECK_MODULES(Qt4,
+                    QtCore >= 4.3.0 QtGui >= 4.3.0,
+                    [enable_openchange_qt4="yes"
+                     MOC=`$PKG_CONFIG --variable=moc_location QtCore`],
+                    [enable_openchange_qt4="no"])
+fi
 
+AC_SUBST(Qt4_CFLAGS)
+AC_SUBST(Qt4_LIBS)
+AC_SUBST(MOC)
 
+if test "x$enable_openchange_qt4" = "xyes"; then
+   OPENCHANGE_QT4="openchange_qt4"
+fi
+AC_SUBST(OPENCHANGE_QT4)
+
 dnl ***********************
 dnl Makefiles 
 dnl ***********************
 AC_CONFIG_FILES([config.mk libmapi.pc libmapiadmin.pc libocpf.pc mapiproxy/libmapiproxy.pc
-		 mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc Doxyfile libmapi++/Doxyfile 
-		 libocpf/Doxyfile libmapiadmin/Doxyfile libmapi/Doxyfile mapiproxy/Doxyfile 
-		 utils/mapitest/Doxyfile])
+		 mapiproxy/libmapiserver.pc mapiproxy/libmapistore.pc libmapi++.pc
+		 Doxyfile libmapi++/Doxyfile libocpf/Doxyfile libmapiadmin/Doxyfile
+		 libmapi/Doxyfile mapiproxy/Doxyfile utils/mapitest/Doxyfile])
 AC_OUTPUT
 
 
@@ -560,7 +666,6 @@
 OC_SETVAL(mapitest)
 OC_SETVAL(openchangemapidump)
 OC_SETVAL(schemaIDGUID)
-OC_SETVAL(locale_codepage)
 OC_SETVAL(mapiproxy)
 
 OC_SETVAL(torture)
@@ -597,16 +702,19 @@
 	     - mapitest:		$enable_mapitest
 	     - openchangemapidump:	$enable_openchangemapidump
 	     - schemaIDGUID:		$enable_schemaIDGUID
-	     - locale_codepage:		$enable_locale_codepage
 
 	   * OpenChange Torture Suite:	$enable_torture
 
 	   * OpenChange Documentation:	$enable_doxygen
 
+	   * Coverage Tests:		$use_cov
+
 	   * OpenChange Bindings:
 	     - Perl:			$enable_perlswig
 	     - Python:			$enable_pymapi
+	     - Qt4:			$enable_openchange_qt4
 
+
 ===============================================================
 
 ])

Modified: trunk/openchange/doc/howto.txt
===================================================================
--- trunk/openchange/doc/howto.txt	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/doc/howto.txt	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,11 +1,11 @@
-Copyright 2005-2008 OpenChange Project
+Copyright 2005-2009 OpenChange Project
 under the terms at http://creativecommons.org/licenses/by-sa/3.0/
 
 
 OpenChange developer howto
 --------------------------
 
-== Updated on January 2009 ==
+== Updated in December 2009 ==
 
 
 ###############
@@ -32,7 +32,8 @@
      [0x5a] Provision
      [0x5b] Extending users Samba AD schema
      [0x5c] Setting smb.conf
-     [0x5d] Running the Address Book Provider (EMSABP)     
+     [0x5d] Running the Server (EMSABP / EMSMDB / RFR)
+     [0x5e] Solving problems     
 [0x6] SWIG BINDINGS
      [0x6a] Installation
      [0x6b] Sample applications
@@ -344,7 +345,7 @@
 Under your root account, provision the server from the Samba4 source
 directory:
 
-# cd samba4/source
+# cd samba4/source4
 # ./setup/provision --domain=OPENCHANGE --realm=OPENCHANGE.LOCAL \
 		    --adminpass=secret --server-role='domain controller'
 
@@ -379,6 +380,15 @@
 # ./setup/openchange_newuser --disable <username>
 
 
+You now need to add the dispatcher database for user mailboxes.
+
+# ./setup/openchange_provision --openchangedb
+
+You can now create the mailbox for the user in the dispatcher database
+
+# ./setup/openchange_newuser --mailbox <username>
+
+
 [0x5c] Setting smb.conf
 =======================
 
@@ -389,8 +399,16 @@
 
 http://mapiproxy.openchange.org
 
+Roughly, you need to add the following entries to the [globals] section:
 
-[0x5d] Running the Address Book Provider (EMSABP)
+### Configuration required by OpenChange server ###
+dcerpc endpoint servers = epmapper, mapiproxy
+dcerpc_mapiproxy:server = true
+dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
+### Configuration required by OpenChange server ###
+
+
+[0x5d] Running the Server (EMSABP / EMSMDB / RFR)
 =================================================
 
 The simplest is to just run "samba", but as a developer you may find
@@ -403,8 +421,24 @@
 particularly easy.
 
 
+[0x5e] Solving problems
+=================================================
+
+The most common problem is not having sufficient rights - make sure
+you are doing the configuration and process startup as root.
+
+Also, make sure that you don't have any older versions (e.g. partial or
+full provisioning). As a last resort, considering deleting the whole
+samba installation directory and reinstalling both samba4 and 
+OpenChange.
+
+If you still have problems, please post a detailed message to the
+development mailing list (devel at lists.openchange.org) showing what
+commands you followed and what the results of each command were.
+
+
 ########################
-[0x5] SWIG BINDINGS
+[0x6] SWIG BINDINGS
 ########################
 
 OpenChange has introduced SWIG bindings support for its MAPI

Modified: trunk/openchange/doc/man/man1/exchange2ical.1
===================================================================
--- trunk/openchange/doc/man/man1/exchange2ical.1	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/doc/man/man1/exchange2ical.1	2010-02-11 11:16:26 UTC (rev 3288)
@@ -32,17 +32,18 @@
 
 .SH SYNOPSIS
 .nf
-exchange2ical [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING]
-  [-P|--password=STRING] [-d|--debuglevel=STRING] [--dump-data]
+exchange2ical [-?V] [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING] 
+	[-P|--password=STRING] [-i|--icalsync=STRING] [-o|--filename=STRING] [-R|--range=STRING]
+        [-d|--debuglevel=STRING] [--dump-data] [-V|--version]
+
 .fi
 
 .SH DESCRIPTION
 exchange2ical provides a way to extract appointments from an Exchange calendar
-into the ical format. The ical is provided on stdout.
+into the ical format. The ical is provided on stdout by default if the filename is not specified.
 
 .SH OPTIONS
 
-.TP
 .B --database
 .TP
 .B -f
@@ -65,6 +66,29 @@
 password is stored in the profile.
 
 .TP
+.B --icalsync
+.TP
+.B -i
+Specify an icalendar file to be used to sync back to exchange.
+
+.TP
+.B --filename
+.TP
+.B -o
+Specify the filename for the icalendar output.  The specified file will be 
+overwritten with the new icalendar. If this is omitted, stdout will be used 
+by default.
+
+.TP
+.B --range
+.TP
+.B -r
+Specify the range of exchange appointments to be converted into an icalendar.  
+If there are no events, whos start date is within the specified range, 
+an icalendar with no vevents will be returned.
+.B Format: MM/DD/YYYY-MM/DD/YYYY
+
+.TP
 .B --dump-data
 Dump the hex data. This is only required for debugging or educational purposes.
 
@@ -80,6 +104,14 @@
 .nf
 exchange2ical > appointments.ical
 .fi
+.B Extract appointments from the Exchange calendar to a specified path
+.nf
+exchange2ical --filename=/path/to/file.ics
+.fi
+.B Extract only appointments which begin from June 25 2008 to July 26 2009
+.nf
+exchange2ical --range=06/25/2008-07/26/2009
+.fi
 
 .SH REMARKS
 If you are using the default profile database path and have set a

Modified: trunk/openchange/doc/man/man1/mapiprofile.1
===================================================================
--- trunk/openchange/doc/man/man1/mapiprofile.1	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/doc/man/man1/mapiprofile.1	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,7 +1,7 @@
 .\" OpenChange Project Tools Man Pages
 .\"
-.\" This manpage is Copyright (C) 2007-2008 Julien Kerihuel;
-.\" This manpage is Copyright (C)      2008 Brad Hards;
+.\" This manpage is Copyright (C) 2007-2010 Julien Kerihuel;
+.\" This manpage is Copyright (C) 2008-2009 Brad Hards;
 .\"
 .\" Permission is granted to make and distribute verbatim copies of this
 .\" manual provided the copyright notice and this permission notice are
@@ -33,13 +33,13 @@
 
 .SH SYNOPSIS
 .nf
-mapiprofile [-?GSncrl] [-?|--help] [--usage] [-L|--ldif PATH] [-G|--getdefault] [-S|--default] 
-	[-n|--newdb] [-f|--database PATH] [-P|--profile PROFILE] [-I|--address xxx.xxx.xxx.xxx] 
-	[-M|--workstation WORKSTATION_NAME] [-D|--domain DOMAIN] [-R|--realm REALM] 
-	[-u|--username USERNAME] [-C|--langcode LANGCODE] [-s|--pattern USERNAME] 
-	[-p|--password PASSWORD] [--nopass] [-c|--create] [-r|--delete] [-R|--rename STRING] 
-	[-l|--list] [--listlangs] [--dump] [-a|--attr VALUE] [--dump-data] [-d|--debuglevel LEVEL] 
-	[--getfqdn]
+mapiprofile [-?GSnEcrlV] [-?|--help] [--usage] [-L|--ldif PATH] [-G|--getdefault] [-S|--default]
+	[-n|--newdb] [-f|--database PATH] [-P|--profile PROFILE] [-I|--address xxx.xxx.xxx.xxx]
+	[-M|--workstation WORKSTATION_NAME] [-D|--domain DOMAIN] [-R|--realm REALM] [-E|--encrypt]
+	[-u|--username USERNAME] [-C|--language LANGUAGE] [-s|--pattern USERNAME]
+	[-p|--password PASSWORD] [--nopass] [-c|--create] [-r|--delete] [-R|--rename STRING]
+	[-l|--list] [--listlangs] [--dump] [-a|--attr VALUE] [--dump-data] [-d|--debuglevel LEVEL]
+	[--getfqdn] [-V|--version]
 .fi
 
 .SH DESCRIPTION
@@ -153,6 +153,14 @@
 Set the Windows domain name.
 
 .TP
+.B --encrypt
+.TP
+.B -E
+Require the connection to be encrypted. This is normally required only on Exchange 2010
+(and will presumably also be required on future versions), but may be used on Exchange 2003
+and Exchange 2007.
+
+.TP
 .B --realm REALM
 .TP
 .B -R
@@ -171,16 +179,16 @@
 Set the password corresponding to the username described above.
 
 .TP
-.B --langcode
+.B --language
 .TP
 .B -C
-Specify the language to use with the account. This can be specified
-as a code (in hexadecimal) or as a name. When specifying the name,
-you use the name of the language, and the location (if any), separated
-by underscores (e.g. English_United_States). See the --listlangs option for
-how to obtain the full list of languages. The default language code is 0x0409,
-for US English.
 
+Specify the language to use with the account. When specifying the
+name, you use the name of the language returned within the list
+--listlangs option displays. See the --listlangs option for how to
+obtain the full list of languages. The default language code is the
+system one stored within the LC_CTYPE environment variable.
+
 .TP
 .B --pattern
 .TP

Modified: trunk/openchange/doc/man/man1/openchangeclient.1
===================================================================
--- trunk/openchange/doc/man/man1/openchangeclient.1	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/doc/man/man1/openchangeclient.1	2010-02-11 11:16:26 UTC (rev 3288)
@@ -26,28 +26,26 @@
 .\" Process this file with
 .\" groff -man -Tascii openchangeclient.1
 .\"
-.TH OPENCHANGECLIENT 1 2008-11-24 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+.TH OPENCHANGECLIENT 1 2009-12-17 "OpenChange libmapi 0.9" "OpenChange Users' Manual"
 
 .SH NAME
 openchangeclient \- MAPI command line messaging tool
 
 .SH SYNOPSIS
 .nf
-openchangeclient [-?|--help] [--usage] [-f|--database=STRING] [--pf]
-  [-p|--profile=STRING] [-P|--password=STRING] [-S|--sendmail] 
-  [--sendappointment] [--sendcontact] [--sendtask] [--sendnote]
-  [-F|--fetchmail] [-G|--storemail=STRING] [-i|--fetch-items=STRING]
-  [--freebusy=STRING] [--force] [--delete=STRING] [-u|--update=STRING]
-  [-m|--mailbox] [-D|--deletemail] [-A|--attachments=STRING]
-  [-I|--html-inline=STRING] [-W|--html-file=STRING] [-t|--to=STRING]
-  [-c|--cc=STRING] [-b|--bcc=STRING] [-s|--subject=STRING] [-B|--body=STRING]
-  [--location=STRING] [--label=STRING] [--dtstart=STRING] [--dtend=STRING]
-  [--busystatus=STRING] [--taskstatus=STRING]
-  [--importance=STRING] [--email=STRING] [--fullname=STRING] [--cardname=STRING]
-  [--color=STRING] [--notifications] [--folder=STRING] [--mkdir] [--rmdir]
-  [--userlist] [--folder-name=STRING] [--folder-comment=STRING]
-  [-d|--debuglevel=STRING] [--dump-data] [--private]
-  [--ocpf-file=STRING] [--ocpf-dump=STRING] [--ocpf-syntax] [--ocpf-sender]
+openchangeclient [-?SFmDV] [-?|--help] [--usage] [-f|--database STRING] [--pf]
+  [-p|--profile STRING] [-P|--password STRING] [-S|--sendmail] [--sendappointment]
+  [--sendcontact] [--sendtask] [--sendnote] [-F|--fetchmail] [-G|--storemail STRING]
+  [-i|--fetch-items STRING] [--freebusy=STRING] [--force] [--delete=STRING]
+  [-u|--update STRING] [-m|--mailbox] [-D|--deletemail] [-A|--attachments STRING]
+  [-I|--html-inline STRING] [-W|--html-file STRING] [-t|--to STRING] [-c|--cc STRING]
+  [-b|--bcc STRING] [-s|--subject STRING] [-B|--body STRING] [--location=STRING]
+  [--label=STRING] [--dtstart=STRING] [--dtend=STRING] [--busystatus=STRING]
+  [--taskstatus=STRING] [--importance=STRING] [--email=STRING] [--fullname=STRING]
+  [--cardname=STRING] [--color=STRING] [--notifications] [--folder=STRING] [--mkdir]
+  [--rmdir] [--userlist] [--folder-name=STRING] [--folder-comment=STRING]
+  [-d|--debuglevel STRING] [--dump-data] [--private] [--ocpf-file=STRING]
+  [--ocpf-dump=STRING] [--ocpf-syntax] [--ocpf-sender] [-V|--version]
 .fi
 
 
@@ -176,6 +174,14 @@
 See the separate (HTML) documentation for libocpf for more information
 on the OCPF format.
 
+.TP
+.B --freebusy=STRING
+Fetch the free / busy status for the user specified by the string. You will
+usually need to use the 
+.B --pf
+option (see below) since free / busy status is normally obtained from the 
+public folder store.
+
 .SH OPTIONS
 
 .TP
@@ -558,5 +564,10 @@
 openchangeclient --mailbox
 .fi
 
+.B Obtain free / busy status
+.nf
+openchangeclient --pf --freebusy="test user3"
+.fi
+
 .SH AUTHOR
 Julien Kerihuel <j.kerihuel at openchange dot org>

Modified: trunk/openchange/exchange.idl
===================================================================
--- trunk/openchange/exchange.idl	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/exchange.idl	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1146,10 +1146,11 @@
 		[switch_is(StringType)] String	String;
 	} TypedString;
 
-	typedef [bitmap8bit] bitmap {
-		/* 0x0 means Read Only */
+	typedef [enum8bit] enum {
+		ReadOnly	= 0x0,
 		ReadWrite	= 0x1,
-		Create		= 0x3
+		Create		= 0x3,
+		OpenSoftDelete	= 0x4
 	} OpenMessage_OpenModeFlags;
 
 	typedef [flag(NDR_NOALIGN)] struct {
@@ -1191,8 +1192,8 @@
 	} RecipSMTP;
 
 	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
-		[case(0x0)] RecipExchange	EXCHANGE;
-		[case(0xA)] RecipSMTP		SMTP;
+		[case(0x1)] RecipExchange	EXCHANGE;
+		[case(0x3)] RecipSMTP		SMTP;
 		[default];
 	} recipient_type;
 
@@ -1205,6 +1206,8 @@
 
 	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
 		[case(0x0)];
+		[case(0x60)];
+		[case(0x260)];
 		[case(0x20)] astring				lpszA;
 		[case(0x220)][flag(STR_NULLTERM)] string	lpszW;
 		[default];
@@ -1226,11 +1229,11 @@
 
 	typedef [flag(NDR_NOALIGN)] struct {
 		uint16									RecipientFlags;
-		[switch_is(RecipientFlags & 0xA)]   recipient_type			type;
+		[switch_is(RecipientFlags & 0x7)]   recipient_type			type;
 		[switch_is(RecipientFlags & 0x208)] recipient_EmailAddress	       	EmailAddress;
 		[switch_is(RecipientFlags & 0x210)] recipient_DisplayName		DisplayName;
 		[switch_is(RecipientFlags & 0x600)] recipient_SimpleDisplayName    	SimpleDisplayName;
-		[switch_is(RecipientFlags & 0x220)] recipient_TransmittableDisplayName	TransmittableDisplayName;
+		[switch_is(RecipientFlags & 0x260)] recipient_TransmittableDisplayName	TransmittableDisplayName;
 		uint16									prop_count;
 		uint8									layout;
 		[flag(NDR_REMAINING)] DATA_BLOB						prop_values;
@@ -4178,8 +4181,9 @@
 		[out]				uint16					rgwBestVersion[3],
 		[in,out]			uint32					*pulTimeStamp,
 		[in,subcontext(4),flag(NDR_NOALIGN|NDR_REMAINING)] mapi2k7_AuxInfo	*rgbAuxIn,
-		[in,out][range(0,0x1008)]	uint32					*pcbAuxOut,
-		[in][flag(NDR_REMAINING)] DATA_BLOB data
+		[in]				uint32					cbAuxIn,
+		[out, length_is(*pcbAuxOut), size_is(*pcbAuxOut)] uint8			rgbAuxOut[],
+		[in,out][range(0,0x1008)]	uint32					*pcbAuxOut
 		);
 
 	/*****************/

Added: trunk/openchange/libexchange2ical/exchange2ical.c
===================================================================
--- trunk/openchange/libexchange2ical/exchange2ical.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/exchange2ical.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,767 @@
+/*
+   Common conversion routines for exchange2ical
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+
+static void exchange2ical_init(TALLOC_CTX *mem_ctx, struct exchange2ical *exchange2ical)
+{
+	exchange2ical->TimeZoneStruct = NULL;
+	exchange2ical->TimeZoneDesc = NULL;
+	exchange2ical->method = ICAL_METHOD_NONE;
+	exchange2ical->vtimezone = NULL;
+	exchange2ical->vcalendar = NULL;
+	exchange2ical->mem_ctx = mem_ctx;
+	exchange2ical->partstat = ICAL_PARTSTAT_NONE;
+	exchange2ical->ResponseStatus = NULL;
+	exchange2ical->Recurring = NULL;
+	exchange2ical->RecurrencePattern = NULL;
+	exchange2ical->AppointmentRecurrencePattern = NULL;
+	exchange2ical->Keywords = NULL;
+	exchange2ical->Contacts = NULL;
+	exchange2ical->apptStateFlags = NULL;
+	exchange2ical->sensitivity = NULL;
+	exchange2ical->apptStartWhole = NULL;
+	exchange2ical->apptEndWhole = NULL;
+	exchange2ical->apptSubType = NULL;
+	exchange2ical->OwnerCriticalChange = NULL;
+	exchange2ical->body = NULL;
+	exchange2ical->LastModified = NULL;
+	exchange2ical->Location = NULL;
+	exchange2ical->Importance = NULL;
+	exchange2ical->ExceptionReplaceTime = NULL;
+	exchange2ical->ResponseRequested = NULL;
+	exchange2ical->NonSendableBcc = NULL;
+	exchange2ical->Sequence = NULL;
+	exchange2ical->Subject = NULL;
+	exchange2ical->MessageLocaleId = NULL;
+	exchange2ical->BusyStatus = NULL;
+	exchange2ical->IntendedBusyStatus = NULL;
+	exchange2ical->GlobalObjectId = NULL;
+	exchange2ical->AttendeeCriticalChange = NULL;
+	exchange2ical->OwnerApptId = NULL;
+	exchange2ical->apptReplyTime = NULL;
+	exchange2ical->NotAllowPropose = NULL;
+	exchange2ical->AllowExternCheck = NULL;
+	exchange2ical->apptLastSequence = NULL;
+	exchange2ical->apptSeqTime = NULL;
+	exchange2ical->AutoFillLocation = NULL;
+	exchange2ical->AutoStartCheck = NULL;
+	exchange2ical->CollaborateDoc = NULL;
+	exchange2ical->ConfCheck = NULL;
+	exchange2ical->ConfType = NULL;
+	exchange2ical->Directory = NULL;
+	exchange2ical->MWSURL = NULL;
+	exchange2ical->NetShowURL = NULL;
+	exchange2ical->OnlinePassword = NULL;
+	exchange2ical->OrgAlias = NULL;
+	exchange2ical->SenderName = NULL;
+	exchange2ical->SenderEmailAddress = NULL;
+	exchange2ical->ReminderSet = NULL;
+	exchange2ical->ReminderDelta = NULL;
+	exchange2ical->vevent = NULL;
+	exchange2ical->valarm = NULL;
+	exchange2ical->bodyHTML = NULL;
+	exchange2ical->idx=0;
+}
+
+static void exchange2ical_clear(struct exchange2ical *exchange2ical)
+{
+	if (exchange2ical->AppointmentRecurrencePattern){
+		talloc_free(exchange2ical->AppointmentRecurrencePattern);
+	}
+	
+	if (exchange2ical->TimeZoneStruct) {
+		talloc_free(exchange2ical->TimeZoneStruct);
+	}
+
+	exchange2ical_init(exchange2ical->mem_ctx, exchange2ical);
+}
+
+
+static void exchange2ical_reset(struct exchange2ical *exchange2ical)
+{
+	if (exchange2ical->AppointmentRecurrencePattern){
+		talloc_free(exchange2ical->AppointmentRecurrencePattern);
+	}
+
+	if (exchange2ical->TimeZoneStruct) {
+		talloc_free(exchange2ical->TimeZoneStruct);
+	}
+	
+	exchange2ical->partstat = ICAL_PARTSTAT_NONE;
+	exchange2ical->ResponseStatus = NULL;
+	exchange2ical->Recurring = NULL;
+	exchange2ical->RecurrencePattern = NULL;
+	exchange2ical->AppointmentRecurrencePattern = NULL;
+	exchange2ical->Keywords = NULL;
+	exchange2ical->Contacts = NULL;
+	exchange2ical->apptStateFlags = NULL;
+	exchange2ical->sensitivity = NULL;
+	exchange2ical->apptStartWhole = NULL;
+	exchange2ical->apptEndWhole = NULL;
+	exchange2ical->apptSubType = NULL;
+	exchange2ical->OwnerCriticalChange = NULL;
+	exchange2ical->body = NULL;
+	exchange2ical->LastModified = NULL;
+	exchange2ical->Location = NULL;
+	exchange2ical->Importance = NULL;
+	exchange2ical->ExceptionReplaceTime = NULL;
+	exchange2ical->ResponseRequested = NULL;
+	exchange2ical->NonSendableBcc = NULL;
+	exchange2ical->Sequence = NULL;
+	exchange2ical->Subject = NULL;
+	exchange2ical->MessageLocaleId = NULL;
+	exchange2ical->BusyStatus = NULL;
+	exchange2ical->IntendedBusyStatus = NULL;
+	exchange2ical->GlobalObjectId = NULL;
+	exchange2ical->AttendeeCriticalChange = NULL;
+	exchange2ical->OwnerApptId = NULL;
+	exchange2ical->apptReplyTime = NULL;
+	exchange2ical->NotAllowPropose = NULL;
+	exchange2ical->AllowExternCheck = NULL;
+	exchange2ical->apptLastSequence = NULL;
+	exchange2ical->apptSeqTime = NULL;
+	exchange2ical->AutoFillLocation = NULL;
+	exchange2ical->AutoStartCheck = NULL;
+	exchange2ical->CollaborateDoc = NULL;
+	exchange2ical->ConfCheck = NULL;
+	exchange2ical->ConfType = NULL;
+	exchange2ical->Directory = NULL;
+	exchange2ical->MWSURL = NULL;
+	exchange2ical->NetShowURL = NULL;
+	exchange2ical->OnlinePassword = NULL;
+	exchange2ical->OrgAlias = NULL;
+	exchange2ical->SenderName = NULL;
+	exchange2ical->SenderEmailAddress = NULL;
+	exchange2ical->ReminderSet = NULL;
+	exchange2ical->ReminderDelta = NULL;
+	exchange2ical->vevent = NULL;
+	exchange2ical->valarm = NULL;
+	exchange2ical->bodyHTML = NULL;
+	exchange2ical->TimeZoneDesc = NULL;
+	exchange2ical->TimeZoneStruct = NULL;
+}
+
+
+static int exchange2ical_get_properties(TALLOC_CTX *mem_ctx, struct SRow *aRow, struct exchange2ical *exchange2ical, enum exchange2ical_flags eFlags)
+{
+	struct Binary_r	*apptrecur;
+	const char *messageClass;
+	struct Binary_r	*TimeZoneStruct;
+
+	if(eFlags & VcalFlag){
+		messageClass = octool_get_propval(aRow, PR_MESSAGE_CLASS_UNICODE);
+		exchange2ical->method = get_ical_method(messageClass);
+		if (!exchange2ical->method) return -1;
+	}
+	
+	if(((eFlags & RangeFlag) && !(eFlags & EntireFlag))||
+		(!(eFlags & RangeFlag) && (eFlags & EntireFlag))){
+		exchange2ical->apptStartWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentStartWhole);
+
+	}
+	
+	if(((eFlags & EventFlag) && !(eFlags & EntireFlag))||
+		(!(eFlags & EventFlag) && (eFlags & EntireFlag))){
+		exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId);
+		exchange2ical->Sequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentSequence); 	
+
+	}
+	
+	if(((eFlags & EventsFlag) && !(eFlags & EntireFlag))||
+		(!(eFlags & EventsFlag) && (eFlags & EntireFlag))){
+		exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId);
+
+	}
+	
+	if(eFlags & EntireFlag) {
+	  
+		apptrecur = (struct Binary_r *) octool_get_propval(aRow, PidLidAppointmentRecur);
+		exchange2ical->AppointmentRecurrencePattern = get_AppointmentRecurrencePattern(mem_ctx,apptrecur);
+		exchange2ical->RecurrencePattern = &exchange2ical->AppointmentRecurrencePattern->RecurrencePattern;
+		
+		TimeZoneStruct = (struct Binary_r *) octool_get_propval(aRow, PidLidTimeZoneStruct);
+		exchange2ical->TimeZoneStruct = get_TimeZoneStruct(mem_ctx, TimeZoneStruct);
+
+		exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription);
+		exchange2ical->Keywords = (const struct StringArray_r *) octool_get_propval(aRow, PidNameKeywords);
+		exchange2ical->Recurring = (uint8_t *) octool_get_propval(aRow, PidLidRecurring);
+		exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription);
+		exchange2ical->ExceptionReplaceTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidExceptionReplaceTime);
+		exchange2ical->ResponseStatus = (uint32_t *) octool_get_propval(aRow, PidLidResponseStatus);
+		exchange2ical->apptStateFlags = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentStateFlags);
+		exchange2ical->Contacts = (const struct StringArray_r *)octool_get_propval(aRow, PidLidContacts);
+		exchange2ical->apptEndWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentEndWhole);	
+		exchange2ical->apptSubType = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentSubType);
+		exchange2ical->OwnerCriticalChange = (const struct FILETIME *)octool_get_propval(aRow, PidLidOwnerCriticalChange);
+		exchange2ical->Location = (const char *) octool_get_propval(aRow, PidLidLocation); 	
+		exchange2ical->NonSendableBcc = (const char *) octool_get_propval(aRow, PidLidNonSendableBcc);
+		exchange2ical->BusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidBusyStatus); 	
+		exchange2ical->IntendedBusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidIntendedBusyStatus);	
+		exchange2ical->AttendeeCriticalChange = (const struct FILETIME *) octool_get_propval(aRow, PidLidAttendeeCriticalChange);	
+		exchange2ical->apptReplyTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentReplyTime);
+		exchange2ical->NotAllowPropose = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentNotAllowPropose);	
+		exchange2ical->AllowExternCheck = (uint8_t *) octool_get_propval(aRow, PidLidAllowExternalCheck);
+		exchange2ical->apptLastSequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentLastSequence);
+		exchange2ical->apptSeqTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentSequenceTime);	
+		exchange2ical->AutoFillLocation = (uint8_t *) octool_get_propval(aRow, PidLidAutoFillLocation);
+		exchange2ical->AutoStartCheck = (uint8_t *) octool_get_propval(aRow, PidLidAutoStartCheck);
+		exchange2ical->CollaborateDoc = (const char *) octool_get_propval(aRow, PidLidCollaborateDoc);
+		exchange2ical->ConfCheck = (uint8_t *) octool_get_propval(aRow, PidLidConferencingCheck);
+		exchange2ical->ConfType = (uint32_t *) octool_get_propval(aRow, PidLidConferencingType);
+		exchange2ical->Directory = (const char *) octool_get_propval(aRow, PidLidDirectory);
+		exchange2ical->MWSURL = (const char *) octool_get_propval(aRow, PidLidMeetingWorkspaceUrl);
+		exchange2ical->NetShowURL = (const char *) octool_get_propval(aRow, PidLidNetShowUrl);
+		exchange2ical->OnlinePassword = (const char *) octool_get_propval(aRow, PidLidOnlinePassword);
+		exchange2ical->OrgAlias = (const char *) octool_get_propval(aRow, PidLidOrganizerAlias);
+		exchange2ical->ReminderSet = (uint8_t *) octool_get_propval(aRow, PidLidReminderSet);
+		exchange2ical->ReminderDelta = (uint32_t *) octool_get_propval(aRow, PidLidReminderDelta);
+		exchange2ical->sensitivity = (uint32_t *) octool_get_propval(aRow, PR_SENSITIVITY);
+		exchange2ical->created = (const struct FILETIME *)octool_get_propval(aRow, PR_CREATION_TIME);
+		exchange2ical->body = (const char *)octool_get_propval(aRow, PR_BODY_UNICODE);
+		exchange2ical->LastModified = (const struct FILETIME *)octool_get_propval(aRow, PR_LAST_MODIFICATION_TIME);
+		exchange2ical->Importance = (uint32_t *) octool_get_propval(aRow, PR_IMPORTANCE);
+		exchange2ical->ResponseRequested = (uint8_t *) octool_get_propval(aRow, PR_RESPONSE_REQUESTED);
+		exchange2ical->Subject = (const char *) octool_get_propval(aRow, PR_SUBJECT_UNICODE);
+		exchange2ical->MessageLocaleId = (uint32_t *) octool_get_propval(aRow, PR_MESSAGE_LOCALE_ID);
+		exchange2ical->OwnerApptId = (uint32_t *) octool_get_propval(aRow, PR_OWNER_APPT_ID);
+		exchange2ical->SenderName = (const char *) octool_get_propval(aRow, PR_SENDER_NAME);
+		exchange2ical->SenderEmailAddress = (const char *) octool_get_propval(aRow, PR_SENDER_EMAIL_ADDRESS);
+	}
+	
+	return 0;
+	
+}
+
+
+static uint8_t exchange2ical_exception_from_ExceptionInfo(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check)
+{
+	uint32_t	i;
+	icalproperty *prop;
+	icalparameter *param;
+	icaltimetype icaltime;
+	/*sanity checks*/
+	if(!exchange2ical->AppointmentRecurrencePattern) return 1;
+	if(!exchange2ical->AppointmentRecurrencePattern->ExceptionInfo) return 1;
+	if(!exchange2ical->AppointmentRecurrencePattern->ExceptionCount) return 1;
+
+	for(i=0; i<exchange2ical->AppointmentRecurrencePattern->ExceptionCount; i++) {
+		
+		/*Check to see if event is acceptable*/
+		struct tm apptStart=get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
+		if (!checkEvent(exchange2ical, exchange2ical_check, &apptStart)){
+			return 0;
+		}
+		
+		/*Create a new vevent*/
+		exchange2ical->vevent = icalcomponent_new_vevent();
+		if ( ! (exchange2ical->vevent) ) {
+			return 1;
+		}
+		icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent);
+
+		/*dtstart from StartDateTime*/
+		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			struct tm	tm;
+			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
+			icaltime= get_icaldate_from_tm(&tm);
+			prop = icalproperty_new_dtstart(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		}else {
+			if(exchange2ical->TimeZoneDesc){
+				struct tm	tm;
+				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_dtstart(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, param);
+			} else {
+				struct tm	tm;
+				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_dtstart(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+		}
+		/*dtend from EndDateTime*/
+		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			struct tm	tm;
+			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
+			icaltime= get_icaldate_from_tm(&tm);
+			prop = icalproperty_new_dtend(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		}else {
+			if(exchange2ical->TimeZoneDesc){
+				struct tm	tm;
+				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_dtend(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, param);
+			} else {
+				struct tm	tm;
+				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_dtend(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+		}
+		/*recurrence-id from OriginalStartDate*/
+		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			struct tm	tm;
+			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
+			icaltime= get_icaldate_from_tm(&tm);
+			prop = icalproperty_new_recurrenceid(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		}else {
+			if(exchange2ical->TimeZoneDesc){
+				struct tm	tm;
+				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_recurrenceid(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, param);
+			} else {
+				struct tm	tm;
+				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
+				icaltime= get_icaldate_from_tm(&tm);
+				prop = icalproperty_new_recurrenceid(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+		}
+		
+		/*summary from Subject if subject is set*/
+		if (exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0001) {
+			exchange2ical->Subject=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Subject.subject;
+			ical_property_SUMMARY(exchange2ical);
+		}
+		
+
+		/*Valarm*/
+		/*ReminderSet*/
+		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0008){
+			exchange2ical->ReminderSet=(uint8_t *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rSet;
+			/*Reminder Delta*/
+			if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0004){
+				exchange2ical->ReminderDelta=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rDelta;
+			} else {
+				exchange2ical->ReminderDelta=NULL;
+			}
+			ical_component_VALARM(exchange2ical);
+		}
+
+		/*Location*/
+		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0010){
+			exchange2ical->Location=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Location.location;
+			ical_property_LOCATION(exchange2ical);
+		}
+		
+		/*Busy Status*/
+		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0020){
+			exchange2ical->BusyStatus=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->BusyStatus.bStatus;
+			ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical);
+		}
+	}
+	return 0;
+}
+
+static uint8_t exchange2ical_exception_from_EmbeddedObj(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check)
+{
+	mapi_object_t			obj_tb_attach;
+	mapi_object_t			obj_attach;
+	struct SRowSet			rowset_attach;
+	struct SPropTagArray		*SPropTagArray;
+	const uint32_t			*attach_num;
+	struct SPropValue		*lpProps;
+	enum MAPISTATUS			retval;
+	unsigned int			i;
+	uint32_t			count;
+	struct SRow			aRow2;
+	struct SRow			aRowT;
+	
+	mapi_object_init(&obj_tb_attach);
+	retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach);
+	if (retval != MAPI_E_SUCCESS) {
+		return 1;
+	}else {
+		SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM);
+		retval = SetColumns(&obj_tb_attach, SPropTagArray);
+		MAPIFreeBuffer(SPropTagArray);
+		retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
+
+		for (i = 0; i < rowset_attach.cRows; i++) {
+			
+			attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM);
+			retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach);
+
+			if (retval != MAPI_E_SUCCESS) {
+				return 1;
+			}else {
+				SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x3,
+									  PR_ATTACH_METHOD,
+									  PR_ATTACHMENT_FLAGS,
+									  PR_ATTACHMENT_HIDDEN
+									  );
+									  
+				lpProps = talloc_zero(exchange2ical->mem_ctx, struct SPropValue);
+				retval = GetProps(&obj_attach, SPropTagArray, &lpProps, &count);
+				MAPIFreeBuffer(SPropTagArray);
+				if (retval != MAPI_E_SUCCESS) {
+					return 1;
+				}else {
+					aRow2.ulAdrEntryPad = 0;
+					aRow2.cValues = count;
+					aRow2.lpProps = lpProps;
+					
+					uint32_t	*attachmentFlags;
+					uint32_t	*attachMethod;
+					uint8_t		*attachmentHidden;
+					
+					attachmentFlags	 = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS);
+					attachMethod	 = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD);
+					attachmentHidden = (uint8_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN);
+
+					if((*attachmentFlags & 0x00000002) 
+						&& (*attachMethod == 0x00000005) 
+						&& (attachmentHidden && (*attachmentHidden))) {
+					
+						struct exchange2ical exception;
+						exchange2ical_init(exchange2ical->mem_ctx,&exception);
+					
+						mapi_object_init(&exception.obj_message);
+						
+						retval = OpenEmbeddedMessage(&obj_attach, &exception.obj_message, MAPI_READONLY);
+						if (retval != MAPI_E_SUCCESS) {
+							return 1;
+						}else {							
+ 							SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x2d,
+												PidLidFExceptionalBody,
+												PidLidRecurring,
+												PidLidAppointmentRecur,
+												PidLidAppointmentStateFlags,
+												PidLidTimeZoneDescription,
+												PidLidTimeZoneStruct,
+												PidLidAppointmentStartWhole,
+												PidLidAppointmentEndWhole,
+												PidLidAppointmentSubType,
+												PidLidOwnerCriticalChange,
+												PidLidLocation,
+												PidLidExceptionReplaceTime,
+												PidLidNonSendableBcc,
+												PidLidAppointmentSequence,
+												PidLidBusyStatus,
+												PidLidIntendedBusyStatus,
+												PidLidCleanGlobalObjectId,
+												PidLidAttendeeCriticalChange,
+												PidLidAppointmentReplyTime,
+												PidLidAppointmentNotAllowPropose,
+												PidLidAllowExternalCheck,
+												PidLidAppointmentLastSequence,
+												PidLidAppointmentSequenceTime,
+												PidLidAutoFillLocation,
+												PidLidAutoStartCheck,
+												PidLidCollaborateDoc,
+												PidLidConferencingCheck,
+												PidLidConferencingType,
+												PidLidDirectory,
+												PidLidNetShowUrl,
+												PidLidOnlinePassword,
+												PidLidOrganizerAlias,
+												PidLidReminderSet,
+												PidLidReminderDelta,
+												PR_MESSAGE_CLASS_UNICODE,
+												PR_BODY_UNICODE,
+												PR_CREATION_TIME,
+												PR_LAST_MODIFICATION_TIME,
+												PR_IMPORTANCE,
+												PR_RESPONSE_REQUESTED,
+												PR_SUBJECT_UNICODE,
+												PR_OWNER_APPT_ID,
+												PR_SENDER_NAME,
+												PR_SENDER_EMAIL_ADDRESS,
+												PR_MESSAGE_LOCALE_ID
+ 								  );
+								  
+								  
+		
+							retval = GetProps(&exception.obj_message, SPropTagArray, &lpProps, &count);
+							
+							if (retval == MAPI_E_SUCCESS) {	
+								aRow2.ulAdrEntryPad = 0;
+								aRow2.cValues = count;
+								aRow2.lpProps = lpProps;
+								
+								
+								/*Get required properties to check if right event*/
+								exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags);
+					
+								/*Check to see if event is acceptable*/
+								if (!checkEvent(&exception, exchange2ical_check, get_tm_from_FILETIME(exception.apptStartWhole))){
+									break;
+								}
+
+								/*Grab Rest of Properties*/
+								exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags | EntireFlag);
+								uint8_t *dBody = (uint8_t *) octool_get_propval(&aRow2, PidLidFExceptionalBody);
+								retval = GetRecipientTable(&exception.obj_message, 
+									&exception.Recipients.SRowSet,
+									&exception.Recipients.SPropTagArray);
+									
+								/*Check for set subject*/
+								if (!exception.Subject){
+									exception.Subject=exchange2ical->Subject;
+								}
+								/*Check for a set apptSubType*/
+								if (!exception.apptSubType){
+									exception.apptSubType=exchange2ical->apptSubType;
+								}
+								/*check for a set Location*/
+								if (!exception.Location){
+									exception.Location=exchange2ical->Location;
+								}
+								/*check for set valarm info*/
+								if(!exception.ReminderSet){
+									exception.ReminderSet=exchange2ical->ReminderSet;
+								}
+								if(!exception.ReminderDelta){
+									exception.ReminderDelta=exchange2ical->ReminderDelta;
+								}
+								
+								/*Set to same vcalendar as parent*/
+								exception.vcalendar=exchange2ical->vcalendar;
+								
+								/*Set to same uid fallback in case GlobalObjId is missing*/
+								exception.idx=exchange2ical->idx;
+								
+								
+								/*has a modified summary*/
+								if(dBody && *dBody){
+									SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_BODY_HTML_UNICODE);
+									retval = GetProps(&exception.obj_message, SPropTagArray, &lpProps, &count);
+									MAPIFreeBuffer(SPropTagArray);
+									if (retval == MAPI_E_SUCCESS) {
+										aRowT.ulAdrEntryPad = 0;
+										aRowT.cValues = count;
+										aRowT.lpProps = lpProps;
+										exception.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE);
+									}
+								/* has the same summary as parent*/
+								} else{
+									exception.body=exchange2ical->body;
+									exception.bodyHTML=exchange2ical->bodyHTML;
+								}
+								
+								ical_component_VEVENT(&exception);
+								exception.vcalendar=NULL;
+								exchange2ical_clear(&exception);
+							}
+						} 							
+						mapi_object_release(&exception.obj_message);
+					}
+					MAPIFreeBuffer(lpProps);
+				}
+			}
+			
+		}
+
+	}
+	mapi_object_release(&obj_tb_attach);
+	return 0;	
+}
+
+icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	int				ret;
+	struct SRowSet			SRowSet;
+	struct SRow			aRow;
+	struct SRow			aRowT;
+	struct SPropValue		*lpProps;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	struct exchange2ical		exchange2ical;
+	mapi_object_t			obj_table;
+	uint32_t			count;
+	int				i;
+
+	mem_ctx = talloc_named(NULL, 0, "exchange2ical");
+	exchange2ical_init(mem_ctx, &exchange2ical);
+	
+	/* Open the contents table */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(obj_folder, &obj_table, 0, &count);
+	if (retval != MAPI_E_SUCCESS){
+		return NULL;
+	}
+	
+	DEBUG(0, ("MAILBOX (%d appointments)\n", count));
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
+					  PR_FID,
+					  PR_MID);
+					  
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("SetColumns", GetLastError());
+		return NULL;
+	}
+	
+	while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = (SRowSet.cRows-1); i >= 0; i--) {
+			mapi_object_init(&exchange2ical.obj_message);
+			retval = OpenMessage(obj_folder,
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     SRowSet.aRow[i].lpProps[1].value.d,
+					     &exchange2ical.obj_message, 0);
+			if (retval != MAPI_E_NOT_FOUND) {
+				SPropTagArray = set_SPropTagArray(mem_ctx, 0x30,
+								  PidLidGlobalObjectId,
+								  PidNameKeywords,
+								  PidLidRecurring,
+								  PidLidAppointmentRecur,
+								  PidLidAppointmentStateFlags,
+								  PidLidTimeZoneDescription,
+								  PidLidTimeZoneStruct,
+								  PidLidContacts,
+								  PidLidAppointmentStartWhole,
+								  PidLidAppointmentEndWhole,
+								  PidLidAppointmentSubType,
+								  PidLidOwnerCriticalChange,
+								  PidLidLocation,
+								  PidLidNonSendableBcc,
+								  PidLidAppointmentSequence,
+								  PidLidBusyStatus,
+								  PidLidIntendedBusyStatus,
+								  PidLidAttendeeCriticalChange,
+								  PidLidAppointmentReplyTime,
+								  PidLidAppointmentNotAllowPropose,
+								  PidLidAllowExternalCheck,
+								  PidLidAppointmentLastSequence,
+								  PidLidAppointmentSequenceTime,
+								  PidLidAutoFillLocation,
+								  PidLidAutoStartCheck,
+								  PidLidCollaborateDoc,
+								  PidLidConferencingCheck,
+								  PidLidConferencingType,
+								  PidLidDirectory,
+								  PidLidMeetingWorkspaceUrl,
+								  PidLidNetShowUrl,
+								  PidLidOnlinePassword,
+								  PidLidOrganizerAlias,
+								  PidLidReminderSet,
+								  PidLidReminderDelta,
+								  PidLidResponseStatus,
+								  PR_MESSAGE_CLASS_UNICODE,
+								  PR_SENSITIVITY,
+								  PR_BODY_UNICODE,
+								  PR_CREATION_TIME,
+								  PR_LAST_MODIFICATION_TIME,
+								  PR_IMPORTANCE,
+								  PR_RESPONSE_REQUESTED,
+								  PR_SUBJECT_UNICODE,
+								  PR_OWNER_APPT_ID,
+								  PR_SENDER_NAME,
+								  PR_SENDER_EMAIL_ADDRESS,
+								  PR_MESSAGE_LOCALE_ID
+								  );
+								  
+								  
+				retval = GetProps(&exchange2ical.obj_message, SPropTagArray, &lpProps, &count);
+
+				MAPIFreeBuffer(SPropTagArray);
+	
+				if (retval == MAPI_E_SUCCESS) {
+					aRow.ulAdrEntryPad = 0;
+					aRow.cValues = count;
+					aRow.lpProps = lpProps;
+					
+					/*Get Vcal info if first event*/
+					if(i==(SRowSet.cRows-1)){
+						ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, VcalFlag);
+						/*TODO: exit nicely*/
+						ical_component_VCALENDAR(&exchange2ical);
+					}
+					
+					
+					/*Get required properties to check if right event*/
+					ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, exchange2ical_check->eFlags);
+					
+					/*Check to see if event is acceptable*/
+					if (!checkEvent(&exchange2ical, exchange2ical_check, get_tm_from_FILETIME(exchange2ical.apptStartWhole))){
+						break;
+					}
+					
+					/*Set RecipientTable*/
+					retval = GetRecipientTable(&exchange2ical.obj_message, 
+							   &exchange2ical.Recipients.SRowSet,
+							   &exchange2ical.Recipients.SPropTagArray);
+					
+					/*Set PR_BODY_HTML for x_alt_desc property*/
+					SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_BODY_HTML_UNICODE);
+					retval = GetProps(&exchange2ical.obj_message, SPropTagArray, &lpProps, &count);
+					MAPIFreeBuffer(SPropTagArray);
+					if (retval == MAPI_E_SUCCESS) {
+						aRowT.ulAdrEntryPad = 0;
+						aRowT.cValues = count;
+						aRowT.lpProps = lpProps;
+						exchange2ical.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE);
+					}
+					
+					/*Get rest of properties*/
+					ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, (exchange2ical_check->eFlags | EntireFlag));
+					
+					/*add new vevent*/
+					ical_component_VEVENT(&exchange2ical);
+					
+					/*Exceptions to event*/
+					if(exchange2ical_check->eFlags != EventFlag){
+						ret = exchange2ical_exception_from_EmbeddedObj(&exchange2ical, exchange2ical_check);
+						if (ret){
+							ret=exchange2ical_exception_from_ExceptionInfo(&exchange2ical, exchange2ical_check);
+						}
+					}
+					
+					/*REMOVE once globalobjid is fixed*/
+					exchange2ical.idx++;
+					
+					MAPIFreeBuffer(lpProps);
+					exchange2ical_reset(&exchange2ical);
+				}
+				
+			}
+			mapi_object_release(&exchange2ical.obj_message);
+		}
+	}
+
+	icalcomponent *icalendar = exchange2ical.vcalendar;
+	exchange2ical_clear(&exchange2ical);
+	
+	/* Uninitialize MAPI subsystem */
+	mapi_object_release(&obj_table);
+	talloc_free(mem_ctx);	
+	return icalendar;
+}

Added: trunk/openchange/libexchange2ical/exchange2ical.h
===================================================================
--- trunk/openchange/libexchange2ical/exchange2ical.h	                        (rev 0)
+++ trunk/openchange/libexchange2ical/exchange2ical.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,372 @@
+/*
+   Convert Exchange appointments to ICAL
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef	__EXCHANGE2ICAL_H_
+#define	__EXCHANGE2ICAL_H_
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_property.h>
+#include <utils/openchange-tools.h>
+
+#include <libical/ical.h>
+
+#include <time.h>
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+
+struct message_recipients {
+	struct SRowSet			SRowSet;
+	struct SPropTagArray		SPropTagArray;
+};
+
+enum exchange2ical_flags{
+	EntireFlag = 	0x00001,
+	RangeFlag =  	0x00010,
+	VcalFlag =	0x00100,
+	EventFlag = 	0x01000,
+	EventsFlag = 	0x10000
+};
+
+struct exchange2ical_check {
+	enum exchange2ical_flags eFlags;
+	struct tm *begin;
+	struct tm *end;
+	struct GlobalObjectId *GlobalObjectId;
+	uint32_t Sequence;
+};
+
+struct exchange2ical {
+	TALLOC_CTX				*mem_ctx;
+	struct message_recipients		Recipients;
+	enum icalproperty_method		method;
+	enum icalparameter_partstat		partstat;
+	uint32_t				*ResponseStatus;
+	uint8_t					*Recurring;
+	struct RecurrencePattern		*RecurrencePattern;
+	struct TimeZoneStruct			*TimeZoneStruct;
+	const char				*TimeZoneDesc;
+	const struct StringArray_r     		*Keywords;
+	const struct StringArray_r		*Contacts;
+	uint32_t				*apptStateFlags;
+	uint32_t				*sensitivity;
+	uint32_t				*Importance;
+	const struct FILETIME  			*created;
+	const char				*body;
+	const struct FILETIME			*apptStartWhole;
+	const struct FILETIME			*apptEndWhole;
+	const struct FILETIME			*OwnerCriticalChange;
+	const struct FILETIME			*LastModified;
+	const struct FILETIME			*ExceptionReplaceTime;
+	uint8_t					*apptSubType;
+	const char				*Location;       
+	uint8_t					*ResponseRequested;
+	const char				*NonSendableBcc;
+	uint32_t				*Sequence;
+	const char				*Subject;
+	uint32_t				*MessageLocaleId;
+	uint32_t				*BusyStatus;
+	uint32_t				*IntendedBusyStatus;
+	struct Binary_r				*GlobalObjectId;
+	const struct FILETIME			*AttendeeCriticalChange;
+	uint32_t				*OwnerApptId;
+	const struct FILETIME			*apptReplyTime;
+	uint8_t					*NotAllowPropose;
+	uint8_t					*AllowExternCheck;
+	uint32_t				*apptLastSequence;
+	const struct FILETIME			*apptSeqTime;
+	uint8_t					*AutoFillLocation;
+	uint8_t					*AutoStartCheck;
+	const char				*CollaborateDoc;
+	uint8_t					*ConfCheck;
+	uint32_t				*ConfType;
+	const char				*Directory;
+	const char				*MWSURL;
+	const char				*NetShowURL;
+	const char				*OnlinePassword;
+	const char				*OrgAlias;
+	const char				*SenderName;
+	const char				*SenderEmailAddress;
+	uint8_t					*ReminderSet;
+	uint32_t				*ReminderDelta;	
+	icalcomponent				*vcalendar;
+	icalcomponent				*vevent;
+	icalcomponent				*vtimezone;
+	icalcomponent				*valarm;
+	mapi_object_t				obj_message;
+	const char				*bodyHTML;
+	uint32_t				idx;
+	struct	AppointmentRecurrencePattern	*AppointmentRecurrencePattern;
+};
+
+
+struct	ical_method {
+	enum icalproperty_method	method;
+	enum icalparameter_partstat	partstat;
+	const char			*PidTagMessageClass;
+};
+
+struct ical_calendartype {
+	uint16_t	type;
+	const char	*calendar;
+};
+
+struct ical_day {
+	enum icalrecurrencetype_weekday ical;
+	enum FirstDOW exchange;
+	uint32_t rdfDays;
+
+};
+
+struct ical_class {
+	uint32_t		sensivity;
+	enum icalproperty_class	classtype;
+};
+
+
+#define	OPENCHANGE_ICAL_PRODID	"-//OpenChange Project/exchange2ical MIMEDIR//EN"
+#define	OPENCHANGE_ICAL_VERSION	"2.0"
+
+__BEGIN_DECLS
+
+/* definitions from exchang2ical.c */
+icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check);
+
+
+/* definitions from exchange2ical_utils.c */
+struct icaltimetype get_icaltime_from_FILETIME(const struct FILETIME *);
+struct icaltimetype get_icaltime_from_FILETIME_UTC(const struct FILETIME *);
+struct icaltimetype get_icaldate_from_FILETIME(const struct FILETIME *);
+struct tm *get_tm_from_FILETIME(const struct FILETIME *);
+struct icaltimetype get_icaldate_from_tm(struct tm *);
+struct icaltimetype get_icaltimetype_from_tm_UTC(struct tm *tm);
+struct icaltimetype get_icaltimetype_from_tm(struct tm *tm);
+struct FILETIME get_FILETIME_from_string(const char *);
+struct FILETIME get_FILETIME_from_icaltimetype(icaltimetype *);
+struct tm get_tm_from_minutes(uint32_t mins);
+struct tm get_tm_from_minutes_UTC(uint32_t mins);
+struct icaltimetype get_icaldate_from_GlobalObjectId(struct GlobalObjectId *);
+NTTIME FILETIME_to_NTTIME(struct FILETIME);
+enum icalproperty_method get_ical_method(const char *);
+enum icalparameter_partstat get_ical_partstat(const char *);
+enum icalproperty_class get_ical_class(uint32_t);
+enum icalparameter_partstat get_ical_partstat_from_status(uint32_t status);
+enum FirstDOW get_exchange_day_from_ical(enum icalrecurrencetype_weekday weekday);
+uint8_t set_exception_from_ExceptionInfo(struct exchange2ical *, struct exchange2ical_check *);
+uint8_t set_exception_from_EmbeddedObj(struct exchange2ical *, struct exchange2ical_check *);
+bool checkEvent(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check, struct tm *aptStart);
+bool compareGlobalObjectIds(struct GlobalObjectId *glb1, struct GlobalObjectId *glb2);
+bool has_component_DAYLIGHT(struct exchange2ical *);
+uint16_t get_exchange_calendartype(const char *);
+uint32_t get_minutes_from_icaltimetype(icaltimetype);
+uint32_t get_exchange_rdfDays_from_ical(enum icalrecurrencetype_weekday weekday);
+const char *get_ical_calendartype(uint16_t);
+char *get_ical_date(TALLOC_CTX *, struct SYSTEMTIME *);
+int compare_minutes(const void *min1, const void *min2);
+
+/* definitions from exchange2ical_component.c */
+void ical_component_VCALENDAR(struct exchange2ical *);
+void ical_component_VEVENT(struct exchange2ical *);
+void ical_component_VTIMEZONE(struct exchange2ical *);
+void ical_component_STANDARD(struct exchange2ical *);
+void ical_component_DAYLIGHT(struct exchange2ical *);
+void ical_component_VALARM(struct exchange2ical *);
+
+
+/* definitions from exchange2ical_property.c */
+void ical_property_ATTACH(struct exchange2ical *);
+void ical_property_ATTENDEE(struct exchange2ical *);
+void ical_property_CATEGORIES(struct exchange2ical *);
+void ical_property_CLASS(struct exchange2ical *);
+void ical_property_CONTACT(struct exchange2ical *);
+void ical_property_CREATED(struct exchange2ical *);
+void ical_property_DTEND(struct exchange2ical *);
+void ical_property_DTSTAMP(struct exchange2ical *);
+void ical_property_DTSTART(struct exchange2ical *);
+void ical_property_DESCRIPTION(struct exchange2ical *);
+void ical_property_EXDATE(struct exchange2ical *);
+void ical_property_LAST_MODIFIED(struct exchange2ical *);
+void ical_property_LOCATION(struct exchange2ical *);
+void ical_property_ORGANIZER(struct exchange2ical *);
+void ical_property_PRIORITY(struct exchange2ical *);
+void ical_property_RDATE(struct exchange2ical *);
+void ical_property_RRULE_Daily(struct exchange2ical *);
+void ical_property_RRULE_Weekly(struct exchange2ical *);
+void ical_property_RRULE_Monthly(struct exchange2ical *);
+void ical_property_RRULE_NthMonthly(struct exchange2ical *);
+void ical_property_RRULE_Yearly(struct exchange2ical *);
+void ical_property_RRULE_NthYearly(struct exchange2ical *);
+void ical_property_RRULE(struct exchange2ical *);
+void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st);
+void ical_property_RECURRENCE_ID(struct exchange2ical *);
+void ical_property_RESOURCES(struct exchange2ical *);
+void ical_property_SEQUENCE(struct exchange2ical *);
+void ical_property_SUMMARY(struct exchange2ical *);
+void ical_property_TRANSP(struct exchange2ical *);
+void ical_property_TRIGGER(struct exchange2ical *);
+void ical_property_UID(struct exchange2ical *);
+void ical_property_X_ALT_DESC(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *);
+void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *);
+void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *);
+void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *);
+void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *);
+void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *);
+void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *);
+void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *);
+void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *);
+void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *);
+void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *);
+void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *);
+void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *);
+void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *);
+void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *);
+void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *);
+void ical_property_X_MS_OLK_SENDER(struct exchange2ical *);
+void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *);
+
+
+struct ical2exchange{
+	TALLOC_CTX				*mem_ctx;
+	enum icalproperty_method	method;
+	icalproperty 			*classProp;
+	icalproperty			*commentProp;
+	icalproperty 			*descriptionProp;
+	icalproperty 			*dtendProp;
+	icalproperty 			*dtstampProp;
+	icalproperty 			*dtstartProp;
+	icalproperty 			*durationProp;
+	icalproperty 			*locationProp;
+	icalproperty 			*organizerProp;
+	icalproperty 			*priorityProp;
+	icalproperty 			*recurrenceidProp;
+	icalproperty 			*rruleProp;
+	icalproperty			*sequenceProp;
+	icalproperty			*statusProp;
+	icalproperty			*summaryProp;
+	icalproperty 			*transpProp;
+	icalproperty 			*uidProp;
+	
+	uint32_t			rdateCount;
+	uint32_t			exdateCount;
+	
+	/*		x properties				*/
+	icalproperty			*x_busystatusProp;
+	icalproperty			*x_sequenceProp;
+	icalproperty			*x_importanceProp;
+	icalproperty			*x_intendedProp;
+	icalproperty			*x_ownerapptidProp;
+	icalproperty			*x_attendeecriticalchangeProp;
+	icalproperty			*x_replytimeProp;
+	icalproperty			*x_disallowcounterProp;
+	icalproperty			*x_isdraftProp;
+	icalproperty			*x_allowexterncheckProp;
+	icalproperty			*x_apptlastsequenceProp;
+	icalproperty			*x_apptseqtimeProp;
+	icalproperty			*x_autofilllocationProp;
+	icalproperty			*x_autostartcheckProp;
+	icalproperty			*x_confcheckProp;
+	icalproperty			*x_collaborateddocProp;
+	icalproperty			*x_conftypeProp;
+	icalproperty			*x_mwsurlProp;
+	icalproperty			*x_netshowurlProp;
+	icalproperty			*x_onlinepasswordProp;
+	icalproperty			*x_originalstartProp;
+	icalproperty			*x_originalendProp;
+	icalproperty			*x_orgaliasProp;
+	icalproperty			*x_ownercriticalchangeProp;
+				
+	
+	/*		Events					*/
+	icalcomponent			*attachEvent;
+	icalcomponent			*attendeeEvent;
+	icalcomponent			*categoriesEvent;
+	icalcomponent			*contactEvent;
+	icalcomponent			*exdateEvent;
+	icalcomponent			*rdateEvent;
+	icalcomponent			*resourcesEvent;
+	icalcomponent			*valarmEvent;
+	
+	mapi_object_t			*obj_message;
+	struct SPropValue		*lpProps;
+	uint32_t			cValues;
+
+};
+
+
+/*ical2exchange file*/
+void _IcalEvent2Exchange(mapi_object_t *obj_folder, icalcomponent *);
+
+
+/*ical2exchange_property*/
+void ical2exchange_property_ATTACH(struct ical2exchange *);
+//TODO ATTENDEE, ORGANIZER, x_ms_ok_sender
+void ical2exchange_property_CATEGORIES(struct ical2exchange *);
+void ical2exchange_property_CLASS(struct ical2exchange *);
+void ical2exchange_property_COMMENT(struct ical2exchange *);
+void ical2exchange_property_CONTACT(struct ical2exchange *);
+void ical2exchange_property_DESCRIPTION(struct ical2exchange *);
+void ical2exchange_property_DTSTAMP(struct ical2exchange *);
+void ical2exchange_property_DTSTART_DTEND(struct ical2exchange *);
+void ical2exchange_property_LOCATION(struct ical2exchange *);
+void ical2exchange_property_PRIORITY(struct ical2exchange *);
+void ical2exchange_property_RRULE_EXDATE_RDATE(struct ical2exchange *);
+void ical2exchange_property_SEQUENCE(struct ical2exchange *);
+void ical2exchange_property_STATUS(struct ical2exchange *);
+void ical2exchange_property_SUMMARY(struct ical2exchange *);
+void ical2exchange_property_VALARM(struct ical2exchange *);
+void ical2exchange_property_X_ALLOWEXTERNCHECK(struct ical2exchange *);
+void ical2exchange_property_X_APPTSEQTIME(struct ical2exchange *);
+void ical2exchange_property_X_APPTLASTSEQUENCE(struct ical2exchange *);
+void ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(struct ical2exchange *);
+void ical2exchange_property_X_AUTOFILLLOCATION(struct ical2exchange *);
+void ical2exchange_property_X_AUTOSTARTCHECK(struct ical2exchange *);
+void ical2exchange_property_X_COLLABORATEDDOC(struct ical2exchange *);
+void ical2exchange_property_X_CONFCHECK(struct ical2exchange *);
+void ical2exchange_property_X_CONFTYPE(struct ical2exchange *);
+void ical2exchange_property_X_DISALLOW_COUNTER(struct ical2exchange *);
+void ical2exchange_property_X_INTENDEDSTATUS(struct ical2exchange *);
+void ical2exchange_property_X_ISDRAFT(struct ical2exchange *);
+void ical2exchange_property_X_MWSURL(struct ical2exchange *);
+void ical2exchange_property_X_NETSHOWURL(struct ical2exchange *);
+void ical2exchange_property_X_ONLINEPASSWORD(struct ical2exchange *);
+void ical2exchange_property_X_ORGALIAS(struct ical2exchange *);
+void ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(struct ical2exchange *);
+void ical2exchange_property_X_OWNER_CRITICAL_CHANGE(struct ical2exchange *);
+void ical2exchange_property_X_OWNERAPPTID(struct ical2exchange *);
+void ical2exchange_property_X_REPLYTIME(struct ical2exchange *);
+
+
+__END_DECLS
+
+#endif /* __EXCHANGE2ICAL_H_ */

Added: trunk/openchange/libexchange2ical/exchange2ical_component.c
===================================================================
--- trunk/openchange/libexchange2ical/exchange2ical_component.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/exchange2ical_component.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,247 @@
+/*
+   Convert Exchange appointments and meetings to ICAL files
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <libexchange2ical/libexchange2ical.h>
+#include <libical/icalderivedproperty.h>
+
+/*
+   VCALENDAR component
+ */
+void ical_component_VCALENDAR(struct exchange2ical *exchange2ical)
+{
+	icalproperty* prop;
+	
+	exchange2ical->vcalendar = icalcomponent_new_vcalendar();
+	if (!(exchange2ical->vcalendar)) {
+		return;
+	}
+
+	prop = icalproperty_new_version(OPENCHANGE_ICAL_VERSION);
+	icalcomponent_add_property(exchange2ical->vcalendar, prop);
+
+	prop = icalproperty_new_prodid(OPENCHANGE_ICAL_PRODID);
+	icalcomponent_add_property(exchange2ical->vcalendar, prop);
+
+	prop = icalproperty_new_method(exchange2ical->method);
+	icalcomponent_add_property(exchange2ical->vcalendar, prop);
+
+
+	if (exchange2ical->RecurrencePattern && exchange2ical->RecurrencePattern->CalendarType) {
+		prop = icalproperty_new_x(get_ical_calendartype(exchange2ical->RecurrencePattern->CalendarType));
+		icalproperty_set_x_name(prop, "X-MICROSOFT-CALSCALE");
+		icalcomponent_add_property(exchange2ical->vcalendar, prop);
+	}
+
+	ical_component_VTIMEZONE(exchange2ical);
+}
+
+/*
+   VEVENT component
+ */
+void ical_component_VEVENT(struct exchange2ical *exchange2ical)
+{
+	exchange2ical->vevent = icalcomponent_new_vevent();
+	if ( ! (exchange2ical->vevent) ) {
+		return;
+	}
+	
+	icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent);
+	ical_property_ATTACH(exchange2ical);
+	ical_property_ATTENDEE(exchange2ical);
+	ical_property_CATEGORIES(exchange2ical);
+	ical_property_CLASS(exchange2ical);
+	ical_property_CONTACT(exchange2ical);
+	ical_property_CREATED(exchange2ical);
+	ical_property_DESCRIPTION(exchange2ical);
+	ical_property_DTEND(exchange2ical);
+	ical_property_DTSTAMP(exchange2ical);
+	ical_property_DTSTART(exchange2ical);
+	ical_property_RECURRENCE_ID(exchange2ical);
+	ical_property_EXDATE(exchange2ical);
+	ical_property_LAST_MODIFIED(exchange2ical);
+	ical_property_LOCATION(exchange2ical);
+	ical_property_ORGANIZER(exchange2ical);
+	ical_property_PRIORITY(exchange2ical);
+	/*All possible RDATE properties are now exported as separate vevents.
+	No longer a need for it*/
+	//ical_property_RDATE(exchange2ical);
+	ical_property_RRULE(exchange2ical);
+	ical_property_RESOURCES(exchange2ical);
+	ical_property_SEQUENCE(exchange2ical);
+	ical_property_SUMMARY(exchange2ical);
+	ical_property_TRANSP(exchange2ical);
+	ical_property_UID(exchange2ical);
+	ical_property_X_ALT_DESC(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical);
+	/* Looks like this is no longer supposed to be used, and is ignored by most Outlook versions */
+	/* ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(exchange2ical); */
+	ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_OWNERAPPTID(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_REPLYTIME(exchange2ical);
+	ical_property_X_MICROSOFT_DISALLOW_COUNTER(exchange2ical);
+	ical_property_X_MS_OLK_ALLOWEXTERNCHECK(exchange2ical);
+	ical_property_X_MS_OLK_APPTLASTSEQUENCE(exchange2ical);
+	ical_property_X_MS_OLK_APPTSEQTIME(exchange2ical);
+	ical_property_X_MS_OLK_AUTOFILLLOCATION(exchange2ical);
+	ical_property_X_MS_OLK_AUTOSTARTCHECK(exchange2ical);
+	ical_property_X_MS_OLK_COLLABORATEDOC(exchange2ical);
+	ical_property_X_MS_OLK_CONFCHECK(exchange2ical);
+	ical_property_X_MS_OLK_CONFTYPE(exchange2ical);
+	ical_property_X_MS_OLK_DIRECTORY(exchange2ical);
+	ical_property_X_MS_OLK_MWSURL(exchange2ical);
+	ical_property_X_MS_OLK_NETSHOWURL(exchange2ical);
+	ical_property_X_MS_OLK_ONLINEPASSWORD(exchange2ical);
+	ical_property_X_MS_OLK_ORGALIAS(exchange2ical);
+	ical_property_X_MS_OLK_SENDER(exchange2ical);
+	ical_component_VALARM(exchange2ical);
+}
+
+/*
+   VTIMEZONE component
+ */
+void ical_component_VTIMEZONE(struct exchange2ical *exchange2ical)
+{
+	exchange2ical->vtimezone = icalcomponent_new_vtimezone();
+
+	/* TZID property */
+	if (exchange2ical->TimeZoneDesc) {
+		icalproperty *tzid = icalproperty_new_tzid(exchange2ical->TimeZoneDesc);
+		icalcomponent_add_property(exchange2ical->vtimezone, tzid);
+	}
+	/* STANDARD sub-component */
+	if (exchange2ical->TimeZoneStruct) {
+		icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vtimezone);
+		ical_component_STANDARD(exchange2ical);
+
+		if (has_component_DAYLIGHT(exchange2ical)) {
+			ical_component_DAYLIGHT(exchange2ical);
+		}
+	} else {
+		icalcomponent_free(exchange2ical->vtimezone);
+	}
+}
+
+/*
+   STANDARD sub-component
+ */
+void ical_component_STANDARD(struct exchange2ical *exchange2ical)
+{
+	char		*dtstart = NULL;
+	int32_t		tzoffsetfrom;
+	int32_t		tzoffsetto;
+	icalcomponent	*standard;
+	icalproperty	*prop;
+
+	standard = icalcomponent_new_xstandard();
+	icalcomponent_add_component(exchange2ical->vtimezone, standard);
+
+	/* DTSTART property */
+	dtstart = get_ical_date(exchange2ical->mem_ctx, &(exchange2ical->TimeZoneStruct->stStandardDate));
+	if (dtstart) {
+		prop = icalproperty_new_dtstart(icaltime_from_string(dtstart));
+		icalcomponent_add_property(standard, prop);
+		talloc_free(dtstart);
+	}
+
+	/* RRULE Property */
+	if (has_component_DAYLIGHT(exchange2ical)){
+		ical_property_RRULE_daylight_standard(standard,exchange2ical->TimeZoneStruct->stStandardDate);
+	}
+	
+	/* TZOFFSETFROM property */
+	tzoffsetfrom = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lDaylightBias));
+	prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom);
+	icalcomponent_add_property(standard, prop);
+
+	/* TZOFFSETTO property */
+	tzoffsetto = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lStandardBias));
+	prop = icalproperty_new_tzoffsetto(tzoffsetto);
+	icalcomponent_add_property(standard, prop);
+}
+
+
+/*
+   DAYLIGHT sub-component
+ */
+void ical_component_DAYLIGHT(struct exchange2ical *exchange2ical)
+{
+	char		*dtstart = NULL;
+	int32_t		tzoffsetfrom;
+	int32_t		tzoffsetto;
+	icalcomponent	*daylight;
+	icalproperty	*prop;
+
+	daylight = icalcomponent_new_xdaylight();
+	icalcomponent_add_component(exchange2ical->vtimezone, daylight);
+
+	/* DTSTART property */
+	dtstart = get_ical_date(exchange2ical->mem_ctx, &exchange2ical->TimeZoneStruct->stDaylightDate);
+	if (dtstart) {
+		prop = icalproperty_new_dtstart(icaltime_from_string(dtstart));
+		icalcomponent_add_property(daylight, prop);
+		talloc_free(dtstart);
+	}
+	
+	/* RRULE property */
+	ical_property_RRULE_daylight_standard(daylight,exchange2ical->TimeZoneStruct->stDaylightDate);
+	
+	/* TZOFFSETFROM property */
+	tzoffsetfrom = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lStandardBias));
+	prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom);
+	icalcomponent_add_property(daylight, prop);
+
+	/* TZOFFSETTO property */
+	tzoffsetto = (-60 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lDaylightBias));
+	prop = icalproperty_new_tzoffsetto(tzoffsetto);
+	icalcomponent_add_property(daylight, prop);
+}
+
+
+/*
+   VALARM component
+
+   [MS-OXCICAL], Section 2.2.1.20.61 
+ */
+void ical_component_VALARM(struct exchange2ical *exchange2ical)
+{
+	icalproperty *action;
+	icalproperty *description;
+
+	/* Sanity check */
+	if (!exchange2ical->vevent) return;
+	if (!exchange2ical->ReminderSet) return;
+	if (*exchange2ical->ReminderSet == false) return;
+
+	exchange2ical->valarm = icalcomponent_new_valarm();
+	if (!(exchange2ical->valarm)) {
+		printf("could not create new valarm\n");
+		return;
+	}
+	icalcomponent_add_component(exchange2ical->vevent, exchange2ical->valarm);
+	ical_property_TRIGGER(exchange2ical);
+	action = icalproperty_new_action(ICAL_ACTION_DISPLAY);
+	icalcomponent_add_property(exchange2ical->valarm, action);
+	description = icalproperty_new_description("Reminder");
+	icalcomponent_add_property(exchange2ical->valarm, description);
+}

Added: trunk/openchange/libexchange2ical/exchange2ical_property.c
===================================================================
--- trunk/openchange/libexchange2ical/exchange2ical_property.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/exchange2ical_property.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,1515 @@
+/*
+   Convert Exchange appointments and meetings to ICAL files
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+
+struct RRULE_byday {
+	uint16_t	DayOfWeek;
+	const char	*DayName;
+};
+
+static const struct RRULE_byday RRULE_byday[] = {
+	{ 0x0000,	"SU" },
+	{ 0x0001,	"MO" },
+	{ 0x0002,	"TU" },
+	{ 0x0003,	"WE" },
+	{ 0x0004,	"TH" },
+	{ 0x0005,	"FR" },
+	{ 0x0006,	"SA" },
+	{ 0x0007,	NULL }
+};
+
+static const char *get_filename(const char *filename)
+{
+	const char *substr;
+
+	if (!filename) return NULL;
+
+	substr = rindex(filename, '/');
+	if (substr) return substr;
+
+	return filename;
+}
+
+/*
+  encode as base64
+  Samba4 code
+  caller frees
+*/
+static char *ldb_base64_encode(void *mem_ctx, const char *buf, int len)
+{
+	const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	int bit_offset, byte_offset, idx, i;
+	const uint8_t *d = (const uint8_t *)buf;
+	int bytes = (len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0;
+	char *out;
+
+	out = talloc_array(mem_ctx, char, bytes+pad_bytes+1);
+	if (!out) return NULL;
+
+	for (i=0;i<bytes;i++) {
+		byte_offset = (i*6)/8;
+		bit_offset = (i*6)%8;
+		if (bit_offset < 3) {
+			idx = (d[byte_offset] >> (2-bit_offset)) & 0x3F;
+		} else {
+			idx = (d[byte_offset] << (bit_offset-2)) & 0x3F;
+			if (byte_offset+1 < len) {
+				idx |= (d[byte_offset+1] >> (8-(bit_offset-2)));
+			}
+		}
+		out[i] = b64[idx];
+	}
+
+	for (;i<bytes+pad_bytes;i++)
+		out[i] = '=';
+	out[i] = 0;
+
+	return out;
+}
+
+
+
+void ical_property_ATTACH(struct exchange2ical *exchange2ical)
+{
+	mapi_object_t			obj_tb_attach;
+	mapi_object_t			obj_attach;
+	mapi_object_t			obj_stream;
+	struct SRowSet			rowset_attach;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	const uint32_t			*attach_num = NULL;
+	struct SPropValue		*lpProps;
+	enum MAPISTATUS			retval;
+	unsigned int			i;
+	uint32_t			count;
+	struct SRow			aRow2;
+
+	
+	mapi_object_init(&obj_tb_attach);
+	retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach);
+	if (retval == MAPI_E_SUCCESS) {
+		SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM);
+		retval = SetColumns(&obj_tb_attach, SPropTagArray);
+		MAPIFreeBuffer(SPropTagArray);
+		retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
+		
+		for (i = 0; i < rowset_attach.cRows; i++) {
+			attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM);
+			retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach);
+
+			if (retval == MAPI_E_SUCCESS) {
+
+				SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x7,
+									  PR_ATTACH_FILENAME,
+									  PR_ATTACH_LONG_FILENAME,
+									  PR_ATTACH_METHOD,
+									  PR_ATTACHMENT_FLAGS,
+									  PR_ATTACHMENT_HIDDEN,
+									  PR_ATTACH_MIME_TAG,
+									  PR_ATTACH_DATA_BIN
+									  );
+									  
+				lpProps = talloc_zero(exchange2ical->mem_ctx, struct SPropValue);
+				retval = GetProps(&obj_attach, SPropTagArray, &lpProps, &count);
+				MAPIFreeBuffer(SPropTagArray);
+				if (retval == MAPI_E_SUCCESS) {
+
+					uint32_t		*attachmentFlags = NULL;
+					uint32_t		*attachMethod = NULL;
+					uint8_t			*attachmentHidden = NULL;
+					const char 		*data = NULL;
+					const char		*fmttype = NULL;
+					const char		*attach_filename = NULL;
+					DATA_BLOB		body;
+					icalattach		*icalattach = NULL;
+					icalproperty 		*prop = NULL;
+					icalparameter 		*param = NULL;
+						
+					
+					aRow2.ulAdrEntryPad = 0;
+					aRow2.cValues = count;
+					aRow2.lpProps = lpProps;
+					
+					attachmentFlags	 = octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS);
+					attachMethod	 = octool_get_propval(&aRow2, PR_ATTACH_METHOD);
+					attachmentHidden = octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN);
+
+					if(!(*attachmentFlags & 0x00000007) 
+						&& (*attachMethod == 0x00000001) 
+						&& (!attachmentHidden || !(*attachmentHidden))) {
+
+						/* Get data of attachment */
+						retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+						retval = octool_get_stream(exchange2ical->mem_ctx, &obj_stream, &body);
+						data=ldb_base64_encode(exchange2ical->mem_ctx, (const char *)body.data, body.length);
+						
+						/*Create a new icalattach from above data*/
+						icalattach = icalattach_new_from_data((unsigned char *)data,0,0);
+						
+						/*Add attach property to vevent component*/
+						prop = icalproperty_new_attach(icalattach);
+						icalcomponent_add_property(exchange2ical->vevent, prop);
+
+						/* Attachment filename for X-FILENAME parameter*/
+						attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_LONG_FILENAME));
+						if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) {
+							attach_filename = get_filename(octool_get_propval(&aRow2, PR_ATTACH_FILENAME));
+						}
+						
+						/* fmttype parameter */
+						fmttype = (const char *) octool_get_propval(&aRow2, PR_ATTACH_MIME_TAG);
+						if(fmttype) {
+							param = icalparameter_new_fmttype(fmttype);
+							icalproperty_add_parameter(prop, param);
+						}
+						
+						/* ENCODING parameter */
+						param =icalparameter_new_encoding(ICAL_ENCODING_BASE64);
+						icalproperty_add_parameter(prop,param);
+						
+						/* VALUE parameter */
+						param=icalparameter_new_value(ICAL_VALUE_BINARY);
+						icalproperty_add_parameter(prop,param);
+						
+						/* X-FILENAME parameter */
+						param = icalparameter_new_x(attach_filename);
+						icalparameter_set_xname(param,"X-FILENAME");
+						icalproperty_add_parameter(prop,param);
+					}
+					MAPIFreeBuffer(lpProps);
+				}
+			}
+		}
+	}
+	mapi_object_release(&obj_tb_attach);
+}
+
+
+// TODO: check this - need an example
+void ical_property_ATTENDEE(struct exchange2ical *exchange2ical)
+{
+	uint32_t	i;
+	const char	*smtp;
+	const char	*display_name;
+	uint32_t	*RecipientFlags;
+	uint32_t	*RecipientType;
+	uint32_t	*TrackStatus;
+	struct SRowSet	*SRowSet;
+
+	/* Sanity check */
+	if (!exchange2ical->apptStateFlags) return;
+	if (!(*exchange2ical->apptStateFlags & 0x1)) return;
+	SRowSet = &(exchange2ical->Recipients.SRowSet);
+
+	/* Loop over the recipient table */
+	for (i = 0; i < SRowSet->cRows; i++) {
+		smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS);
+		display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME);
+		RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENTS_FLAGS);
+		RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE);
+		TrackStatus  = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TRACKSTATUS);
+
+
+		if (RecipientFlags && !(*RecipientFlags & 0x20) && !(*RecipientFlags & 0x2) &&
+		    (RecipientType && *RecipientType)) {
+			icalproperty *prop;
+			icalparameter *cn;
+			icalparameter *participantType;
+			enum icalparameter_partstat	partstat = ICAL_PARTSTAT_NONE;
+
+			if (smtp) {
+				char *mailtoURL;
+				mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:");
+				mailtoURL = talloc_strdup_append(mailtoURL, smtp);
+				prop = icalproperty_new_attendee(mailtoURL);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			} else {
+				prop = icalproperty_new_attendee("invalid:nomail");
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+
+			if (display_name) {
+				cn = icalparameter_new_cn(display_name);
+				icalproperty_add_parameter(prop, cn);
+			}
+
+			if (*RecipientType == 0x3) {
+				icalparameter *cutype = icalparameter_new_cutype(ICAL_CUTYPE_RESOURCE);
+				icalproperty_add_parameter(prop, cutype);
+			}
+
+			switch (*RecipientType) {
+			case 0x00000002:
+				participantType = icalparameter_new_role(ICAL_ROLE_OPTPARTICIPANT);
+				icalproperty_add_parameter(prop, participantType);
+				break;
+			case 0x00000003:
+				participantType = icalparameter_new_role(ICAL_ROLE_NONPARTICIPANT);
+				icalproperty_add_parameter(prop, participantType);
+				break;
+			}
+
+		
+			
+			if((exchange2ical->method==ICAL_METHOD_REPLY) || (exchange2ical->method==ICAL_METHOD_COUNTER)){
+				partstat = exchange2ical->partstat;	
+			}else if(exchange2ical->method==ICAL_METHOD_PUBLISH){
+				if(TrackStatus){
+					partstat = get_ical_partstat_from_status(*TrackStatus);
+				}else if(exchange2ical->ResponseStatus){
+					partstat = get_ical_partstat_from_status(*exchange2ical->ResponseStatus);
+				}
+			}
+			
+			if (partstat != ICAL_PARTSTAT_NONE) {
+				icalparameter *param;
+				param = icalparameter_new_partstat(partstat);
+				icalproperty_add_parameter(prop, param);
+			}
+
+			if (exchange2ical->ResponseRequested) {
+				icalparameter *rsvp;
+				if (*(exchange2ical->ResponseRequested)) {
+					rsvp = icalparameter_new_rsvp(ICAL_RSVP_TRUE);
+				} else {
+					rsvp = icalparameter_new_rsvp(ICAL_RSVP_FALSE);
+				}
+				icalproperty_add_parameter(prop, rsvp);
+			}
+		}
+	}
+}
+
+
+void ical_property_CATEGORIES(struct exchange2ical *exchange2ical)
+{
+	uint32_t	i;
+	icalproperty	*prop;
+
+	/* Sanity check */
+	if (!exchange2ical->Keywords) return;
+	if (!exchange2ical->Keywords->cValues) return;
+
+	for (i = 0; i < exchange2ical->Keywords->cValues; i++) {
+		prop = icalproperty_new_categories(exchange2ical->Keywords->lppszA[i]); 
+		icalcomponent_add_property(exchange2ical->vevent, prop);
+	}
+
+}
+
+
+void ical_property_CLASS(struct exchange2ical *exchange2ical)
+{
+	icalproperty	*prop;
+
+	/* Sanity check */
+	if (!exchange2ical->sensitivity) return;
+
+	prop = icalproperty_new_class(get_ical_class(*exchange2ical->sensitivity));
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_CONTACT(struct exchange2ical *exchange2ical)
+{
+	icalproperty	*prop;
+	uint32_t	i;
+
+	/* Sanity check */
+	if (!exchange2ical->Contacts) return;
+	if (!exchange2ical->Contacts->cValues) return;
+
+	for (i = 0; i < exchange2ical->Contacts->cValues; i++) {
+		prop = icalproperty_new_contact(exchange2ical->Contacts->lppszA[i]);
+		icalcomponent_add_property(exchange2ical->vevent, prop);
+	}
+}
+
+
+void ical_property_CREATED(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	struct icaltimetype	icaltime;
+
+	/* Sanity check */
+	if (!exchange2ical->created) return;
+
+	icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->created);
+
+	prop = icalproperty_new_created(icaltime);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+void ical_property_DTSTART(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	icalparameter		*tzid;
+	struct icaltimetype	icaltime;
+
+	/* Sanity check */
+	if (!exchange2ical->apptStartWhole) return;
+
+	/* If this is an all-day appointment */
+	if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+		icaltime = get_icaldate_from_FILETIME(exchange2ical->apptStartWhole);
+		prop = icalproperty_new_dtstart(icaltime);
+		icalcomponent_add_property(exchange2ical->vevent, prop);
+	} else {
+		if (exchange2ical->TimeZoneDesc) {
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
+			prop = icalproperty_new_dtstart(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+			icalproperty_add_parameter(prop, tzid);
+		} else {
+			icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
+			prop = icalproperty_new_dtstart(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		}
+	
+		
+	}
+}
+
+
+void ical_property_DTEND(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	icalparameter		*tzid;
+	struct icaltimetype	icaltime;
+
+	/* Sanity check */
+	if (!exchange2ical->apptEndWhole) return;
+
+	/* If this is an all-day appointment */
+	if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+		icaltime = get_icaldate_from_FILETIME(exchange2ical->apptEndWhole);
+		prop = icalproperty_new_dtend(icaltime);
+		icalcomponent_add_property(exchange2ical->vevent, prop);
+	} else {
+		if (exchange2ical->TimeZoneDesc) {
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole);
+			prop = icalproperty_new_dtend(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+			icalproperty_add_parameter(prop, tzid);
+		} else {
+			icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptEndWhole);
+			prop = icalproperty_new_dtend(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		}
+		
+	}
+}
+
+
+void ical_property_DTSTAMP(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	struct icaltimetype	icaltime;
+	struct tm		*tm;
+	icalparameter		*tzid;
+	time_t			t;
+
+	/* Sanity check */
+	/*If OwnerCriticalChange field is null, get time system time*/
+	if (!exchange2ical->OwnerCriticalChange) {
+		t=time(NULL);
+		tm = gmtime(&t);
+		icaltime = get_icaltimetype_from_tm_UTC(tm);
+		prop = icalproperty_new_dtstamp(icaltime);
+		icalcomponent_add_property(exchange2ical->vevent, prop);
+		return;
+	} else {
+	      icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->OwnerCriticalChange);
+	      prop = icalproperty_new_dtstamp(icaltime);
+	      icalcomponent_add_property(exchange2ical->vevent, prop);
+	      if (exchange2ical->TimeZoneDesc) {
+			tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+			icalproperty_add_parameter(prop, tzid);
+		}
+	}
+}
+
+
+void ical_property_DESCRIPTION(struct exchange2ical *exchange2ical)
+{
+	icalproperty	*prop;
+
+	if (exchange2ical->method == ICAL_METHOD_REPLY) return;
+	if (!exchange2ical->body) return;
+
+	prop = icalproperty_new_description(exchange2ical->body);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_EXDATE(struct exchange2ical *exchange2ical)
+{
+	uint32_t	i;
+	uint32_t	j;
+	uint8_t		modified;
+	struct icaltimetype	icaltime;
+	struct icaltimetype	dttime;
+
+	icalproperty	*prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+
+	/* Sanity check */
+	if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
+	if (!pat) return;
+	if (!pat->DeletedInstanceCount) return;
+
+	for (i = 0; i < pat->DeletedInstanceCount; i++) {
+		modified=0;
+		if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){
+			for(j=0; j < pat->ModifiedInstanceCount; j++){
+				if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){
+					modified=1;
+					break;
+				}
+			}
+		}
+		/* If this is an all-day appointment */
+		if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			struct tm	tm;
+			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
+			icaltime= get_icaldate_from_tm(&tm);
+			prop = icalproperty_new_exdate(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		} else if (!modified){
+			/* number of minutes between midnight of the specified
+			* day and midnight, January 1, 1601 */
+			struct tm	tm;
+			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
+			icaltime= get_icaltimetype_from_tm(&tm);
+
+			if (exchange2ical->TimeZoneDesc) {
+				/*Get time from dtstart*/
+				if (exchange2ical->apptEndWhole){
+					dttime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
+					icaltime.hour   = dttime.hour;
+					icaltime.minute = dttime.minute;
+				}
+
+				prop = icalproperty_new_exdate(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			} else {
+				/*Get time from dtstart*/
+				icaltime.is_utc = 1;
+				if (exchange2ical->apptEndWhole){
+					dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
+					icaltime.hour   = dttime.hour;
+					icaltime.minute = dttime.minute;
+				}
+				prop = icalproperty_new_exdate(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+		}		
+		
+	}
+}
+
+
+void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	struct icaltimetype	icaltime;
+	icalparameter		*tzid;
+
+
+	/* Sanity check */
+	if (!exchange2ical->LastModified) return;
+	if (exchange2ical->TimeZoneDesc) {
+		icaltime=get_icaltime_from_FILETIME(exchange2ical->LastModified);
+		prop = icalproperty_new_lastmodified(icaltime);
+		tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+		icalproperty_add_parameter(prop, tzid);
+	} else {
+		icaltime=get_icaltime_from_FILETIME_UTC(exchange2ical->LastModified);
+		prop = icalproperty_new_lastmodified(icaltime);
+	}
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_LOCATION(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	/* Sanity check */
+	if (!exchange2ical->Location) return;
+
+	prop = icalproperty_new_location(exchange2ical->Location);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_ORGANIZER(struct exchange2ical *exchange2ical)
+{
+	const char	*smtp;
+	const char	*display_name;
+	uint32_t	*RecipientFlags;
+	uint32_t	*RecipientType;
+	uint32_t	i;
+	struct SRowSet	*SRowSet;
+
+	/* Sanity check */
+	if (!exchange2ical->apptStateFlags) return;
+	if (!(*exchange2ical->apptStateFlags & 0x1)) return;
+
+	SRowSet = &(exchange2ical->Recipients.SRowSet);
+
+	/* Loop over the recipient table */
+	for (i = 0; i < SRowSet->cRows; i++) {
+		smtp = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_SMTP_ADDRESS);
+		display_name = (const char *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_DISPLAY_NAME);
+		RecipientFlags = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENTS_FLAGS);
+		RecipientType = (uint32_t *) octool_get_propval(&(SRowSet->aRow[i]), PR_RECIPIENT_TYPE);
+
+		if (RecipientFlags && !(*RecipientFlags & 0x20) &&
+		    ((*RecipientFlags & 0x2) || (RecipientType && !*RecipientType))) {
+			icalproperty *prop;
+			icalparameter *cn;
+
+			if (smtp) {
+				char *mailtoURL;
+				mailtoURL = talloc_strdup(exchange2ical->mem_ctx, "mailto:");
+				mailtoURL = talloc_strdup_append(mailtoURL, smtp);
+				prop = icalproperty_new_organizer(mailtoURL);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				talloc_free(mailtoURL);
+			} else {
+				prop = icalproperty_new_organizer("invalid:nomail");
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+
+			if (display_name) {
+				cn = icalparameter_new_cn(display_name);
+				icalproperty_add_parameter(prop, cn);
+			}
+		}
+	}
+}
+
+
+void ical_property_PRIORITY(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	/* Sanity check */
+	if (!exchange2ical->Importance) return;
+
+	switch (*exchange2ical->Importance) {
+	case 0x00000000:
+		prop = icalproperty_new_priority(9);
+		break;
+	case 0x00000001:
+		prop = icalproperty_new_priority(5);
+		break;
+	case 0x00000002:
+		prop = icalproperty_new_priority(1);
+		break;
+	default:
+		prop = icalproperty_new_priority(5);
+	}
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE_Daily(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_DAILY_RECURRENCE;
+	recurrence.interval = (pat->Period / 1440);
+
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	}
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE_Weekly(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+	uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.WeekRecurrencePattern;
+	short idx = 0;
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_WEEKLY_RECURRENCE;
+	recurrence.interval = pat->Period;
+	
+	if(pat->Period > 1){
+		switch(pat->FirstDOW){
+			case FirstDOW_Sunday:
+				recurrence.week_start=ICAL_SUNDAY_WEEKDAY;
+				break;
+			case FirstDOW_Monday:
+				recurrence.week_start=ICAL_MONDAY_WEEKDAY;
+				break;
+			case FirstDOW_Tuesday:
+				recurrence.week_start=ICAL_TUESDAY_WEEKDAY;
+				break;
+			case FirstDOW_Wednesday:
+				recurrence.week_start=ICAL_WEDNESDAY_WEEKDAY;
+				break;
+			case FirstDOW_Thursday:
+				recurrence.week_start=ICAL_THURSDAY_WEEKDAY;
+				break;
+			case FirstDOW_Friday:
+				recurrence.week_start=ICAL_FRIDAY_WEEKDAY;
+				break;
+			case FirstDOW_Saturday:
+				recurrence.week_start=ICAL_SATURDAY_WEEKDAY;
+				break;
+		}
+	}
+	
+	if (rdfDaysBitmask & Su) {
+		recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & M) {
+		recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Tu) {
+		recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & W) {
+		recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Th) {
+		recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & F) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Sa) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	}
+
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE_Monthly(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+	uint32_t day = pat->PatternTypeSpecific.Day;
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_MONTHLY_RECURRENCE;
+	recurrence.interval = pat->Period;
+
+	if (day == 0x0000001F) {
+		recurrence.by_month_day[0] = -1;
+	} else {
+		recurrence.by_month_day[0] = day;
+	}
+	recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	}
+
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE_NthMonthly(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+	uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
+	short idx = 0;
+	enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_MONTHLY_RECURRENCE;
+	recurrence.interval = pat->Period;
+
+	if (rdfDaysBitmask & Su) {
+		recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & M) {
+		recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Tu) {
+		recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & W) {
+		recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Th) {
+		recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & F) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Sa) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	if (setpos == RecurrenceN_First) {
+		recurrence.by_set_pos[0] = 1;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Second) {
+		recurrence.by_set_pos[0] = 2;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Third) {
+		recurrence.by_set_pos[0] = 3;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Fourth) {
+		recurrence.by_set_pos[0] = 4;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Last) {
+		recurrence.by_set_pos[0] = -1;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	}
+
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	}
+
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE_Yearly(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+	uint32_t day = pat->PatternTypeSpecific.Day;
+	struct icaltimetype icaltime;
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_YEARLY_RECURRENCE;
+	recurrence.interval = (pat->Period / 12);
+
+	if (day == 0x0000001F) {
+		recurrence.by_month_day[0] = -1;
+	} else {
+		recurrence.by_month_day[0] = day;
+	}
+	recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
+	recurrence.by_month[0] = icaltime.month;
+	recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
+
+
+	
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	} 
+	
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+void ical_property_RRULE_NthYearly(struct exchange2ical *exchange2ical)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
+	uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
+	short idx = 0;
+	enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;
+
+	struct icaltimetype icaltime;
+
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_YEARLY_RECURRENCE;
+	recurrence.interval = (pat->Period / 12);
+
+	if (rdfDaysBitmask & Su) {
+		recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & M) {
+		recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Tu) {
+		recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & W) {
+		recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Th) {
+		recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & F) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	if (rdfDaysBitmask & Sa) {
+		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
+		++idx;
+	}
+	recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	if (setpos == RecurrenceN_First) {
+		recurrence.by_set_pos[0] = 1;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Second) {
+		recurrence.by_set_pos[0] = 2;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Third) {
+		recurrence.by_set_pos[0] = 3;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Fourth) {
+		recurrence.by_set_pos[0] = 4;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	} else if (setpos == RecurrenceN_Last) {
+		recurrence.by_set_pos[0] = -1;
+		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	}
+
+	icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
+	recurrence.by_month[0] = icaltime.month;
+	recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
+	
+	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
+		recurrence.count = pat->OccurrenceCount;
+	}
+
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_RRULE(struct exchange2ical *exchange2ical)
+{
+	struct RecurrencePattern *pat;
+
+	/* Sanity check */
+	if (!(exchange2ical->RecurrencePattern)) return;
+
+	pat = exchange2ical->RecurrencePattern;
+
+	switch(pat->PatternType) {
+	case PatternType_Day:
+		ical_property_RRULE_Daily(exchange2ical);
+		break;
+	case PatternType_Week:
+		ical_property_RRULE_Weekly(exchange2ical);
+		break;
+	case PatternType_Month:
+		if ((pat->Period % 12 ) == 0) {
+			ical_property_RRULE_Yearly(exchange2ical);
+		} else {
+			ical_property_RRULE_Monthly(exchange2ical);
+		}
+		break;
+	case PatternType_MonthNth:
+		if ((pat->Period % 12 ) == 0) {
+			ical_property_RRULE_NthYearly(exchange2ical);
+		} else {
+			ical_property_RRULE_NthMonthly(exchange2ical);
+		}
+		break;
+	default:
+		printf("RRULE pattern type not implemented yet!:0x%x\n", pat->PatternType);
+	}
+}
+
+void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st)
+{
+	struct icalrecurrencetype recurrence;
+	icalproperty *prop;
+	
+	icalrecurrencetype_clear(&recurrence);
+	recurrence.freq = ICAL_YEARLY_RECURRENCE;
+
+	if(st.wYear ==0x0000){
+		recurrence.by_month[0]=st.wMonth;
+		/* Microsoft day of week = libIcal day of week +1; */
+		/* Day encode = day + occurrence*8 */
+		if (st.wDay==5){
+			/* Last occurrence of day in the month*/
+			recurrence.by_day[0] = -1 * (st.wDayOfWeek + 9);
+		}else{
+			/* st.wDay occurrence of day in the month */
+			recurrence.by_day[0] = (st.wDayOfWeek + 1 + st.wDay*8);
+		}
+		
+	}else{
+		recurrence.by_month_day[0]=st.wDay;
+		recurrence.by_month[0]=st.wMonth;
+	}
+
+	
+	prop = icalproperty_new_rrule(recurrence);
+	icalcomponent_add_property(component, prop);
+}
+
+
+void ical_property_RECURRENCE_ID(struct exchange2ical *exchange2ical)
+{	
+	struct icaltimetype	icaltime;
+	icalproperty 		*prop;
+	icalparameter		*tzid;
+	struct GlobalObjectId	*GlbObjId;
+
+	
+	if (exchange2ical->ExceptionReplaceTime){
+		/*if parent has an all day event*/
+ 		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			icaltime = get_icaldate_from_FILETIME(exchange2ical->ExceptionReplaceTime);
+			prop = icalproperty_new_recurrenceid(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+		} else {
+			if (exchange2ical->TimeZoneDesc) {
+				icaltime=get_icaltime_from_FILETIME(exchange2ical->ExceptionReplaceTime);
+				prop = icalproperty_new_recurrenceid(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			} else {
+				icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->ExceptionReplaceTime);
+				prop = icalproperty_new_recurrenceid(icaltime);
+				icalcomponent_add_property(exchange2ical->vevent, prop);
+			}
+		}
+	} else if (exchange2ical->GlobalObjectId){
+		GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
+		if(GlbObjId){
+			icaltime=get_icaldate_from_GlobalObjectId(GlbObjId);
+			prop = icalproperty_new_recurrenceid(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			talloc_free(GlbObjId);
+
+		}
+	}
+	
+}
+
+
+void ical_property_RESOURCES(struct exchange2ical *exchange2ical)
+{
+	char		*NonSendableBcc = NULL;
+	icalproperty 	*prop;
+
+	/* Sanity check */
+	if (!exchange2ical->NonSendableBcc) return;
+	
+	NonSendableBcc = talloc_strdup(exchange2ical->mem_ctx, exchange2ical->NonSendableBcc);
+	all_string_sub(NonSendableBcc, ";", ",", 0);
+	prop = icalproperty_new_resources(NonSendableBcc);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+	talloc_free(NonSendableBcc);
+}
+
+
+void ical_property_SEQUENCE(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	if (!exchange2ical->Sequence) {
+		prop = icalproperty_new_sequence(0);
+	} else {
+		prop = icalproperty_new_sequence(*(exchange2ical->Sequence));
+	}
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_SUMMARY(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	icalparameter *language;
+
+	if (exchange2ical->Subject) {
+		prop = icalproperty_new_summary(exchange2ical->Subject);
+	} else {
+		prop = icalproperty_new_summary("");
+	}
+
+	if (exchange2ical->MessageLocaleId) {
+		const char *langtag = mapi_get_locale_from_lcid( *(exchange2ical->MessageLocaleId) ); 
+		language = icalparameter_new_language( langtag );
+		icalproperty_add_parameter(prop, language);
+	}
+
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_TRANSP(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+
+	/* Sanity check */
+	if (!exchange2ical->BusyStatus) return;
+
+	switch (*exchange2ical->BusyStatus) {
+	case 0x00000000:
+		prop = icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT);
+		break;
+	case 0x00000001:
+	case 0x00000002:
+	case 0x00000003:
+		prop = icalproperty_new_transp(ICAL_TRANSP_OPAQUE);
+		break;
+	default:
+		prop = icalproperty_new_transp(ICAL_TRANSP_NONE);
+	}
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+void ical_property_TRIGGER(struct exchange2ical *exchange2ical)
+{
+	struct icaltriggertype duration;
+	icalproperty *prop;
+	if (!exchange2ical->ReminderDelta) return;
+	if (*exchange2ical->ReminderDelta == 0x5AE980E1) {
+		duration = icaltriggertype_from_int(-15 * 60);
+		prop = icalproperty_new_trigger(duration);
+		icalcomponent_add_property(exchange2ical->valarm, prop);
+	} else {
+		duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60);
+		prop = icalproperty_new_trigger(duration);
+		icalcomponent_add_property(exchange2ical->valarm, prop);
+	}
+}
+
+
+#define	GLOBAL_OBJECT_ID_DATA_START	"\x76\x43\x61\x6c\x2d\x55\x69\x64\x01\x00\x00\x00"
+
+void ical_property_UID(struct exchange2ical *exchange2ical)
+{
+	uint32_t		i;
+	const char		*uid;
+	char*			outstr;
+	struct GlobalObjectId	*GlbObjId;
+	icalproperty		*prop;
+
+	outstr = talloc_strdup(exchange2ical->mem_ctx, "uid");
+	
+	if(exchange2ical->GlobalObjectId){
+		GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
+	}
+	
+      
+	if (exchange2ical->GlobalObjectId && GlbObjId) {
+		if (GlbObjId->Size >= 12 && (0 == memcmp(GlbObjId->Data, GLOBAL_OBJECT_ID_DATA_START, 12))) {
+			fflush(0);
+			// TODO: could this code overrun GlobalObjectId->lpb?
+			// TODO: I think we should start at 12, not at zero...
+			for (i = 12; i < 52; i++) {
+				char objID[6];
+				snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
+				outstr = talloc_strdup_append(outstr, objID);
+			}
+
+			uid = (const char *)&(GlbObjId->Data[13]);
+			outstr = talloc_strdup_append(outstr, uid);
+		} else {
+			fflush(0);
+			for (i = 0; i < 16; i++) {
+				char objID[6];
+				snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
+				outstr = talloc_strdup_append(outstr, objID);
+			}
+			/* YH, YL, Month and D must be set to 0 */
+			outstr = talloc_strdup_append(outstr, "00000000");
+
+			for (i = 20; i < exchange2ical->GlobalObjectId->cb; i++) {
+				char objID[6];
+				snprintf(objID, 6, "%.2X", exchange2ical->GlobalObjectId->lpb[i]);
+				outstr = talloc_strdup_append(outstr, objID);
+			}
+		}
+		talloc_free(GlbObjId);
+	} else {
+		char objID[32];
+		snprintf(objID, 32, "%i", exchange2ical->idx);
+		outstr = talloc_strdup(outstr, objID);
+	}
+	
+	prop = icalproperty_new_uid(outstr);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+	talloc_free(outstr);
+}
+
+
+static icalproperty * ical_property_add_x_property_value(icalcomponent *parent, const char* propname, const char* value)
+{
+	icalproperty *prop;
+	icalvalue *icalText;
+
+	/* Sanity checks */
+	if (!parent) return NULL;
+	if (!propname) return NULL;
+	if (!value) return NULL;
+
+	icalText = icalvalue_new_text(value);
+	prop = icalproperty_new_x(icalvalue_as_ical_string(icalText));
+	icalvalue_free(icalText);
+	icalproperty_set_x_name(prop, propname);
+	icalcomponent_add_property(parent, prop);
+	return prop;
+}
+
+void ical_property_X_ALT_DESC(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	icalparameter *param;
+	
+	/*sanity check */
+	if(!exchange2ical->bodyHTML) return;
+	prop = ical_property_add_x_property_value(exchange2ical->vevent, "X-ALT-DESC",exchange2ical->bodyHTML);
+	param = icalparameter_new_fmttype("text/html");
+	icalproperty_add_parameter(prop, param);	
+}
+
+void ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
+{
+	struct tm	*tm;
+	char		outstr[200];
+
+	/* Sanity check */
+	if (!exchange2ical->AttendeeCriticalChange) return;
+
+	tm = get_tm_from_FILETIME(exchange2ical->AttendeeCriticalChange);
+	strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE", outstr);
+}
+
+
+void ical_property_X_MICROSOFT_CDO_BUSYSTATUS(struct exchange2ical *exchange2ical)
+{
+	/*sanity check*/
+	if(!exchange2ical->BusyStatus) return;
+	
+	switch (*exchange2ical->BusyStatus) {
+	case 0x00000000:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "FREE");
+		break;
+	case 0x00000001:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "TENTATIVE");
+		break;
+	case 0x00000002:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "BUSY");
+		break;
+	case 0x00000003:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-BUSYSTATUS", "OOF");
+		break;
+	}
+}
+void ical_property_X_MICROSOFT_MSNCALENDAR_IMPORTANCE(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->Importance) return;
+
+	switch (*exchange2ical->Importance) {
+	case 0x00000000:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "0");
+		break;
+	case 0x00000001:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "1");
+		break;
+	case 0x00000002:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-MSNCALENDAR-IMPORTANCE", "2");
+		break;
+	}
+}
+
+void ical_property_X_MICROSOFT_CDO_INTENDEDSTATUS(struct exchange2ical *exchange2ical)
+{
+	if (!exchange2ical->IntendedBusyStatus) return;
+
+	switch (*exchange2ical->IntendedBusyStatus) {
+	case 0x00000000:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "FREE");
+		break;
+	case 0x00000001:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "TENTATIVE");
+		break;
+	case 0x00000002:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "BUSY");
+		break;
+	case 0x00000003:
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-INTENDEDSTATUS", "OOF");
+		break;
+	}
+}
+
+
+void ical_property_X_MICROSOFT_CDO_OWNERAPPTID(struct exchange2ical *exchange2ical)
+{
+	char outstr[200];
+	/* Sanity check */
+	if (!exchange2ical->OwnerApptId) return;
+	snprintf(outstr, 200, "%d", *(exchange2ical->OwnerApptId));
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNERAPPTID", outstr);
+}
+
+
+void ical_property_X_MICROSOFT_CDO_OWNER_CRITICAL_CHANGE(struct exchange2ical *exchange2ical)
+{
+	struct tm	*tm;
+	char		outstr[200];
+	
+	/* Sanity check */
+	if (!exchange2ical->OwnerCriticalChange) return;
+
+
+	tm = get_tm_from_FILETIME(exchange2ical->OwnerCriticalChange);
+	
+
+	strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE", outstr);
+}
+
+
+void ical_property_X_MICROSOFT_CDO_REPLYTIME(struct exchange2ical *exchange2ical)
+{
+	struct tm	*tm;
+	char		outstr[200];
+
+	/* Sanity check */
+	if (!exchange2ical->apptReplyTime) return;
+
+	tm = get_tm_from_FILETIME(exchange2ical->apptReplyTime);
+	strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-CDO-REPLYTIME", outstr);
+}
+
+
+void ical_property_X_MICROSOFT_DISALLOW_COUNTER(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->NotAllowPropose) return;
+
+	if (*(exchange2ical->NotAllowPropose) == true) {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "TRUE");
+	} else {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-DISALLOW-COUNTER", "FALSE");
+	}
+}
+
+
+void ical_property_X_MS_OLK_ALLOWEXTERNCHECK(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->AllowExternCheck) return;
+
+	if (*(exchange2ical->AllowExternCheck) == true) {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "TRUE");
+	} else {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MICROSOFT-ALLOWEXTERNCHECK", "FALSE");
+	}
+}
+
+
+void ical_property_X_MS_OLK_APPTLASTSEQUENCE(struct exchange2ical *exchange2ical)
+{
+	char outstr[20];
+	/* Sanity check */
+	if (!exchange2ical->apptLastSequence) return;
+
+	snprintf(outstr, 20, "%d", *exchange2ical->apptLastSequence);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTLASTSEQUENCE", outstr);
+}
+
+
+void ical_property_X_MS_OLK_APPTSEQTIME(struct exchange2ical *exchange2ical)
+{
+	struct tm	*tm = NULL;
+	char		outstr[200];
+
+	/* Sanity check */
+	if (!exchange2ical->apptSeqTime) return;
+
+	tm = get_tm_from_FILETIME(exchange2ical->apptSeqTime);
+	strftime(outstr, sizeof(outstr), "%Y%m%dT%H%M%SZ", tm);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-APPTSEQTIME", outstr);
+}
+
+
+void ical_property_X_MS_OLK_AUTOFILLLOCATION(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->AutoFillLocation) return;
+
+	if (*(exchange2ical->AutoFillLocation) == true) {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "TRUE");
+	} else {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOFILLLOCATION", "FALSE");
+	}
+}
+
+
+void ical_property_X_MS_OLK_AUTOSTARTCHECK(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->AutoStartCheck) return;
+	if (*(exchange2ical->AutoStartCheck) == true) {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "TRUE");
+	} else {
+		ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-AUTOSTARTCHECK", "FALSE");
+	}
+}
+
+
+void ical_property_X_MS_OLK_COLLABORATEDOC(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->CollaborateDoc) return;
+	if(!(*exchange2ical->CollaborateDoc)) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-COLLABORATEDOC", exchange2ical->CollaborateDoc);
+}
+
+
+void ical_property_X_MS_OLK_CONFCHECK(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->ConfCheck) return;
+	
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFCHECK", (*exchange2ical->ConfCheck == true) ? "TRUE" : "FALSE");
+}
+
+
+void ical_property_X_MS_OLK_CONFTYPE(struct exchange2ical *exchange2ical)
+{
+	char outstr[20];
+	/* Sanity check */
+	if (!exchange2ical->ConfType) return;
+
+	snprintf(outstr, 20, "%d", *exchange2ical->ConfType);
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-CONFTYPE", outstr);
+}
+
+
+void ical_property_X_MS_OLK_DIRECTORY(struct exchange2ical *exchange2ical)
+{
+	/*Sanity Check*/
+	if(!exchange2ical->Directory) return;
+	if(!(*exchange2ical->Directory)) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-DIRECTORY", exchange2ical->Directory);
+}
+
+
+void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *exchange2ical)
+{
+	/*Sanity Check*/
+	if(!exchange2ical->MWSURL) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-MWSURL", exchange2ical->MWSURL);
+}
+
+
+void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *exchange2ical)
+{
+	/*Sanity Check*/
+	if(!exchange2ical->NetShowURL) return;
+	if(!(*exchange2ical->NetShowURL)) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-NETSHOWURL", exchange2ical->NetShowURL);
+}
+
+void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *exchange2ical)
+{
+	/*Sanity Check*/
+	if(!exchange2ical->OnlinePassword) return;
+	if(!(*exchange2ical->OnlinePassword)) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ONLINEPASSWORD", exchange2ical->OnlinePassword);
+}
+
+void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if(!exchange2ical->OrgAlias) return;
+	if(!(*exchange2ical->OrgAlias)) return;
+
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ORGALIAS", exchange2ical->OrgAlias);
+}
+
+
+// TODO: double check this - need an example.
+void ical_property_X_MS_OLK_SENDER(struct exchange2ical *exchange2ical)
+{
+	icalproperty *prop;
+	icalparameter *param;
+	char outstr[200];
+
+	/* Sanity check */
+	if (!exchange2ical->apptStateFlags) return;
+	if (!(*exchange2ical->apptStateFlags & 0x1)) return;
+	if (!exchange2ical->SenderName) return;
+
+	if (exchange2ical->SenderEmailAddress) {
+		snprintf(outstr, 200, "mailto:%s",exchange2ical->SenderEmailAddress);
+		prop = icalproperty_new_x(outstr);
+	} else {
+		prop = icalproperty_new_x("invalid:nomail");
+	}
+
+	icalproperty_set_x_name(prop, "X-MS-OLK-SENDER");
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+
+	param = icalparameter_new_cn(exchange2ical->SenderName);
+	icalproperty_add_parameter(prop, param);
+}

Added: trunk/openchange/libexchange2ical/exchange2ical_utils.c
===================================================================
--- trunk/openchange/libexchange2ical/exchange2ical_utils.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/exchange2ical_utils.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,587 @@
+/*
+   Common conversion routines for exchange2ical
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+static struct ical_method	ical_method[] = {
+	{ ICAL_METHOD_PUBLISH,	ICAL_PARTSTAT_NONE,	"IPM.Appointment"		},
+	{ ICAL_METHOD_REQUEST,	ICAL_PARTSTAT_NONE,	"IPM.Schedule.Meeting.Request"	},
+	{ ICAL_METHOD_REPLY,	ICAL_PARTSTAT_ACCEPTED,	"IPM.Schedule.Meeting.Resp.Pos" },
+	{ ICAL_METHOD_REPLY,	ICAL_PARTSTAT_TENTATIVE,"IPM.Schedule.Meeting.Resp.Tent"},
+	{ ICAL_METHOD_REPLY,	ICAL_PARTSTAT_DECLINED,	"IPM.Schedule.Meeting.Resp.Neg"	},
+	{ ICAL_METHOD_CANCEL,	ICAL_PARTSTAT_NONE,	"IPM.Schedule.Meeting.Canceled" },
+	{ ICAL_METHOD_NONE,	ICAL_PARTSTAT_NONE,	NULL }
+};
+
+static struct ical_calendartype	ical_calendartype[] = {
+	{ 0x0001,	"Gregorian"		},
+	{ 0x0002,	"Gregorian_us"		},
+	{ 0x0003,	"Japan"			},
+	{ 0x0004,	"Taiwan"		},
+	{ 0x0005,	"Korean"		},
+	{ 0x0006,	"Hijri"			},
+	{ 0x0007,	"Thai"			},
+	{ 0x0008,	"Hebrew"		},
+	{ 0x0009,	"GregorianMeFrench"	},
+	{ 0x000A,	"GregorianArabic"	},
+	{ 0x000B,	"GregorianXlitEnglish"	},
+	{ 0x000C,	"GregorianXlitFrench"	},
+	{ 0x000E,	"JapanLunar"		},
+	{ 0x000F,	"ChineseLunar"		},
+	{ 0x0010,	"Saka"			},
+	{ 0x0011,	"LunarEtoChn"		},
+	{ 0x0012,	"LunarEthoKor"		},
+	{ 0x0013,	"LunarRockuyou"		},
+	{ 0x0014,	"KoreanLunar"		},
+	{ 0x0017,	"Umalqura"		},
+	{ 0x0000,	NULL			}
+};
+
+static struct ical_class	ical_class[] = {
+	{ 0x00000000,	ICAL_CLASS_PUBLIC	},
+	{ 0x00000001,	ICAL_CLASS_X		},
+	{ 0x00000002,	ICAL_CLASS_PRIVATE	},
+	{ 0x00000003,	ICAL_CLASS_CONFIDENTIAL	},
+	{ 0x00000000,	ICAL_CLASS_NONE		}
+};
+
+static struct ical_day	ical_day[] = {
+	{ ICAL_SUNDAY_WEEKDAY,		FirstDOW_Sunday, 	Su },
+	{ ICAL_MONDAY_WEEKDAY,		FirstDOW_Monday,	M  },
+	{ ICAL_TUESDAY_WEEKDAY,		FirstDOW_Tuesday,	Tu },
+	{ ICAL_WEDNESDAY_WEEKDAY,	FirstDOW_Wednesday, 	W  },
+	{ ICAL_THURSDAY_WEEKDAY,	FirstDOW_Thursday,	Th },
+	{ ICAL_FRIDAY_WEEKDAY,		FirstDOW_Friday,	F  },
+	{ ICAL_SATURDAY_WEEKDAY,	FirstDOW_Saturday,	Sa },
+	{ ICAL_NO_WEEKDAY,		0,			0 }
+
+};
+
+bool has_component_DAYLIGHT(struct exchange2ical *exchange2ical)
+{
+	if (!exchange2ical->TimeZoneStruct) return false;
+	if (!exchange2ical->TimeZoneStruct->stStandardDate.wYear &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wMonth &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wDayOfWeek &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wDay &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wHour &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wMinute &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wSecond &&
+	    !exchange2ical->TimeZoneStruct->stStandardDate.wMilliseconds) return false;
+
+	return true;
+}
+
+struct FILETIME get_FILETIME_from_string(const char *time)
+{
+	icaltimetype icaltime;
+	
+	icaltime = icaltime_from_string(time);
+	return get_FILETIME_from_icaltimetype(&icaltime);
+}
+
+
+char *get_ical_date(TALLOC_CTX *mem_ctx, struct SYSTEMTIME *time)
+{
+	char	*date;
+
+	date = talloc_asprintf(mem_ctx, "%.4d%.2d%.2dT%.2d%.2d%.2d", time->wYear + 1601, time->wMonth,
+			       time->wDay, time->wHour, time->wMinute, time->wSecond);
+	return date;
+}
+
+
+enum icalproperty_method get_ical_method(const char *msgclass)
+{
+	uint32_t	i;
+
+	/* Sanity check */
+	if (!msgclass) return ICAL_METHOD_NONE;
+
+	for (i = 0; ical_method[i].PidTagMessageClass; i++) {
+		if (!strcmp(msgclass, ical_method[i].PidTagMessageClass)) {
+			return ical_method[i].method;
+		}
+	}
+
+	return ICAL_METHOD_NONE;
+}
+
+uint16_t get_exchange_calendartype(const char *CalendarType)
+{
+	uint32_t	i;
+
+	/* Sanity check */
+	if (!CalendarType) return 0x0000;
+
+	for (i = 0; ical_calendartype[i].type; i++) {
+		if (strcmp(CalendarType, ical_calendartype[i].calendar)) {
+			return ical_calendartype[i].type;
+		}
+	}
+	return 0x0000;
+}
+
+const char *get_ical_calendartype(uint16_t CalendarType)
+{
+	uint32_t	i;
+
+	/* Sanity check */
+	if (!CalendarType) return NULL;
+
+	for (i = 0; ical_calendartype[i].type; i++) {
+		if (CalendarType == ical_calendartype[i].type) {
+			return ical_calendartype[i].calendar;
+		}
+	}
+	
+	return NULL;
+}
+enum icalparameter_partstat get_ical_partstat_from_status(uint32_t status)
+{
+	enum icalparameter_partstat partstat;
+	switch(status){
+		case 0x00000003:
+			partstat = ICAL_PARTSTAT_ACCEPTED;
+			break;
+		case 0x00000004:
+			partstat = ICAL_PARTSTAT_DECLINED;
+			break;
+		case 0x00000002:
+			partstat = ICAL_PARTSTAT_TENTATIVE;
+			break;
+		default:
+			partstat = ICAL_PARTSTAT_NONE;
+	}
+	return partstat;
+}
+
+enum icalparameter_partstat get_ical_partstat(const char *msgclass)
+{
+	uint32_t	i;
+
+	/* Sanity check */
+	if (!msgclass) return ICAL_PARTSTAT_NONE;
+
+	for (i = 0; ical_method[i].PidTagMessageClass; i++) {
+		if (!strcmp(msgclass, ical_method[i].PidTagMessageClass)) {
+			return ical_method[i].partstat;
+		}
+	}
+
+	return ICAL_PARTSTAT_NONE;
+}
+
+enum icalproperty_class get_ical_class(uint32_t sensivity)
+{
+	uint32_t	i;
+	
+	for (i = 0; ical_class[i].classtype != ICAL_CLASS_NONE; ++i) {
+		if (sensivity == ical_class[i].sensivity) {
+			return ical_class[i].classtype;
+		}
+	}
+
+	return ICAL_CLASS_NONE;
+}
+
+enum FirstDOW get_exchange_day_from_ical(enum icalrecurrencetype_weekday weekday)
+{
+	
+	uint32_t	i;
+	
+	for (i = 0; ical_day[i].ical != ICAL_NO_WEEKDAY; ++i) {
+		if (weekday == ical_day[i].ical) {
+			return ical_day[i].exchange;
+		}
+	}
+
+	return 0x00000000;
+}
+
+uint32_t get_exchange_rdfDays_from_ical(enum icalrecurrencetype_weekday weekday){
+	
+	uint32_t	i;
+	
+	for (i = 0; ical_day[i].ical != ICAL_NO_WEEKDAY; ++i) {
+		if (weekday == ical_day[i].ical) {
+			return ical_day[i].rdfDays;
+		}
+	}
+
+	return 0;
+}
+
+struct icaltimetype get_icaltimetype_from_tm(struct tm *tm)
+{
+	struct icaltimetype tt;
+
+	tt.year   = tm->tm_year+1900;
+	tt.month  = tm->tm_mon+1;
+	tt.day    = tm->tm_mday;
+	tt.hour   = tm->tm_hour;
+	tt.minute = tm->tm_min;
+	tt.second = tm->tm_sec;
+
+	tt.is_utc      = 0;
+	tt.is_date     = 0;
+	tt.is_daylight = 0;
+	tt.zone        = 0;
+
+	return tt;
+}
+
+struct icaltimetype get_icaltimetype_from_tm_UTC(struct tm *tm)
+{
+	struct icaltimetype tt;
+	
+	tt = get_icaltimetype_from_tm(tm);
+	tt.is_utc      = 1;
+	
+	return tt;
+}
+
+struct icaltimetype get_icaldate_from_tm(struct tm *tm)
+{
+	struct icaltimetype tt;
+
+	tt.year   = tm->tm_year+1900;
+	tt.month  = tm->tm_mon+1;
+	tt.day    = tm->tm_mday;
+	tt.hour   = 0;
+	tt.minute = 0;
+	tt.second = 0;
+
+	tt.is_utc      = 1;
+	tt.is_date     = 1;
+	tt.is_daylight = 0;
+	tt.zone        = NULL;
+
+	return tt;
+}
+
+struct tm *get_tm_from_FILETIME(const struct FILETIME *ft)
+{
+	NTTIME		time;
+	struct timeval	t;
+	struct tm	*tm;
+	
+	time = FILETIME_to_NTTIME(*ft);
+	nttime_to_timeval(&t, time);
+	tm = localtime(&t.tv_sec);
+
+	return tm;
+}
+
+struct icaltimetype get_icaltime_from_FILETIME(const struct FILETIME *ft)
+{
+	struct icaltimetype	tt;
+	NTTIME			nttime;
+	struct timeval		temp_timeval;
+	struct tm		*tm;
+
+	nttime = FILETIME_to_NTTIME(*ft);
+	nttime_to_timeval(&temp_timeval, nttime);
+	
+	tm = localtime(&temp_timeval.tv_sec);
+	
+	tt.year   = tm->tm_year + 1900;                                        
+	tt.month  = tm->tm_mon + 1;                                            
+	tt.day    = tm->tm_mday;                                               
+	tt.hour   = tm->tm_hour;                                               
+	tt.minute = tm->tm_min;                                                
+	tt.second = tm->tm_sec;
+	tt.is_date = 0;
+	tt.is_utc = 0;
+	tt.is_daylight = 0;
+	tt.zone = NULL;
+
+	return tt;
+}
+
+struct icaltimetype get_icaltime_from_FILETIME_UTC(const struct FILETIME *ft)
+{
+	struct icaltimetype	tt;
+	NTTIME			nttime;
+	struct timeval		temp_timeval;
+	struct tm		*tm;
+
+	nttime = FILETIME_to_NTTIME(*ft);
+	nttime_to_timeval(&temp_timeval, nttime);
+
+	tm = gmtime(&temp_timeval.tv_sec);
+	
+	tt.year   = tm->tm_year + 1900;                                        
+	tt.month  = tm->tm_mon + 1;                                            
+	tt.day    = tm->tm_mday;                                               
+	tt.hour   = tm->tm_hour;                                               
+	tt.minute = tm->tm_min;                                                
+	tt.second = tm->tm_sec;
+	tt.is_date = 0;
+	tt.is_utc = 1;
+	tt.is_daylight = 0;
+	tt.zone = NULL;
+
+	return tt;
+}
+
+struct icaltimetype get_icaldate_from_FILETIME(const struct FILETIME *ft)
+{
+	struct icaltimetype	tt;
+	NTTIME			nttime;
+	struct timeval		temp_timeval;
+	struct tm		*tm;
+
+	nttime = FILETIME_to_NTTIME(*ft);
+	nttime_to_timeval(&temp_timeval, nttime);
+
+	tm = gmtime(&temp_timeval.tv_sec);
+                                                                 
+	tt.year   = tm->tm_year + 1900;                                        
+	tt.month  = tm->tm_mon + 1;                                            
+	tt.day    = tm->tm_mday;
+	if (tm->tm_hour >= 12) {
+		/* If the time is greater than or equal to 12, and we're representing midnight, then
+		the actual day is one less (e.g. if we're at UTC+11 timezone, then local
+		midnight is 1300 UTC, on the day before). So we add a day. */
+		tt.day++;
+	}
+	tt.hour   = 0;                                               
+	tt.minute = 0;                                                
+	tt.second = 0;
+	tt.is_date = 1;
+	tt.is_utc = 1;
+	tt.is_daylight = 0;
+	tt.zone = NULL;
+
+	return tt;
+}
+
+struct icaltimetype get_icaldate_from_GlobalObjectId(struct GlobalObjectId *GlobalObjectId)
+{
+	struct icaltimetype	tt;
+	tt.year   = GlobalObjectId->YH;
+	tt.year   = tt.year <<8;
+	tt.year   |= GlobalObjectId->YL;
+	tt.month  = GlobalObjectId->Month;
+	tt.day    = GlobalObjectId->D;
+	tt.hour   = 0;
+	tt.minute = 0;
+	tt.second = 0;
+
+	tt.is_utc      = 1;
+	tt.is_date     = 1;
+	tt.is_daylight = 0;
+	tt.zone        = NULL;
+
+	return tt;
+}
+
+struct tm get_tm_from_minutes(uint32_t mins)
+{
+	struct timeval	t;
+	struct tm	tm;
+	NTTIME		nt;
+	nt = mins;
+	nt *= 10000000;
+	nt *= 60;
+	nttime_to_timeval(&t, nt);
+	tm= *localtime(&t.tv_sec);
+	return tm;
+}
+
+struct tm get_tm_from_minutes_UTC(uint32_t mins)
+{
+	struct timeval	t;
+	struct tm	tm;
+	NTTIME		nt;
+	nt = mins;
+	nt *= 10000000;
+	nt *= 60;
+	nttime_to_timeval(&t, nt);
+	tm= *gmtime(&t.tv_sec);
+	return tm;
+}
+
+bool compareGlobalObjectIds(struct GlobalObjectId *glb1, struct GlobalObjectId *glb2)
+{
+	int i;
+	time_t creationTime1;
+	time_t creationTime2;
+	
+	
+	creationTime1=mktime(get_tm_from_FILETIME(&glb1->CreationTime));
+	creationTime2=mktime(get_tm_from_FILETIME(&glb2->CreationTime));
+	
+	if(difftime(creationTime1, creationTime2)!=0) return false;
+	
+	for(i=0; i<16; i++){
+		if(glb1->ByteArrayID[i]!=glb2->ByteArrayID[i]) return false;
+	}
+	if(glb1->YH!=glb2->YH) return false;
+	if(glb1->YL!=glb2->YL) return false;
+	if(glb1->Month!=glb2->Month) return false;
+	if(glb1->D!=glb2->D) return false;
+	
+	for(i=0; i<8; i++){
+		if(glb1->X[i]!=glb2->X[i]) return false;
+	}
+	if(glb1->Size!=glb2->Size) return false;
+	for(i=0; i<glb1->Size; i++){
+		if(glb1->Data[i]!=glb2->Data[i]) return false;
+	}
+	return true;
+}
+
+
+
+bool checkEvent(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check, struct tm *aptStart)
+{
+	time_t beginTime;
+	time_t endTime;
+	time_t dtstart;
+	struct GlobalObjectId	*GlbObjId;
+	enum exchange2ical_flags eFlags= exchange2ical_check->eFlags;
+
+	if(eFlags & EntireFlag) return true;
+		
+	if(eFlags & RangeFlag){
+		dtstart = mktime(aptStart);
+		if(dtstart==-1) return false;
+		if(exchange2ical_check->begin){
+			beginTime=mktime(exchange2ical_check->begin);
+			if(beginTime!=-1){
+				if(difftime(dtstart, beginTime)<0){
+					return false;
+				}
+			}
+		}
+		if(exchange2ical_check->end){
+			endTime=mktime(exchange2ical_check->end);
+			if(endTime!=-1){
+				if(difftime(endTime, dtstart)<0){
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+	
+	if(eFlags & EventFlag){
+		if(!exchange2ical->Sequence) return false;
+		GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
+		if(!GlbObjId || !exchange2ical_check->GlobalObjectId) return false;
+		if (!compareGlobalObjectIds(GlbObjId, exchange2ical_check->GlobalObjectId)) return false;
+		if(*exchange2ical->Sequence != exchange2ical_check->Sequence) return false;
+		talloc_free(GlbObjId);
+		return true;
+	}
+	
+	if(eFlags & EventsFlag){
+		GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
+		if(!GlbObjId || !exchange2ical_check->GlobalObjectId) return false;
+		if (!compareGlobalObjectIds(GlbObjId, exchange2ical_check->GlobalObjectId)) return false;
+		talloc_free(GlbObjId);
+		return true;
+	}
+	
+	return false;
+}
+
+
+
+#define WIN32_UNIX_EPOCH_DIFF 194074560
+
+uint32_t get_minutes_from_icaltimetype(icaltimetype icaltime)
+{
+	struct tm		tm;
+	time_t			time;
+	NTTIME			nttime;
+	struct timeval 		t;
+	
+	tm.tm_year	= icaltime.year - 1900;
+	tm.tm_mon 	= icaltime.month - 1;
+	tm.tm_mday	= icaltime.day;
+	tm.tm_hour	= icaltime.hour;
+	tm.tm_min	= icaltime.minute;
+	tm.tm_sec	= icaltime.second;
+	tm.tm_isdst	= 0;
+
+	/* TODO: fix this properly when we implement ical2exchange */
+#if !defined(__FreeBSD__)
+ 	if(timezone!=0){
+ 		tm.tm_hour-=timezone/3600;
+ 	}
+#endif
+	time = mktime(&tm);
+	unix_to_nt_time(&nttime, time);
+	nttime_to_timeval(&t, nttime);
+	
+	return t.tv_sec/60+WIN32_UNIX_EPOCH_DIFF;
+	
+}
+
+
+struct FILETIME get_FILETIME_from_icaltimetype(icaltimetype *tt)
+{
+	struct FILETIME		ft;
+	struct tm		tm;
+	time_t			time;
+	NTTIME			nttime;
+	
+	tm.tm_year	= tt->year - 1900;
+	tm.tm_mon 	= tt->month - 1;
+	tm.tm_mday	= tt->day;
+	tm.tm_hour	= tt->hour;
+	tm.tm_min	= tt->minute;
+	tm.tm_sec	= tt->second;
+	tm.tm_isdst	= 0;
+
+	/* TODO: fix this properly when we implement ical2exchange */
+#if !defined(__FreeBSD__)
+ 	if(timezone!=0){
+ 		tm.tm_hour-=timezone/3600;
+ 	}
+#endif
+	time = mktime(&tm);
+	unix_to_nt_time(&nttime, time);
+	
+	ft.dwHighDateTime=(uint32_t) (nttime>>32);
+	ft.dwLowDateTime=(uint32_t) (nttime);
+	
+	return ft;
+}
+
+
+NTTIME FILETIME_to_NTTIME(struct FILETIME ft)
+{
+	NTTIME nt;
+	nt = ft.dwHighDateTime;
+	nt = nt << 32;
+	nt |= ft.dwLowDateTime;
+	return nt;
+}
+
+int compare_minutes(const void *min1, const void *min2)
+{
+	if( *(uint32_t *) min1 > * (uint32_t *) min2) return -1;
+	return 1;
+}

Added: trunk/openchange/libexchange2ical/ical2exchange.c
===================================================================
--- trunk/openchange/libexchange2ical/ical2exchange.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/ical2exchange.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,381 @@
+/*
+   Common conversion routines for exchange2ical
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+static void ical2exchange_get_properties(struct ical2exchange *ical2exchange, icalcomponent *vevent){
+	icalproperty *icalProp = NULL;
+	icalproperty *prop = NULL;
+	const char *xname;
+	enum icalproperty_kind propType;
+
+	icalProp=icalcomponent_get_first_property(vevent, ICAL_ANY_PROPERTY);
+	
+	while(icalProp!=0){
+		propType=icalproperty_isa(icalProp);
+		switch (propType){
+			case ICAL_ATTACH_PROPERTY:
+				if(!ical2exchange->attachEvent){
+					ical2exchange->attachEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				icalcomponent_add_property(ical2exchange->attachEvent, prop);
+				break;
+			case ICAL_ATTENDEE_PROPERTY:
+				if(!ical2exchange->attendeeEvent){
+					ical2exchange->attendeeEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				icalcomponent_add_property(ical2exchange->attendeeEvent, prop);
+				break;
+			case ICAL_CATEGORIES_PROPERTY:
+				if(!ical2exchange->categoriesEvent){
+					ical2exchange->categoriesEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				icalcomponent_add_property(ical2exchange->categoriesEvent, prop);
+				break;
+			case ICAL_CLASS_PROPERTY:
+				ical2exchange->classProp=icalProp;
+				break;
+			case ICAL_COMMENT_PROPERTY:
+				ical2exchange->commentProp=icalProp;
+				break;
+			case ICAL_CONTACT_PROPERTY:
+				if(!ical2exchange->contactEvent){
+					ical2exchange->contactEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				icalcomponent_add_property(ical2exchange->contactEvent, prop);
+				break;
+			case ICAL_CREATED_PROPERTY:
+				break;
+			case ICAL_DESCRIPTION_PROPERTY:
+				ical2exchange->descriptionProp=icalProp;
+				break;
+			case ICAL_DTEND_PROPERTY:
+				ical2exchange->dtendProp=icalProp;
+				break;
+			case ICAL_DTSTAMP_PROPERTY:
+				ical2exchange->dtstampProp=icalProp;
+				break;
+			case ICAL_DTSTART_PROPERTY:
+				ical2exchange->dtstartProp=icalProp;
+				break;
+			case ICAL_DURATION_PROPERTY:
+				ical2exchange->durationProp=icalProp;
+				break;
+			case ICAL_EXDATE_PROPERTY:
+				if(!ical2exchange->exdateEvent){
+					ical2exchange->exdateEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				ical2exchange->exdateCount ++;
+				icalcomponent_add_property(ical2exchange->exdateEvent, prop);
+				break;
+			case ICAL_LASTMODIFIED_PROPERTY:
+				break;
+			case ICAL_LOCATION_PROPERTY:
+				ical2exchange->locationProp=icalProp;
+				break;
+			case ICAL_ORGANIZER_PROPERTY:
+				//TODO: figure out how to MS-OXOABK
+				ical2exchange->organizerProp=icalProp;
+				break;
+			case ICAL_PRIORITY_PROPERTY:
+				ical2exchange->priorityProp=icalProp;
+				break;
+			case ICAL_RDATE_PROPERTY:
+				if(!ical2exchange->rdateEvent){
+					ical2exchange->rdateEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				ical2exchange->rdateCount ++;
+				icalcomponent_add_property(ical2exchange->rdateEvent, prop);
+				break;
+			case ICAL_RECURRENCEID_PROPERTY:
+				ical2exchange->recurrenceidProp=icalProp;
+				break;
+			case ICAL_RESOURCES_PROPERTY:
+				if(!ical2exchange->resourcesEvent){
+					ical2exchange->resourcesEvent=icalcomponent_new_vevent();
+				}
+				prop = icalproperty_new_clone(icalProp);
+				icalcomponent_add_property(ical2exchange->resourcesEvent, prop);
+				break;
+			case ICAL_RRULE_PROPERTY:
+				ical2exchange->rruleProp=icalProp;
+				break;
+			case ICAL_SEQUENCE_PROPERTY:
+				ical2exchange->sequenceProp=icalProp;
+				break;
+			case ICAL_STATUS_PROPERTY:
+				ical2exchange->statusProp=icalProp;
+				break;
+			case ICAL_SUMMARY_PROPERTY:
+				ical2exchange->summaryProp=icalProp;
+				break;
+			case ICAL_TRANSP_PROPERTY:
+				ical2exchange->transpProp=icalProp;
+				break;
+			case ICAL_UID_PROPERTY:
+				//TODO
+				ical2exchange->uidProp=icalProp;
+				break;
+		 	case ICAL_X_PROPERTY: 
+				xname=icalproperty_get_x_name(icalProp);
+				if(!strcmp(xname,"X-MICROSOFT-CDO-BUSYSTATUS")){
+					ical2exchange->x_busystatusProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-BUSYSTATUS")){
+					ical2exchange->x_busystatusProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-APPT-SEQUENCE")){
+					ical2exchange->x_sequenceProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-IMPORTANCE")){
+					ical2exchange->x_importanceProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-IMPORTANCE")){
+					ical2exchange->x_importanceProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-INTENDEDSTATUS")){
+					ical2exchange->x_intendedProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-INTENDEDSTATUS")){
+					ical2exchange->x_intendedProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNERAPPTID")){
+					ical2exchange->x_ownerapptidProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE")){
+					ical2exchange->x_attendeecriticalchangeProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE")){
+					ical2exchange->x_ownercriticalchangeProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-CDO-REPLYTIME")){
+					ical2exchange->x_replytimeProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-DISALLOW-COUNTER")){
+					ical2exchange->x_disallowcounterProp=icalProp;
+				} else if(!strcmp(xname,"X-MICROSOFT-ISDRAFT")){
+					ical2exchange->x_isdraftProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-ALLOWEXTERNCHECK")){
+					ical2exchange->x_allowexterncheckProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-APPTLASTSEQUENCE")){
+					ical2exchange->x_apptlastsequenceProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-APPTSEQTIME")){
+					ical2exchange->x_apptseqtimeProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-AUTOFILLLOCATION")){
+					ical2exchange->x_autofilllocationProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-AUTOSTARTCHECK")){
+					ical2exchange->x_autostartcheckProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-CONFCHECK")){
+					ical2exchange->x_confcheckProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-COLLABORATEDDOC")){
+					ical2exchange->x_collaborateddocProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-CONFTYPE")){
+					ical2exchange->x_conftypeProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-MWSURL")){
+					ical2exchange->x_mwsurlProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-NETSHOWURL")){
+					ical2exchange->x_netshowurlProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-ONLINEPASSWORD")){
+					ical2exchange->x_onlinepasswordProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-ORGALIAS")){
+					ical2exchange->x_orgaliasProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-ORIGINALEND")){
+					ical2exchange->x_originalendProp=icalProp;
+				} else if(!strcmp(xname,"X-MS-OLK-ORIGINALSTART")){
+					ical2exchange->x_originalstartProp=icalProp;
+				}
+				
+				break;
+			default:
+				break;
+		}
+		icalProp=icalcomponent_get_next_property(vevent, ICAL_ANY_PROPERTY);
+	}
+	
+	ical2exchange->valarmEvent = icalcomponent_get_first_component(vevent,ICAL_VALARM_COMPONENT);
+	
+}
+
+static void ical2exchange_convert_event(struct ical2exchange *ical2exchange)
+{
+	ical2exchange_property_ATTACH(ical2exchange);
+// 	//TODO ATTENDEE, ORGANIZER, x_ms_ok_sender
+	ical2exchange_property_CATEGORIES(ical2exchange);
+	ical2exchange_property_CLASS(ical2exchange);
+	ical2exchange_property_COMMENT(ical2exchange);
+	ical2exchange_property_CONTACT(ical2exchange);
+	ical2exchange_property_DESCRIPTION(ical2exchange);
+	ical2exchange_property_DTSTAMP(ical2exchange);
+	ical2exchange_property_DTSTART_DTEND(ical2exchange);
+	ical2exchange_property_LOCATION(ical2exchange);
+	ical2exchange_property_PRIORITY(ical2exchange);
+	ical2exchange_property_RRULE_EXDATE_RDATE(ical2exchange);
+	ical2exchange_property_SEQUENCE(ical2exchange);
+	ical2exchange_property_STATUS(ical2exchange);
+	ical2exchange_property_SUMMARY(ical2exchange);
+	ical2exchange_property_VALARM(ical2exchange);
+	ical2exchange_property_X_ALLOWEXTERNCHECK(ical2exchange);
+	ical2exchange_property_X_APPTSEQTIME(ical2exchange);
+	ical2exchange_property_X_APPTLASTSEQUENCE(ical2exchange);
+	ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(ical2exchange);
+	ical2exchange_property_X_AUTOFILLLOCATION(ical2exchange);
+	ical2exchange_property_X_AUTOSTARTCHECK(ical2exchange);
+	ical2exchange_property_X_COLLABORATEDDOC(ical2exchange);
+	ical2exchange_property_X_CONFCHECK(ical2exchange);
+	ical2exchange_property_X_CONFTYPE(ical2exchange);
+	ical2exchange_property_X_DISALLOW_COUNTER(ical2exchange);
+	ical2exchange_property_X_INTENDEDSTATUS(ical2exchange);
+	ical2exchange_property_X_ISDRAFT(ical2exchange);
+	ical2exchange_property_X_MWSURL(ical2exchange);
+	ical2exchange_property_X_NETSHOWURL(ical2exchange);
+	ical2exchange_property_X_ONLINEPASSWORD(ical2exchange);
+	ical2exchange_property_X_ORGALIAS(ical2exchange);
+	ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(ical2exchange);
+	ical2exchange_property_X_OWNER_CRITICAL_CHANGE(ical2exchange);
+	ical2exchange_property_X_OWNERAPPTID(ical2exchange);
+	ical2exchange_property_X_REPLYTIME(ical2exchange);
+}
+
+static void ical2exchange_init(struct ical2exchange *ical2exchange, TALLOC_CTX *mem_ctx)
+{
+	ical2exchange->mem_ctx = mem_ctx;
+	ical2exchange->classProp = NULL;
+	ical2exchange->commentProp = NULL;
+	ical2exchange->descriptionProp = NULL;
+	ical2exchange->dtendProp = NULL;
+	ical2exchange->dtstampProp = NULL;
+	ical2exchange->dtstartProp = NULL;
+	ical2exchange->durationProp = NULL;
+	ical2exchange->locationProp = NULL;
+	ical2exchange->organizerProp = NULL;
+	ical2exchange->priorityProp = NULL;
+	ical2exchange->recurrenceidProp = NULL;
+	ical2exchange->rruleProp = NULL;
+	ical2exchange->sequenceProp = NULL;
+	ical2exchange->statusProp = NULL;
+	ical2exchange->summaryProp = NULL;
+	ical2exchange->transpProp = NULL;
+	ical2exchange->uidProp = NULL;
+	ical2exchange->attachEvent = NULL;
+	ical2exchange->attendeeEvent = NULL;
+	ical2exchange->categoriesEvent = NULL;
+	ical2exchange->contactEvent = NULL;
+	ical2exchange->exdateEvent = NULL;
+	ical2exchange->rdateEvent = NULL;
+	ical2exchange->resourcesEvent = NULL;
+	ical2exchange->valarmEvent = NULL;
+	ical2exchange->x_busystatusProp = NULL;
+	ical2exchange->x_sequenceProp = NULL;
+	ical2exchange->x_importanceProp = NULL;
+	ical2exchange->x_intendedProp= NULL;
+	ical2exchange->x_ownerapptidProp = NULL;
+	ical2exchange->x_attendeecriticalchangeProp = NULL;
+	ical2exchange->x_ownercriticalchangeProp = NULL;
+	ical2exchange->x_replytimeProp = NULL;
+	ical2exchange->x_disallowcounterProp = NULL;
+	ical2exchange->x_isdraftProp = NULL;
+	ical2exchange->x_allowexterncheckProp = NULL;
+	ical2exchange->x_apptlastsequenceProp = NULL;
+	ical2exchange->x_apptseqtimeProp = NULL;
+	ical2exchange->x_autofilllocationProp = NULL;
+	ical2exchange->x_autostartcheckProp = NULL;
+	ical2exchange->x_confcheckProp = NULL;
+	ical2exchange->x_collaborateddocProp = NULL;
+	ical2exchange->x_conftypeProp = NULL;
+	ical2exchange->x_mwsurlProp = NULL;
+	ical2exchange->x_netshowurlProp = NULL;
+	ical2exchange->x_onlinepasswordProp = NULL;
+	ical2exchange->x_originalstartProp = NULL;
+	ical2exchange->x_originalendProp = NULL;
+	ical2exchange->x_orgaliasProp = NULL;
+	
+	ical2exchange->lpProps = NULL;
+	ical2exchange->rdateCount = 0 ;
+	ical2exchange->exdateCount = 0;
+	ical2exchange->cValues = 0;
+	
+}
+
+static void ical2exchange_reset(struct ical2exchange *ical2exchange)
+{
+	if(ical2exchange->attachEvent){
+		icalcomponent_free(ical2exchange->attachEvent);
+	}
+	if(ical2exchange->attendeeEvent){
+		icalcomponent_free(ical2exchange->attendeeEvent);
+	}
+
+	if(ical2exchange->contactEvent){
+		icalcomponent_free(ical2exchange->contactEvent);
+	}
+	if(ical2exchange->exdateEvent){
+		icalcomponent_free(ical2exchange->exdateEvent);
+	}
+	if(ical2exchange->rdateEvent){
+		icalcomponent_free(ical2exchange->rdateEvent);
+	}
+	if(ical2exchange->resourcesEvent){
+		icalcomponent_free(ical2exchange->resourcesEvent);
+	}
+	if(ical2exchange->categoriesEvent){
+		icalcomponent_free(ical2exchange->categoriesEvent);
+	}
+	ical2exchange_init(ical2exchange, NULL);
+}
+
+void _IcalEvent2Exchange(mapi_object_t *obj_folder, icalcomponent *vevent)
+{
+	struct ical2exchange ical2exchange;
+	TALLOC_CTX	*mem_ctx;
+	enum MAPISTATUS			retval;
+	mapi_object_t		obj_message;
+	ical2exchange.obj_message = &obj_message;
+
+	ical2exchange.method=ICAL_METHOD_PUBLISH;
+	mapi_object_init(&obj_message);
+	
+	/*sanity check*/
+	if(icalcomponent_isa(vevent) != ICAL_VEVENT_COMPONENT) return;
+	
+	mem_ctx = talloc_named(NULL, 0, "ical2exchange");
+	ical2exchange.lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
+
+	ical2exchange_init(&ical2exchange, mem_ctx);
+	ical2exchange_get_properties(&ical2exchange, vevent);
+	ical2exchange_convert_event(&ical2exchange);
+	
+	retval = CreateMessage(obj_folder, &obj_message);
+	
+	if (retval != MAPI_E_SUCCESS){
+		mapi_errstr("CreateMessage", GetLastError());
+	} else {
+		retval = SetProps(&obj_message, ical2exchange.lpProps, ical2exchange.cValues);
+		if (retval != MAPI_E_SUCCESS){
+			mapi_errstr("SetProps", GetLastError());
+		} else {
+			retval = SaveChangesMessage(obj_folder, &obj_message, KeepOpenReadOnly);
+			if (retval != MAPI_E_SUCCESS){
+				mapi_errstr("SaveChangesMessage", GetLastError());
+			}
+		}
+	}
+	
+
+	MAPIFreeBuffer(ical2exchange.lpProps);
+	ical2exchange_reset(&ical2exchange);
+	talloc_free(mem_ctx);
+
+}

Added: trunk/openchange/libexchange2ical/ical2exchange_property.c
===================================================================
--- trunk/openchange/libexchange2ical/ical2exchange_property.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/ical2exchange_property.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,1209 @@
+/*
+   Common conversion routines for exchange2ical
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+#define MAXCAT  100000
+
+
+/*Taken from Samba4 code*/
+/*
+  this base64 decoder was taken from jitterbug (written by tridge).
+  we might need to replace it with a new version
+*/
+static int ldb_base64_decode(char *s)
+{
+	const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	int bit_offset=0, byte_offset, idx, i, n;
+	uint8_t *d = (uint8_t *)s;
+	char *p=NULL;
+
+	n=i=0;
+
+	while (*s && (p=strchr(b64,*s))) {
+		idx = (int)(p - b64);
+		byte_offset = (i*6)/8;
+		bit_offset = (i*6)%8;
+		d[byte_offset] &= ~((1<<(8-bit_offset))-1);
+		if (bit_offset < 3) {
+			d[byte_offset] |= (idx << (2-bit_offset));
+			n = byte_offset+1;
+		} else {
+			d[byte_offset] |= (idx >> (bit_offset-2));
+			d[byte_offset+1] = 0;
+			d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
+			n = byte_offset+2;
+		}
+		s++; i++;
+	}
+	if (bit_offset >= 3) {
+		n--;
+	}
+
+	if (*s && !p) {
+		/* the only termination allowed */
+		if (*s != '=') {
+			return -1;
+		}
+	}
+
+	/* null terminate */
+	d[n] = 0;
+	return n;
+}
+
+
+void ical2exchange_property_ATTACH(struct ical2exchange *ical2exchange)
+{
+	int 		data;
+	char 		*extension = NULL;
+	char 		*filename = NULL;
+	const char 	*fmttype = NULL;
+	icalattach	*icalattach = NULL;
+	icalparameter	*fmttypePar = NULL;
+	icalparameter	*xfilePar = NULL;
+	const char 	*xname = NULL;
+	icalproperty	*attachProp = NULL;
+	
+	/*sanity check*/
+	if(!ical2exchange->attachEvent) return;
+	
+	attachProp=icalcomponent_get_first_property(ical2exchange->attachEvent, ICAL_ATTACH_PROPERTY);
+	while(attachProp){
+	
+		icalattach = icalproperty_get_attach(attachProp);
+		data = ldb_base64_decode((char *) icalattach_get_data (icalattach));
+		
+		/*FMTTYPE*/
+		fmttypePar = icalproperty_get_first_parameter(attachProp, ICAL_FMTTYPE_PARAMETER);
+		if(fmttypePar){
+			fmttype = icalparameter_get_fmttype(fmttypePar);
+		}
+		
+		/*X-FIlename*/
+		xfilePar = icalproperty_get_first_parameter(attachProp, ICAL_X_PARAMETER);
+		if(xfilePar){
+			xname = icalparameter_get_xname(xfilePar);
+			if(!strcmp(xname,"X-FILENAME")){
+				filename = (char *) icalparameter_get_x(xfilePar);
+		
+			}
+		}
+		
+		/*Extension*/
+		if(filename){
+			char buff[256]; 
+			char *temp;
+			strncpy(buff,filename, 255);
+			buff[255] = '\0';
+			extension = strtok(buff, ".");
+			while((temp = strtok(NULL, "."))) extension = temp;
+		}
+		
+		printf("Create a new attachment object with\n");
+		printf("	set PidTagAttachDataBinary to %d\n", data);
+		printf("	set PidTagAttachExtension to %s\n", extension);
+		printf("	set PidTagAttachFilename to %s\n", filename);
+		printf("	set PidTagAttachLongFilename to %s\n", filename);
+		printf("	set PidTagAttachMimeTag to %s\n", fmttype);
+		printf("	set PidTagAttachFlags to 0x00000000\n");
+		printf("	set PidTagAttachMethod to 0x00000001\n");
+		printf("	set PidTagAttachmentContactPhoto to FALSE\n");
+		printf("	set PidTagAttachmentFlags to 0x00000000\n");
+		printf("	set PidTagAttachEncoding to empty SBinary");
+		printf("	set PidTagAttachmentHidden to FALSE\n");
+		printf("	set PidTagAttachmentLinkId to 0x00000000\n");
+		printf("	set PidTagDisplayName to  %s\n", filename);
+		printf("	set PidTagExceptionEndTime to 0x0CB34557A3DD4000\n");
+		printf("	set PidTagExceptionStartTime to 0x0CB34557A3DD4000\n");
+		printf("	set PidTagRenderingPosition to 0xFFFFFFFF\n");
+		
+		attachProp=icalcomponent_get_next_property(ical2exchange->attachEvent, ICAL_ATTACH_PROPERTY);
+	}
+}
+
+
+//TODO:
+void ical2exchange_property_CATEGORIES(struct ical2exchange *ical2exchange)
+{
+	struct StringArray_r *sArray;
+	char **stringArray = NULL;
+	char string[256];
+	char *value;
+	char *tok;
+	icalproperty *categoriesProp;
+	uint32_t i = 0;
+
+	/*sanity check*/
+ 	if(!ical2exchange->categoriesEvent) return;
+	
+	sArray = talloc(ical2exchange->mem_ctx, struct StringArray_r);
+	
+	categoriesProp = icalcomponent_get_first_property(ical2exchange->categoriesEvent, ICAL_CATEGORIES_PROPERTY);
+	sArray->cValues = 0;
+	while(categoriesProp){
+	
+		value = strdup(icalproperty_get_categories(categoriesProp));
+		tok = strtok(value, ",");
+		while(tok){
+			if(!stringArray){
+				stringArray = talloc_array(ical2exchange->mem_ctx, char *, 1);
+			} else {
+				stringArray = talloc_realloc(ical2exchange->mem_ctx, stringArray, char *, sArray->cValues+2);
+			}
+			strcpy(string, "");
+			while(tok[i]){
+				if (strlen(string) == 255) break;
+				//remove beginning and ending white spaces
+				if((tok[i]!= ' ' || (tok[i+1] && tok[i+1] != ' ')) && (strlen(string) || tok[i]!=' ')){
+					strncat(string, &tok[i], 1);
+				}
+				i++;
+			}
+			stringArray[sArray->cValues] = talloc_strdup(ical2exchange->mem_ctx, string);
+			sArray->cValues++;
+			i=0;
+			tok= strtok(NULL, ",");
+		}
+		categoriesProp = icalcomponent_get_next_property(ical2exchange->categoriesEvent, ICAL_CATEGORIES_PROPERTY);
+
+	}
+	sArray->lppszA= (const char **) stringArray;
+	
+ 	/* SetProps */
+ 	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidNameKeywords, 
+ 					(const void *) sArray);
+}
+
+void ical2exchange_property_CLASS(struct ical2exchange *ical2exchange)
+{
+	enum icalproperty_class class;
+	uint32_t	temp = 0;
+	uint32_t	*tag;
+	
+	/*sanity check*/
+	if(!ical2exchange->classProp) return;
+	
+	class = icalproperty_get_class(ical2exchange->classProp); 
+	
+	switch(class){
+		case ICAL_CLASS_PUBLIC:
+			temp = 0x00000000;
+			break;
+		case ICAL_CLASS_X:
+			temp = 0x00000001;
+			break;
+		case ICAL_CLASS_PRIVATE:
+			temp = 0x00000002;
+			break;
+		case ICAL_CLASS_CONFIDENTIAL:
+			temp = 0x00000003;
+			break;
+		case ICAL_CLASS_NONE:
+			return;
+	}
+	
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag = temp;
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_SENSITIVITY, 
+					(const void *) tag);
+}
+
+void ical2exchange_property_COMMENT(struct ical2exchange *ical2exchange)
+{
+	const char *comment;
+
+	/*sanity check*/
+	if(!ical2exchange->commentProp) return;
+	if(ical2exchange->method != ICAL_METHOD_COUNTER && ical2exchange->method != ICAL_METHOD_REPLY) return;
+	
+	comment  = icalproperty_get_comment(ical2exchange->commentProp);
+	comment = talloc_strdup(ical2exchange->mem_ctx, comment);
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_BODY,
+			(const void *) comment);
+}
+
+void ical2exchange_property_CONTACT(struct ical2exchange *ical2exchange)
+{
+	struct StringArray_r *sArray;
+ 	char *value;
+	char **stringArray = NULL;
+	icalproperty *contactProp;
+	
+	/*sanity check*/
+	if(!ical2exchange->contactEvent) return;
+	
+
+	contactProp=icalcomponent_get_first_property(ical2exchange->contactEvent, ICAL_CONTACT_PROPERTY);
+	sArray = talloc(ical2exchange->mem_ctx, struct StringArray_r);	
+	sArray->cValues =0;
+	while(contactProp){
+		if(!stringArray){
+			stringArray = talloc_array(ical2exchange->mem_ctx, char *, 1);
+		} else {
+			stringArray = talloc_realloc(ical2exchange->mem_ctx, stringArray, char *, sArray->cValues+2);
+		}
+		value = strdup(icalproperty_get_contact(contactProp));
+ 		if(strlen(value)<500){
+ 			stringArray[sArray->cValues] = talloc_strdup(ical2exchange->mem_ctx, value);
+ 		} else {
+			value[499] = '\0';
+ 			stringArray[sArray->cValues] = talloc_strndup(ical2exchange->mem_ctx, value, 500);
+		}
+ 		sArray->cValues++;
+		contactProp=icalcomponent_get_next_property(ical2exchange->contactEvent, ICAL_CONTACT_PROPERTY);
+	}
+		
+	/*set up struct*/
+	sArray->lppszA=(const char **) stringArray;
+
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidContacts, 
+					(const void *) sArray);
+
+}
+
+void ical2exchange_property_DESCRIPTION(struct ical2exchange *ical2exchange)
+{
+	const char *description;
+	
+	/*sanity check*/
+	if(!ical2exchange->descriptionProp) return;
+	
+	if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY) return;
+	
+	description  = icalproperty_get_description(ical2exchange->descriptionProp);
+	description = talloc_strdup(ical2exchange->mem_ctx, description);
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_BODY,
+			(const void *) description);	
+}
+
+void ical2exchange_property_DTSTAMP(struct ical2exchange *ical2exchange)
+{
+	struct FILETIME *ft;
+	icaltimetype dtstamp;
+	
+	/*sanity check*/
+	if(!ical2exchange->dtstampProp) return;
+		
+	dtstamp  = icalproperty_get_dtstamp(ical2exchange->dtstampProp);
+	ft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	*ft = get_FILETIME_from_icaltimetype(&dtstamp);
+	
+	if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY){
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAttendeeCriticalChange,
+			       (const void *) ft);
+	} else {
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOwnerCriticalChange,
+			       (const void *) ft);
+	}
+}
+
+void ical2exchange_property_DTSTART_DTEND(struct ical2exchange *ical2exchange)
+{
+	icaltimetype dtstart;
+	icaltimetype dtend;
+	struct FILETIME *startft; 
+	struct FILETIME *endft; 
+	double difference;
+	uint32_t *duration; 
+	
+	/*sanity check*/
+	if(!ical2exchange->dtstartProp) return;
+	if(!ical2exchange->dtendProp) return;
+
+	/*dtstart property*/
+	dtstart  = icalproperty_get_dtstart(ical2exchange->dtstartProp);
+	startft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	*startft = get_FILETIME_from_icaltimetype(&dtstart);
+	
+	/*dtend property*/
+	dtend  = icalproperty_get_dtend(ical2exchange->dtendProp);
+	endft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	*endft = get_FILETIME_from_icaltimetype(&dtend);
+	
+	if(ical2exchange->method == ICAL_METHOD_COUNTER){
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentProposedStartWhole,
+			       (const void *) startft);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentProposedEndWhole,
+			       (const void *) endft);
+	} else {
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentStartWhole,
+			       (const void *) startft);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentEndWhole,
+			       (const void *) endft);
+			       
+		/*duration property*/
+		duration = talloc(ical2exchange->mem_ctx, uint32_t);
+		difference =  difftime(nt_time_to_unix(FILETIME_to_NTTIME(*endft)), 
+				       nt_time_to_unix(FILETIME_to_NTTIME(*startft)));  
+		*duration = difference/60;
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentDuration,
+				(const void *) duration);
+		/*check if all day appointment*/
+		if(*duration==1440 && dtstart.hour==0 && dtstart.minute==0){
+			uint32_t *allday = talloc(ical2exchange->mem_ctx, uint32_t);
+			*allday = 0x00000001;
+			ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSubType,
+					(const void *) allday);
+		}
+	}
+}
+
+void ical2exchange_property_LOCATION(struct ical2exchange *ical2exchange)
+{
+	uint32_t *langtag;
+	char location[256] = "";
+	icalparameter *param = NULL;
+	const char *value;
+	char *string;
+	
+	/*sanity check*/
+	if(!ical2exchange->locationProp) return;
+		
+	value  = icalproperty_get_location(ical2exchange->locationProp);
+	int i;
+	
+	for(i=0; i<255; i++){
+		if(!value[i]) break;
+		char c = value[i];
+		if(c !='\xD' && c!='\xA' )
+			strncat(location, &c, 1);
+	}
+	string = talloc_strdup(ical2exchange->mem_ctx, location);
+
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidLocation, 
+			(const void *) string);
+			
+	if((param=icalproperty_get_first_parameter(ical2exchange->locationProp, ICAL_LANGUAGE_PARAMETER))){
+		const char* langName;
+		langtag = talloc(ical2exchange->mem_ctx, uint32_t);
+		langName = icalparameter_get_language(param);
+		*langtag = mapi_get_lcid_from_language(langName);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_MESSAGE_LOCALE_ID, 
+					(const void *) langtag);
+	} 
+
+}
+
+void ical2exchange_property_PRIORITY(struct ical2exchange *ical2exchange)
+{
+	uint32_t temp = 0;
+	uint32_t *tag;
+	
+	if(ical2exchange->x_importanceProp){
+		const char *value = icalproperty_get_x(ical2exchange->x_importanceProp);
+		switch(atoi(value)){
+			case 0:
+				temp = 0x00000000;
+				break;
+			case 1:
+				temp = 0x00000001;
+				break;
+			case 2:
+				temp = 0x00000002;
+				break;
+		}
+	} else if(ical2exchange->priorityProp){
+		switch(icalproperty_get_priority(ical2exchange->priorityProp)){
+			case 0:
+				return;
+			case 1:
+			case 2:
+			case 3:
+			case 4:
+				temp = 0x00000002;
+				break;
+			case 5:
+				temp = 0x00000001;
+				break;
+			case 6:
+			case 7:
+			case 8:
+			case 9:
+				temp = 0x00000000;
+				break;
+			default:
+				return;
+		}
+	} else return;
+	
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag = temp;
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequence, 
+					(const void *) tag);	
+}
+
+//TODO: Finish this
+void ical2exchange_property_RRULE_EXDATE_RDATE(struct ical2exchange *ical2exchange)
+{
+	struct RecurrencePattern	rp;
+	struct icalrecurrencetype 	irt;
+	struct icaltimetype 		next;
+	struct icaltimetype 		last;
+	icalrecur_iterator 		*ritr;
+	icaltimetype 			dtstart;
+	icaltimetype 			rdate;
+	icaltimetype 			exdate;
+	icalproperty 			*exdateProp;
+	icalproperty 			*rdateProp;
+	enum CalendarType 		calendarType;
+	enum EndType 			endType;
+	enum icalrecurrencetype_weekday	weekday; 
+	uint32_t 			startTime;
+	uint32_t 			endTime;
+	uint32_t 			occurrenceCount;
+	uint32_t			i;
+	uint32_t 			modifiedInstanceDates[ical2exchange->rdateCount];
+	uint32_t 			deletedInstanceDates[ical2exchange->exdateCount+ical2exchange->rdateCount];
+	
+	if(!ical2exchange->rruleProp) return;
+	if(!ical2exchange->dtstartProp) return;
+	
+	irt =  icalproperty_get_rrule(ical2exchange->rruleProp);
+
+	/*StartTime*/
+	enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day);
+	dtstart  = icalproperty_get_dtstart(ical2exchange->dtstartProp);
+	dtstart.hour = 0;
+	dtstart.minute = 0;
+	dtstart.second = 0;
+	startTime = get_minutes_from_icaltimetype(dtstart);
+	
+	/*WeekDay*/
+	if(irt.week_start == ICAL_NO_WEEKDAY){
+		weekday = icalrecurrencetype_day_day_of_week(icaltime_day_of_week(dtstart));
+	} else {
+		weekday = irt.week_start;
+	}
+	
+	/*calendarType*/
+	//if(ical2exchange->calscaleProp){
+		//calendarType = get_exchange_calendartype(icalproperty_get_x(ical2exchange->calscaleProp));
+		
+	//} else {
+		calendarType = CAL_DEFAULT;
+	//}
+	
+	/*endType occurrenceCount endTime*/
+	if(irt.count || !icaltime_is_null_time(irt.until)){
+		endType	= END_AFTER_N_OCCURRENCES;
+		occurrenceCount = irt.count;
+		
+		ritr = icalrecur_iterator_new(irt,dtstart);
+		next=icalrecur_iterator_next(ritr);
+		
+		while (!icaltime_is_null_time(next)){
+			last = next;
+			next=icalrecur_iterator_next(ritr);
+			
+			if(!irt.count) occurrenceCount++;
+		}
+		
+		endTime	= get_minutes_from_icaltimetype(last); 
+		icalrecur_iterator_free(ritr);
+		
+	} else {
+		endType	= END_NEVER_END;
+		occurrenceCount = 0x0000000A;
+		endTime		= 0x5AE980DF;
+	}
+	
+	/*Common values for all rrule*/
+	rp.ReaderVersion 	= 0x3004;
+	rp.WriterVersion 	= 0x3004;
+	rp.CalendarType		= calendarType;
+	rp.FirstDateTime	= startTime;
+	rp.SlidingFlag		= 0x00000000;
+	rp.EndType		= endType;
+	rp.OccurrenceCount	= occurrenceCount;
+	rp.FirstDOW		= get_exchange_day_from_ical(weekday);	
+	rp.StartDate		= startTime;
+	rp.EndDate		= endTime;
+	
+	/*Specific values*/
+	switch(irt.freq){
+		case ICAL_DAILY_RECURRENCE:
+			rp.RecurFrequency 	= RecurFrequency_Daily;
+			rp.PatternType		= PatternType_Day;
+			rp.Period		= 1440 * irt.interval;
+			break;
+		case ICAL_WEEKLY_RECURRENCE:
+			rp.RecurFrequency 	= RecurFrequency_Weekly;
+			rp.PatternType		= PatternType_Day;
+			rp.Period		= irt.interval;
+			break;
+		case ICAL_MONTHLY_RECURRENCE:
+			rp.RecurFrequency 	= RecurFrequency_Monthly;
+			rp.Period		= irt.interval;
+			
+			if(irt.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX){
+				rp.PatternType	= PatternType_Month;
+				
+				if(irt.by_month_day[0] == -1){
+					rp.PatternTypeSpecific.Day = 0x0000001F;
+				} else {
+					rp.PatternTypeSpecific.Day = irt.by_month_day[0];
+				}
+				
+			} else {
+				rp.PatternType	= PatternType_MonthNth;
+				i = 0;
+				rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = 0;
+				while( irt.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX){
+					rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern  |= get_exchange_rdfDays_from_ical(irt.by_day[i]);
+					i++;
+				}
+				if(irt.by_set_pos[0] == -1) rp.PatternTypeSpecific.MonthRecurrencePattern.N = RecurrenceN_Last;
+				else rp.PatternTypeSpecific.MonthRecurrencePattern.N = irt.by_set_pos[0];
+			}
+			break;
+		case ICAL_YEARLY_RECURRENCE:
+			rp.RecurFrequency 	= RecurFrequency_Yearly;
+			rp.Period		= 12 * irt.interval;
+			
+			/*Nth*/
+			if(irt.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX){
+				rp.PatternType	= PatternType_Month;
+				if(irt.by_month_day[0] == -1){
+					rp.PatternTypeSpecific.Day = 0x0000001F;
+				} else {
+					rp.PatternTypeSpecific.Day = irt.by_month_day[0];
+				}
+			} else {
+				rp.PatternType	= PatternType_MonthNth;
+				i = 0;
+				rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern = 0;
+				while( irt.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX){
+					rp.PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern  |= get_exchange_rdfDays_from_ical(irt.by_day[i]);
+					i++;
+				}
+				if(irt.by_set_pos[0] == -1) rp.PatternTypeSpecific.MonthRecurrencePattern.N = RecurrenceN_Last;
+				else rp.PatternTypeSpecific.MonthRecurrencePattern.N = irt.by_set_pos[0];
+			}
+			break;
+		default:
+			printf("not handled yet\n");
+			
+	}
+	
+
+	/*deletedInstanceDates & modifiedInstanceDates*/
+	if(ical2exchange->exdateEvent){
+		exdateProp=icalcomponent_get_first_property(ical2exchange->exdateEvent, ICAL_EXDATE_PROPERTY);
+
+		for(i=0; i<ical2exchange->exdateCount; i++){
+			exdate = icalproperty_get_exdate(exdateProp);
+			deletedInstanceDates[i] = get_minutes_from_icaltimetype(exdate);
+			exdateProp=icalcomponent_get_first_property(ical2exchange->exdateEvent, ICAL_EXDATE_PROPERTY);
+		}
+	}
+	
+	if(ical2exchange->rdateEvent){
+		rdateProp = icalcomponent_get_first_property(ical2exchange->rdateEvent, ICAL_EXDATE_PROPERTY);
+
+		for(i=0; i<ical2exchange->rdateCount; i++){
+			rdate = icalproperty_get_exdate(rdateProp);
+			deletedInstanceDates[i + ical2exchange->exdateCount] = get_minutes_from_icaltimetype(rdate);
+			modifiedInstanceDates[i] = get_minutes_from_icaltimetype(rdate);
+			rdateProp = icalcomponent_get_first_property(ical2exchange->rdateEvent, ICAL_EXDATE_PROPERTY);
+		}
+	}
+	/*Sort array*/
+	qsort(deletedInstanceDates, ical2exchange->rdateCount + ical2exchange->exdateCount, sizeof(uint32_t), compare_minutes);
+	qsort(modifiedInstanceDates, ical2exchange->rdateCount, sizeof(uint32_t), compare_minutes);
+	
+	rp.DeletedInstanceCount = ical2exchange->rdateCount + ical2exchange->exdateCount;
+	rp.ModifiedInstanceCount = ical2exchange->rdateCount;
+	
+	rp.DeletedInstanceDates = deletedInstanceDates;
+	rp.ModifiedInstanceDates = modifiedInstanceDates;
+	
+	
+}
+
+void ical2exchange_property_SEQUENCE(struct ical2exchange *ical2exchange)
+{
+	uint32_t temp;
+	uint32_t *tag;
+	
+	if(ical2exchange->x_sequenceProp){
+		temp = atoi(icalproperty_get_x(ical2exchange->x_sequenceProp));
+	} else if(ical2exchange->sequenceProp){
+		temp = icalproperty_get_sequence(ical2exchange->sequenceProp);
+	} else return;
+	
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag = temp;
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequence, 
+					(const void *) tag);	
+}
+
+void ical2exchange_property_STATUS(struct ical2exchange *ical2exchange)
+{
+	
+	enum icalproperty_status status;
+	enum icalproperty_transp transp;
+	uint32_t *tag;
+	uint32_t temp = 0;
+	const char *prop;
+	
+	if(ical2exchange->x_busystatusProp){
+		prop=icalproperty_get_x(ical2exchange->x_busystatusProp);
+
+		if(!strcmp(prop, "FREE")){
+			temp = 0x00000000;
+		} else if(!strcmp(prop, "TENTATIVE")){
+			temp = 0x00000001;
+		} else if(!strcmp(prop, "BUSY")){
+			temp = 0x00000002;
+		} else if(!strcmp(prop, "OOF")){
+			temp = 0x00000003;
+		}
+		
+	} else if(ical2exchange->transpProp){
+		transp = icalproperty_get_transp(ical2exchange->transpProp); 
+		switch(transp){
+			case ICAL_TRANSP_TRANSPARENT:
+				temp = 0x00000000;
+				break;
+			case ICAL_TRANSP_OPAQUE:
+				temp = 0x00000002;
+				break;
+			default:
+				return;
+		}
+		
+	} else if(ical2exchange->statusProp){
+		status = icalproperty_get_status(ical2exchange->classProp); 
+		switch(status){
+			case ICAL_STATUS_CANCELLED:
+				temp = 0x00000000;
+				break;
+			case ICAL_STATUS_TENTATIVE:
+				temp = 0x00000001;
+				break;
+			case ICAL_STATUS_CONFIRMED:
+				temp = 0x00000002;
+				break;
+			default:
+				return;
+		}
+	} else return;
+	
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag = temp;
+	
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidBusyStatus, 
+					(const void *) tag);	
+}
+
+void ical2exchange_property_SUMMARY(struct ical2exchange *ical2exchange)
+{
+	const char *value;
+	uint32_t langtag;
+	char summary[256] = "";
+	icalparameter *param = NULL;
+	char *string;
+	
+	/*sanity check*/
+	if(!ical2exchange->summaryProp) return;
+	
+	value  = icalproperty_get_summary(ical2exchange->summaryProp);
+	
+	int i;
+	
+	for(i=0; i<255; i++){
+		if(!value[i]) break;
+		char c = value[i];
+		if(c !='\xD' && c!='\xA' )
+			strncat(summary, &c, 1);
+	}
+	string = talloc_strdup(ical2exchange->mem_ctx, summary);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_SUBJECT, 
+			(const void *) string);
+	if((param=icalproperty_get_first_parameter(ical2exchange->summaryProp, ICAL_LANGUAGE_PARAMETER))){
+		const char *langName;
+		langName = icalparameter_get_language(param);
+		langtag = mapi_get_lcid_from_language(langName);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_MESSAGE_LOCALE_ID, 
+						(const void *) &langtag);
+	}
+}
+
+void ical2exchange_property_VALARM(struct ical2exchange *ical2exchange)
+{
+	icalproperty *triggerProp = NULL;
+	uint32_t *duration;
+	icaltimetype dtstart;
+	icaltimetype current;
+	icaltimetype triggerSet;
+	icaltimetype next;
+	
+	const icaltimezone *timezone; 
+	struct FILETIME *rtimeft;
+	struct FILETIME *rsignalft;
+	struct icalrecurrencetype 	irt;
+	icalrecur_iterator 		*ritr;
+	struct icaltriggertype trigger;
+	bool *set;
+	
+
+	/*sanity check*/
+	if(!ical2exchange->valarmEvent) return;
+	if(!ical2exchange->dtstartProp) return;
+
+	triggerProp = icalcomponent_get_first_property(ical2exchange->valarmEvent, ICAL_TRIGGER_PROPERTY);
+	if(!triggerProp) return;
+	
+	trigger = icalproperty_get_trigger(triggerProp);
+	dtstart  = icalproperty_get_dtstart(ical2exchange->dtstartProp);
+	duration = talloc(ical2exchange->mem_ctx, uint32_t);
+	
+	if(trigger.duration.is_neg){
+		*duration = -trigger.duration.minutes;
+	} else {
+		*duration = trigger.duration.minutes;
+	}
+
+	timezone = icaltime_get_timezone(dtstart);
+	current = icaltime_current_time_with_zone(timezone);
+	
+	if(icaltime_compare(dtstart, current)) {
+		rtimeft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+		rsignalft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+
+		*rtimeft = get_FILETIME_from_icaltimetype(&dtstart);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderTime, 
+						(const void *) rtimeft);
+			
+		triggerSet = icaltime_add(dtstart, trigger.duration);
+		*rsignalft = get_FILETIME_from_icaltimetype(&triggerSet);
+		ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSignalTime, 
+						(const void *) rsignalft);
+	} else if(ical2exchange->rruleProp) {
+		irt =  icalproperty_get_rrule(ical2exchange->rruleProp);
+		ritr = icalrecur_iterator_new(irt,dtstart);
+		next = icalrecur_iterator_next(ritr);
+		
+		while (!icaltime_is_null_time(next)){
+			if(icaltime_compare(next, current)) {
+				rtimeft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+				rsignalft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+				
+				*rtimeft = get_FILETIME_from_icaltimetype(&next);
+				ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderTime, 
+					(const void *) rtimeft);
+					
+				triggerSet = icaltime_add(next, trigger.duration);
+				*rsignalft = get_FILETIME_from_icaltimetype(&triggerSet);
+				ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSignalTime, 
+					(const void *) &rsignalft);
+				break;
+			}
+			next=icalrecur_iterator_next(ritr);
+		}
+	} else return;
+	
+	set = talloc(ical2exchange->mem_ctx, bool);
+	*set = true;
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderSet, 
+					(const void *) set);
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidReminderDelta, 
+					(const void *) duration);
+}
+
+void ical2exchange_property_X_ALLOWEXTERNCHECK(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *allow;
+	
+	if(!ical2exchange->x_allowexterncheckProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_allowexterncheckProp);
+	allow = talloc(ical2exchange->mem_ctx, bool);
+	
+	if(strcmp(prop, "TRUE")){
+		*allow = true;
+	} else {
+		*allow = false;
+	}
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAllowExternalCheck, 
+					(const void *) allow);
+}
+
+void ical2exchange_property_X_APPTSEQTIME(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	struct FILETIME *ft;
+	
+	if(!ical2exchange->x_apptseqtimeProp) return;
+	
+	ft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	
+	prop=icalproperty_get_x(ical2exchange->x_apptseqtimeProp);
+	*ft = get_FILETIME_from_string(prop);
+
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentSequenceTime, 
+					(const void *) ft);
+}
+
+void ical2exchange_property_X_APPTLASTSEQUENCE(struct ical2exchange *ical2exchange)
+{
+	uint32_t *tag;
+	const char *prop;
+	
+	if(!ical2exchange->x_apptlastsequenceProp) return;
+
+	prop=icalproperty_get_x(ical2exchange->x_apptlastsequenceProp);
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag=atoi(prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentLastSequence, 
+					(const void *) tag);
+}
+
+void ical2exchange_property_X_ATTENDEE_CRITICAL_CHANGE(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	struct FILETIME *ft;
+	
+	if(!ical2exchange->x_attendeecriticalchangeProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_attendeecriticalchangeProp);
+	ft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	*ft = get_FILETIME_from_string(prop);
+
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAttendeeCriticalChange, 
+					(const void *) ft);
+}
+
+void ical2exchange_property_X_AUTOFILLLOCATION(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *autoFill;
+	
+	if(!ical2exchange->x_autofilllocationProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_autofilllocationProp);
+	autoFill = talloc(ical2exchange->mem_ctx, bool);
+	
+	if(strcmp(prop, "TRUE")){
+		*autoFill = true;
+	} else {
+		*autoFill = false;
+	}
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAutoFillLocation, 
+					(const void *) autoFill);
+}
+
+void ical2exchange_property_X_AUTOSTARTCHECK(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *autoStart;
+	
+	if(!ical2exchange->x_autostartcheckProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_autostartcheckProp);
+	autoStart = talloc(ical2exchange->mem_ctx, bool);	
+	
+	if(strcmp(prop, "TRUE")){
+		*autoStart = true;
+	} else {
+		*autoStart = false;
+	}
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAutoStartCheck, 
+					(const void *) autoStart);
+}
+
+void ical2exchange_property_X_COLLABORATEDDOC(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	
+	if(!ical2exchange->x_collaborateddocProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_collaborateddocProp);		
+	
+	prop = talloc_strdup(ical2exchange->mem_ctx, prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidCollaborateDoc, 
+					(const void *) prop);
+}
+
+void ical2exchange_property_X_CONFCHECK(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *confCheck;
+	
+	if(!ical2exchange->x_confcheckProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_confcheckProp);
+	confCheck = talloc(ical2exchange->mem_ctx, bool);
+	
+	if(strcmp(prop, "TRUE")){
+		*confCheck = true;
+	} else {
+		*confCheck = false;
+	}
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidConferencingCheck, 
+					(const void *) confCheck);
+}
+
+void ical2exchange_property_X_CONFTYPE(struct ical2exchange *ical2exchange)
+{
+	uint32_t *tag;
+	const char *prop;
+	
+	if(!ical2exchange->x_conftypeProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_conftypeProp);
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag=atoi(prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidConferencingType, 
+					(const void *) tag);
+}
+
+void ical2exchange_property_X_DISALLOW_COUNTER(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *disallow;
+	
+	if(!ical2exchange->x_disallowcounterProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_disallowcounterProp);
+	disallow = talloc(ical2exchange->mem_ctx, bool);
+	
+	if(strcmp(prop, "TRUE")){
+		*disallow = true;
+	} else {
+		*disallow = false;
+	}
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentNotAllowPropose, 
+					(const void *) disallow);
+}
+
+void ical2exchange_property_X_INTENDEDSTATUS(struct ical2exchange *ical2exchange)
+{
+	uint32_t *tag;
+	const char *prop;
+	
+	if(!ical2exchange->x_intendedProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_intendedProp);
+	tag = talloc(ical2exchange->mem_ctx,uint32_t);
+	
+	if(!strcmp(prop, "FREE")){
+		*tag = 0x00000000;
+	} else if(!strcmp(prop, "TENTATIVE")){
+		*tag = 0x00000001;
+	} else if(!strcmp(prop, "BUSY")){
+		*tag = 0x00000002;
+	} else if(!strcmp(prop, "OOF")){
+		*tag = 0x00000003;
+	}
+	
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidIntendedBusyStatus, 
+					(const void *) tag);
+}
+
+void ical2exchange_property_X_ISDRAFT(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	bool *isDraft;
+	
+	isDraft = talloc(ical2exchange->mem_ctx, bool);
+	
+	if(ical2exchange->method == ICAL_METHOD_COUNTER || ical2exchange->method == ICAL_METHOD_REPLY 
+		|| ical2exchange->method == ICAL_METHOD_REQUEST || ical2exchange->method == ICAL_METHOD_CANCEL){
+		
+		*isDraft = true;
+	} else {
+		if(ical2exchange->x_isdraftProp){
+			prop=icalproperty_get_x(ical2exchange->x_isdraftProp);		
+			if(strcmp(prop, "TRUE")){
+				*isDraft = true;
+			} else {
+				*isDraft = false;
+			}
+		} else {
+			*isDraft = false;
+		}
+	}
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidFInvited, 
+					(const void *) isDraft);
+}
+
+void ical2exchange_property_X_MWSURL(struct ical2exchange *ical2exchange)
+{
+	char *mwsurl;
+	const char *prop;
+	
+	if(!ical2exchange->x_mwsurlProp) return;
+	
+	prop = icalproperty_get_x(ical2exchange->x_mwsurlProp);		
+	mwsurl = talloc_strdup(ical2exchange->mem_ctx, prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidMeetingWorkspaceUrl, 
+					(const void *) mwsurl);
+}
+
+void ical2exchange_property_X_NETSHOWURL(struct ical2exchange *ical2exchange)
+{
+	char *netshow;
+	const char *prop;
+	
+	if(!ical2exchange->x_netshowurlProp) return;
+	
+	prop = icalproperty_get_x(ical2exchange->x_netshowurlProp);		
+	netshow = talloc_strdup(ical2exchange->mem_ctx, prop);
+
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidNetShowUrl, 
+					(const void *) netshow);
+}
+
+void ical2exchange_property_X_ONLINEPASSWORD(struct ical2exchange *ical2exchange)
+{
+	char *onlinepass;
+	const char *prop;
+	
+	if(!ical2exchange->x_onlinepasswordProp) return;
+	
+	prop = icalproperty_get_x(ical2exchange->x_onlinepasswordProp);		
+	onlinepass = talloc_strdup(ical2exchange->mem_ctx, prop);
+
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOnlinePassword, 
+					(const void *) onlinepass);
+}
+
+void ical2exchange_property_X_ORGALIAS(struct ical2exchange *ical2exchange)
+{
+	char *orgalias;
+	const char *prop;
+	
+	if(!ical2exchange->x_orgaliasProp) return;
+	
+	prop = icalproperty_get_x(ical2exchange->x_orgaliasProp);		
+	orgalias = talloc_strdup(ical2exchange->mem_ctx, prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOrganizerAlias, 
+					(const void *) orgalias);
+}
+
+void ical2exchange_property_X_ORIGINALEND_ORIGINALSTART(struct ical2exchange *ical2exchange)
+{
+	const char *start;
+	const char *end;
+	double difference;
+	uint32_t duration;
+	struct FILETIME startft;
+	struct FILETIME endft;
+	
+	/*sanity check*/
+	if(!ical2exchange->x_originalendProp) return;
+	if(!ical2exchange->x_originalstartProp) return;
+	if(ical2exchange->method != ICAL_METHOD_COUNTER) return;
+	
+	start = icalproperty_get_x(ical2exchange->x_originalstartProp);
+	end = icalproperty_get_x(ical2exchange->x_originalendProp);
+
+	startft = get_FILETIME_from_string(start);
+	endft = get_FILETIME_from_string(end);
+	
+	/*duration property*/
+	difference =  difftime(nt_time_to_unix(FILETIME_to_NTTIME(endft)), 
+				     nt_time_to_unix(FILETIME_to_NTTIME(startft)));
+	duration = difference/60;
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentStartWhole, 
+			(const void *) &startft);
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentEndWhole, 
+			(const void *) &endft);
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentDuration, 
+			(const void *) &duration);
+			
+}
+
+void ical2exchange_property_X_OWNER_CRITICAL_CHANGE(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	struct FILETIME ft;
+	
+	if(!ical2exchange->x_ownercriticalchangeProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_ownercriticalchangeProp);
+	ft = get_FILETIME_from_string(prop);
+
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidOwnerCriticalChange, 
+					(const void *) &ft);
+}
+
+void ical2exchange_property_X_OWNERAPPTID(struct ical2exchange *ical2exchange)
+{
+	uint32_t *tag;
+	const char *prop;
+	
+	if(!ical2exchange->x_ownerapptidProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_ownerapptidProp);
+	
+	tag = talloc(ical2exchange->mem_ctx, uint32_t);
+	*tag = atoi(prop);
+	
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PR_OWNER_APPT_ID, 
+					(const void *) tag);
+}
+
+void ical2exchange_property_X_REPLYTIME(struct ical2exchange *ical2exchange)
+{
+	const char *prop;
+	struct FILETIME *ft;
+	
+	if(!ical2exchange->x_replytimeProp) return;
+	
+	prop=icalproperty_get_x(ical2exchange->x_replytimeProp);
+	ft = talloc(ical2exchange->mem_ctx, struct FILETIME);
+	*ft = get_FILETIME_from_string(prop);
+
+	/* SetProps */
+	ical2exchange->lpProps = add_SPropValue(ical2exchange->mem_ctx, ical2exchange->lpProps, &ical2exchange->cValues, PidLidAppointmentReplyTime, 
+					(const void *) ft);
+}

Added: trunk/openchange/libexchange2ical/libexchange2ical.c
===================================================================
--- trunk/openchange/libexchange2ical/libexchange2ical.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/libexchange2ical.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,60 @@
+/*
+   Convert Exchange appointments to ICAL
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+
+icalcomponent * Exchange2Ical(mapi_object_t *obj_folder)
+{
+	struct exchange2ical_check exchange2ical_check;
+	exchange2ical_check.eFlags=EntireFlag;
+	
+	return _Exchange2Ical(obj_folder, &exchange2ical_check);
+}
+
+
+icalcomponent * Exchange2IcalRange(mapi_object_t *obj_folder, struct tm *begin, struct tm *end)
+{
+	struct exchange2ical_check exchange2ical_check;
+	exchange2ical_check.eFlags=RangeFlag;
+	exchange2ical_check.begin = begin;
+	exchange2ical_check.end = end;
+	return _Exchange2Ical(obj_folder, &exchange2ical_check);
+}
+
+
+icalcomponent *Exchange2IcalEvent(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId, uint32_t Sequence)
+{
+	struct exchange2ical_check exchange2ical_check;
+	exchange2ical_check.eFlags=EventFlag;
+	exchange2ical_check.GlobalObjectId=GlobalObjectId;
+	exchange2ical_check.Sequence=Sequence;
+	return _Exchange2Ical(obj_folder, &exchange2ical_check);
+}
+
+
+icalcomponent *Exchange2IcalEvents(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId)
+{
+	struct exchange2ical_check exchange2ical_check;
+	exchange2ical_check.eFlags=EventsFlag;
+	exchange2ical_check.GlobalObjectId=GlobalObjectId;
+	return _Exchange2Ical(obj_folder, &exchange2ical_check);
+}

Added: trunk/openchange/libexchange2ical/libexchange2ical.h
===================================================================
--- trunk/openchange/libexchange2ical/libexchange2ical.h	                        (rev 0)
+++ trunk/openchange/libexchange2ical/libexchange2ical.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,94 @@
+/*
+   Convert Exchange appointments to ICAL
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/exchange2ical.h>
+#ifndef	__LIBEXCHANGE2ICAL_H_
+#define	__LIBEXCHANGE2ICAL_H_
+
+/**
+   \details Retrieve entire exchange calendar as an Icalendar
+
+   This function returns an Icalendar of the entire exchange calendar inside the obj_folder
+
+   \param obj_folder the folder to operate in
+  
+   \return Icalendar on success, otherwise Null
+
+   \note Developers should call ical_component_free() on the returned icalendar after use.
+
+ */
+icalcomponent * Exchange2Ical(mapi_object_t *obj_folder);
+
+/**
+   \details Retrieve a range of exchange appointments as an Icalendar
+
+   This function returns an Icalendar of exchange appointments that begin within the specified range.
+
+   \param obj_folder the folder to operate in
+   \param begin	a tm that specifies the start date of the range
+   \param end a tm that specifies the end date of the range
+
+   \return Icalendar on success, otherwise Null
+
+   \note Developers should call ical_component_free() on the returned icalendar after use.
+   If no events are within the specified range, an icalendar will be returned without any vevents.
+
+ */
+icalcomponent * Exchange2IcalRange(mapi_object_t *obj_folder, struct tm *begin, struct tm *end);
+
+
+/**
+   \details Retrieve a specific exchange appointment as an Icalendar
+
+   This function returns an Icalendar with an appointments that match
+   the specified GlobalObjectId amd sequence number.
+
+   \param obj_folder the folder to operate in
+   \param GlobalObjectId the unique GlobalObjectId of the appointment
+   \param Sequence the sequence number of the appointment
+
+   \return Icalendar on success, otherwise Null
+
+   \note Developers should call ical_component_free() on the returned icalendar after use.
+   If no event's GlobalObjectId match the specifid GlobalObjectId, an icalendar will be returned without any vevents.
+
+ */
+icalcomponent *Exchange2IcalEvent(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId, uint32_t Sequence);
+
+
+/**
+   \details Retrieve an exchange appointment and its occurrences as an Icalendar
+
+   This function returns an Icalendar with any appointments that match
+   the specified GlobalObjectId amd sequence number.
+   
+   \param obj_folder the folder to operate in
+   \param GlobalObjectId the unique GlobalObjectId of the appointment
+
+   \return Icalendar on success, otherwise Null
+
+   \note Developers should call ical_component_free() on the returned icalendar after use.
+   If no event's GlobalObjectId match the specifid GlobalObjectId, an icalendar will be returned without any vevents.
+
+ */
+icalcomponent *Exchange2IcalEvents(mapi_object_t *obj_folder, struct GlobalObjectId *GlobalObjectId);
+
+#endif /* __LIBEXCHANGE2ICAL_H_ */

Added: trunk/openchange/libexchange2ical/libical2exchange.c
===================================================================
--- trunk/openchange/libexchange2ical/libical2exchange.c	                        (rev 0)
+++ trunk/openchange/libexchange2ical/libical2exchange.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,22 @@
+/*
+   Common conversion routines for exchange2ical
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>

Modified: trunk/openchange/libmapi/FXICS.c
===================================================================
--- trunk/openchange/libmapi/FXICS.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/FXICS.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -99,7 +99,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IABContainer.c
===================================================================
--- trunk/openchange/libmapi/IABContainer.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IABContainer.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -57,6 +57,9 @@
      path pointed by profiledb
    -# MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
+
+     It is the developer responsibility to call MAPIFreeBuffer on
+     rowset and flaglist once they have finished to use them.
    
    \sa MAPILogonProvider, GetLastError
  */
@@ -67,6 +70,7 @@
 				      struct SPropTagArray **flaglist, 
 				      uint32_t flags)
 {
+	TALLOC_CTX		*mem_ctx;
 	struct nspi_context	*nspi;
 	enum MAPISTATUS		retval;
 
@@ -78,16 +82,22 @@
 	OPENCHANGE_RETVAL_IF(!rowset, MAPI_E_INVALID_PARAMETER, NULL);
 
 	nspi = (struct nspi_context *)session->nspi->ctx;
+	mem_ctx = talloc_named(NULL, 0, "ResolveNames");
 
 	switch (flags) {
 	case MAPI_UNICODE:
-		retval = nspi_ResolveNamesW(nspi, usernames, props, &rowset, &flaglist);
+		retval = nspi_ResolveNamesW(nspi, mem_ctx, usernames, props, &rowset, &flaglist);
 		break;
 	default:
-		retval = nspi_ResolveNames(nspi, usernames, props, &rowset, &flaglist);
+		retval = nspi_ResolveNames(nspi, mem_ctx, usernames, props, &rowset, &flaglist);
 		break;
 	}
 
+	*rowset = talloc_steal(nspi->mem_ctx, *rowset);
+	*flaglist = talloc_steal(nspi->mem_ctx, *flaglist);
+
+	talloc_free(mem_ctx);
+
 	if (retval != MAPI_E_SUCCESS) return retval;
 
 	return MAPI_E_SUCCESS;
@@ -97,16 +107,35 @@
 /**
    \details Retrieve the global address list
    
+   The Global Address List is the full list of email addresses (and other
+   account-type things, such as "rooms" and distribution lists) accessible
+   on the server. A user will usually have access to both a personal
+   address book, and to the Global Address List. Public Address Book is
+   another name for Global Address List.
+   
+   You access the Global Address List by setting the list of things that
+   you want to retrieve from the Global Address List as property names
+   in the SPropTagArray argument, and then calling this function. The 
+   results are returned in SRowSet.
+   
+   You can get a convenient output of the results using mapidump_PAB_entry()
+   for each row returned.
+   
    \param session pointer to the MAPI session context
-   \param SPropTagArray pointer on an array of MAPI properties we want
+   \param SPropTagArray pointer to an array of MAPI properties we want
    to fetch
-   \param SRowSet pointer on the rows returned
+   \param SRowSet pointer to the rows of the table returned
    \param count the number of rows we want to fetch
    \param ulFlags specify the table cursor location
 
    Possible value for ulFlags:
    -# TABLE_START: Fetch rows from the beginning of the table
    -# TABLE_CUR: Fetch rows from current table location
+   
+   The Global Address List may be quite large (tens of thousands of
+   entries in a large deployment), so you usually call this function
+   with ulFlags set to TABLE_START the first time, and then subsequent
+   calls will be made with TABLE_CUR to progress through the table.
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 
@@ -118,7 +147,7 @@
    -# MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
 
-   \sa MapiLogonEx, MapiLogonProvider
+   \sa MapiLogonEx, MapiLogonProvider, mapidump_PAB_entry
  */
 _PUBLIC_ enum MAPISTATUS GetGALTable(struct mapi_session *session,
 				     struct SPropTagArray *SPropTagArray, 
@@ -126,6 +155,7 @@
 				     uint32_t count, 
 				     uint8_t ulFlags)
 {
+	TALLOC_CTX		*mem_ctx;
 	struct nspi_context	*nspi;
 	struct SRowSet		*srowset;
 	enum MAPISTATUS		retval;
@@ -138,6 +168,7 @@
 	OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
 
+	mem_ctx = talloc_named(NULL, 0, "GetGALTable");
 	nspi = (struct nspi_context *)session->nspi->ctx;
 
 	if (ulFlags == TABLE_START) {
@@ -147,11 +178,13 @@
 		nspi->pStat->TotalRecs = 0xffffffff;
 	}
 
-	srowset = talloc_zero(session, struct SRowSet);
-	retval = nspi_QueryRows(nspi, SPropTagArray, NULL, count, &srowset);
+	srowset = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi, mem_ctx, SPropTagArray, NULL, count, &srowset);
+	srowset = talloc_steal(session, srowset);
 	*SRowSet = srowset;
 
-	if (retval != MAPI_E_SUCCESS) return retval;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	talloc_free(mem_ctx);
 
 	return MAPI_E_SUCCESS;
 }
@@ -210,8 +243,8 @@
 	OPENCHANGE_RETVAL_IF(!ppRowSet, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
 
+	mem_ctx = talloc_named(NULL, 0, "GetABRecipientInfo");
 	nspi_ctx = (struct nspi_context *)session->nspi->ctx;
-	mem_ctx = nspi_ctx->mem_ctx;
 
 	/* Step 1. Resolve the username */
 	usernames[0] = username;
@@ -233,12 +266,9 @@
 					  PR_SMTP_ADDRESS_UNICODE);
 	retval = ResolveNames(session, usernames, SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
 	MAPIFreeBuffer(SPropTagArray);
-	OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	if (flaglist->aulPropTag[0] != MAPI_RESOLVED) {
-		MAPIFreeBuffer(SRowSet);
-		return MAPI_E_NOT_FOUND;
-	}
+	OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx);
 
 	username = (const char *) get_SPropValue_SRowSet_data(SRowSet, PR_7BIT_DISPLAY_NAME_UNICODE);
 	email = talloc_strdup(mem_ctx, (const char *) get_SPropValue_SRowSet_data(SRowSet, PR_EMAIL_ADDRESS_UNICODE));
@@ -249,10 +279,10 @@
 	pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
 	pNames.Strings[0] = email;
 	pMId = talloc_zero(mem_ctx, struct SPropTagArray);
-	retval = nspi_DNToMId(nspi_ctx, &pNames, &pMId);
+	retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &pMId);
 	MAPIFreeBuffer((char *)pNames.Strings[0]);
 	MAPIFreeBuffer((char **)pNames.Strings);
-	OPENCHANGE_RETVAL_IF(retval, retval, pMId);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	/* Step 3. Get recipient's properties */
 	if (!pPropTags) {
@@ -267,14 +297,17 @@
 	}
 
 	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
-	retval = nspi_GetProps(nspi_ctx, SPropTagArray, pMId, &SRowSet);
+	retval = nspi_GetProps(nspi_ctx, mem_ctx, SPropTagArray, pMId, &SRowSet);
 	if (allocated == true) {
 		MAPIFreeBuffer(SPropTagArray);
 	}
 	MAPIFreeBuffer(pMId);
-	OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
+	SRowSet = talloc_steal((TALLOC_CTX *)session, SRowSet);
 	*ppRowSet = SRowSet;
 
+	talloc_free(mem_ctx);
+
 	return MAPI_E_SUCCESS;
 }

Modified: trunk/openchange/libmapi/IMAPIContainer.c
===================================================================
--- trunk/openchange/libmapi/IMAPIContainer.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPIContainer.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -127,7 +127,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_container);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -254,7 +254,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_container);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -350,7 +350,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_container);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -448,7 +448,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -522,7 +522,7 @@
 	mem_ctx = talloc_named(NULL, 0, "ModifyTable");
 	size = 0;
 
-	/* Fill the GetTable operation */
+	/* Fill the ModifyTable operation */
 	request.rowList = *rowList;
 	request.rowList.padding = 0;
 	size += sizeof (uint8_t) + sizeof (uint16_t);
@@ -552,7 +552,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -567,9 +567,9 @@
 }
 
 /**
-   \details Etablishes search criteria for the container
+   \details Establishes search criteria for the container
 
-   \param obj_container the object we apply search criteria on
+   \param obj_container the object we apply search criteria to
    \param res pointer to a mapi_SRestriction structure defining the
    search criteria
    \param SearchFlags bitmask of flags that controls how the search
@@ -605,6 +605,7 @@
    \note Developers may also call GetLastError() to retrieve the last
    MAPI error code. Possible MAPI error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: One or more parameters were invalid (usually null pointer)
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
      
@@ -676,7 +677,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_container);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -769,7 +770,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_container);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IMAPIFolder.c
===================================================================
--- trunk/openchange/libmapi/IMAPIFolder.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPIFolder.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -97,7 +97,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -188,7 +188,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -277,7 +277,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -356,7 +356,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -462,7 +462,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -568,7 +568,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -718,7 +718,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_parent);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -805,7 +805,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -900,7 +900,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_parent);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1014,7 +1014,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1130,7 +1130,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1226,7 +1226,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1308,7 +1308,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IMAPIProp.c
===================================================================
--- trunk/openchange/libmapi/IMAPIProp.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPIProp.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -133,7 +133,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -257,7 +257,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -356,7 +356,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_child);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_parent);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -386,6 +386,9 @@
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
 
+     The developer MUST provide an allocated SPropTagArray structure
+     to the function.
+
    \sa GetProps, GetPropsAll, GetLastError
  */
 _PUBLIC_ enum MAPISTATUS GetPropList(mapi_object_t *obj, 
@@ -432,7 +435,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -444,7 +447,7 @@
 	proptags->cValues = mapi_response->mapi_repl->u.mapi_GetPropList.count;
 	if (proptags->cValues) {
 		size = proptags->cValues * sizeof(enum MAPITAGS);
-		proptags->aulPropTag = talloc_array((TALLOC_CTX *)session, enum MAPITAGS, proptags->cValues);
+		proptags->aulPropTag = talloc_array((TALLOC_CTX *) proptags, enum MAPITAGS, proptags->cValues);
 		memcpy((void*)proptags->aulPropTag,
 		       (void*)mapi_response->mapi_repl->u.mapi_GetPropList.tags,
 		       size);
@@ -527,7 +530,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -611,7 +614,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -724,7 +727,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -809,7 +812,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -901,7 +904,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1028,7 +1031,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1038,7 +1041,7 @@
 
 	/* Fill the SPropTagArray */
 	proptags[0]->cValues = mapi_response->mapi_repl->u.mapi_GetIDsFromNames.count;
-	proptags[0]->aulPropTag = talloc_array((TALLOC_CTX *)proptags[0], uint32_t, proptags[0]->cValues);
+	proptags[0]->aulPropTag = (enum MAPITAGS *) talloc_array((TALLOC_CTX *)proptags[0], uint32_t, proptags[0]->cValues);
 	for (i = 0; i < proptags[0]->cValues; i++) {
 		proptags[0]->aulPropTag[i] = (mapi_response->mapi_repl->u.mapi_GetIDsFromNames.propID[i] << 16) | PT_UNSPECIFIED;
 	}
@@ -1135,7 +1138,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx,mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1252,7 +1255,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1263,7 +1266,7 @@
 	if (problemCount) {
 		*problemCount = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblemCount;
 		*problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount);
-		for(i=0; i < *problemCount; ++i) {
+		for(i = 0; i < *problemCount; i++) {
 			(*(problems[i])).index = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].index;
 			(*(problems[i])).property_tag = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].property_tag;
 			(*(problems[i])).error_code = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblem[i].error_code;
@@ -1374,7 +1377,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IMAPISession.c
===================================================================
--- trunk/openchange/libmapi/IMAPISession.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPISession.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -30,6 +30,7 @@
 
 static enum MAPISTATUS FindGoodServer(struct mapi_session *session, const char *legacyDN, bool server)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi;
 	struct StringsArray_r	pNames;
@@ -47,56 +48,57 @@
 	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL);
 	OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
 
+	mem_ctx = talloc_named(NULL, 0, "FindGoodServer");
 	nspi = (struct nspi_context *) session->nspi->ctx;
 
 	if (server == false) {
 		/* Step 1. Retrieve a MID for our legacyDN */
 		pNames.Count = 0x1;
-		pNames.Strings = (const char **) talloc_array(nspi->mem_ctx, char **, 1);
+		pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
 		pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, legacyDN);
 
-		MId_array = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
-		retval = nspi_DNToMId(nspi, &pNames, &MId_array);
+		MId_array = talloc_zero(mem_ctx, struct SPropTagArray);
+		retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_array);
 		MAPIFreeBuffer(pNames.Strings);
-		OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+		OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 		/* Step 2. Retrieve the Server DN associated to this MId */
-		SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
-		SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x1, PR_EMS_AB_HOME_MDB);
-		retval = nspi_GetProps(nspi, SPropTagArray, MId_array, &SRowSet);
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_HOME_MDB);
+		retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_array, &SRowSet);
 		MAPIFreeBuffer(SPropTagArray);
 		MAPIFreeBuffer(MId_array);
-		OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+		OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 		HomeMDB = (char *)find_SPropValue_data(&(SRowSet->aRow[0]), PR_EMS_AB_HOME_MDB);
-		OPENCHANGE_RETVAL_IF(!HomeMDB, MAPI_E_NOT_FOUND, SRowSet);
-		server_dn = x500_truncate_dn_last_elements(nspi->mem_ctx, HomeMDB, 1);
+		OPENCHANGE_RETVAL_IF(!HomeMDB, MAPI_E_NOT_FOUND, mem_ctx);
+		server_dn = x500_truncate_dn_last_elements(mem_ctx, HomeMDB, 1);
 		MAPIFreeBuffer(SRowSet);
 	} else {
-		server_dn = talloc_strdup(nspi->mem_ctx, legacyDN);
+		server_dn = talloc_strdup(mem_ctx, legacyDN);
 	}
 
 	/* Step 3. Retrieve the MId for this server DN */
 	pNames.Count = 0x1;
-	pNames.Strings = (const char **) talloc_array(nspi->mem_ctx, char **, 1);
+	pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
 	pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, server_dn);
-	MId_array = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
-	retval = nspi_DNToMId(nspi, &pNames, &MId_array);
+	MId_array = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_array);
 	MAPIFreeBuffer(pNames.Strings);
-	OPENCHANGE_RETVAL_IF(retval, retval, server_dn);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	/* Step 4. Retrieve the binding strings associated to this DN */
-	SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
-	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
-	retval = nspi_GetProps(nspi, SPropTagArray, MId_array, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
+	retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_array, &SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(MId_array);
 	MAPIFreeBuffer(server_dn);
-	OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	/* Step 5. Extract host from ncacn_ip_tcp binding string */
 	MVszA = (struct StringArray_r *) find_SPropValue_data(&(SRowSet->aRow[0]), PR_EMS_AB_NETWORK_ADDRESS);
-	OPENCHANGE_RETVAL_IF(!MVszA, MAPI_E_NOT_FOUND, SRowSet);
+	OPENCHANGE_RETVAL_IF(!MVszA, MAPI_E_NOT_FOUND, mem_ctx);
 	for (i = 0; i != MVszA->cValues; i++) {
 		if (!strncasecmp(MVszA->lppszA[i], "ncacn_ip_tcp:", 13)) {
 			binding = MVszA->lppszA[i] + 13;
@@ -104,7 +106,7 @@
 		}
 	}
 	MAPIFreeBuffer(SRowSet);
-	OPENCHANGE_RETVAL_IF(!binding, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!binding, MAPI_E_NOT_FOUND, mem_ctx);
 
 	/* Step 6. Close the existing session and initiates it again */
 	talloc_free(session->emsmdb);
@@ -114,6 +116,8 @@
 	retval = Logon(session, session->emsmdb, PROVIDER_ID_EMSMDB);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
+	talloc_free(mem_ctx);
+
 	return MAPI_E_SUCCESS;
 }
 
@@ -192,7 +196,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -214,7 +218,7 @@
 	mapi_object_set_logon_store(obj_store);
 
 	/* retrieve store content */
-	obj_store->private_data = talloc((TALLOC_CTX *)session, mapi_object_store_t);
+	obj_store->private_data = talloc_zero((TALLOC_CTX *)session, mapi_object_store_t);
 	store = (mapi_object_store_t*)obj_store->private_data;
 	OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
 
@@ -228,7 +232,7 @@
 	store->fid_pf_LocalSiteFreeBusy = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[7];
 	store->fid_pf_LocalSiteOfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[8];
 	store->fid_pf_NNTPArticle = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[9];
-	store->cached_mailbox_fid = false;
+	store->store_type = PublicFolder;
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);
@@ -366,7 +370,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -377,8 +381,8 @@
 		retry = true;
 		goto retry;
 	}
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
+	OPENCHANGE_RETVAL_CALL_IF(retval, retval, mapi_response, mem_ctx);
 	OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
 
 	/* set object session, handle and logon_id */
@@ -388,7 +392,7 @@
 	mapi_object_set_logon_store(obj_store);
 
 	/* retrieve store content */
-	obj_store->private_data = talloc((TALLOC_CTX *)session, mapi_object_store_t);
+	obj_store->private_data = talloc_zero((TALLOC_CTX *)session, mapi_object_store_t);
 	store = (mapi_object_store_t *)obj_store->private_data;
 	OPENCHANGE_RETVAL_IF(!obj_store->private_data, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
 
@@ -405,7 +409,7 @@
 	store->fid_search = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[10];
 	store->fid_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[11];
 	store->fid_shortcuts = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[12];
-	store->cached_mailbox_fid = false;
+	store->store_type = PrivateFolderWithoutCachedFids;
 
 	talloc_free(mapi_response);
 	talloc_free(mem_ctx);

Modified: trunk/openchange/libmapi/IMAPISupport.c
===================================================================
--- trunk/openchange/libmapi/IMAPISupport.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPISupport.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -138,7 +138,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -310,7 +310,7 @@
 			while (notification->ulConnection) {
 				if ((notification->NotificationFlags & mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) && 
 				    (handle == mapi_object_get_handle(&(notification->obj_notif)))) {
-					if (notification->callback) {
+					if (notification->callback && NotificationData) {
 						notification->callback(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType,
 								       (void *)NotificationData,
 								       notification->private_data);
@@ -365,14 +365,15 @@
 /**
    \details Wait for notifications and process them
 
-   This function indefinively waits for notifications on the UDP port
+   This function waits for notifications on the UDP port
    and generates the traffic needed to receive MAPI
    notifications. These MAPI notifications are next compared to the
    registered ones and the callback specified in Subscribe() called if
    it matches.
 
-   Note that the function will loop indefinitively until an error
-   occurs.
+   The function takes a callback in cb_data to check if it should 
+   continue to process notifications. Timeval in cb_data can be
+   used to control the behavior of select.
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.  
 
@@ -388,37 +389,56 @@
    non-threaded, only supports fnevNewmail and fnevCreatedObject
    notifications and will block your process until you send a signal.
 */
-_PUBLIC_ enum MAPISTATUS MonitorNotification(struct mapi_session *session,
-					     void *private_data)
+_PUBLIC_ enum MAPISTATUS MonitorNotification(struct mapi_session *session, void *private_data, 
+					     struct mapi_notify_continue_callback_data *cb_data)
 {
 	struct mapi_response	*mapi_response;
 	struct mapi_notify_ctx	*notify_ctx;
-	enum MAPISTATUS		retval;
 	NTSTATUS		status;
 	int			is_done;
 	int			err;
 	char			buf[512];
-	
+	fd_set                  read_fds;
+	int                     nread;
+        mapi_notify_continue_callback_t callback;
+	void                    *data;
+	struct timeval          *tv;
+	enum MAPISTATUS		retval;
+
 	/* sanity checks */
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 
 	notify_ctx = session->notify_ctx;
+	callback = cb_data ? cb_data->callback : NULL;
+	data = cb_data ? cb_data->data : NULL;
+	tv = cb_data ? &cb_data->tv : NULL;
 
+	nread = 0;
 	is_done = 0;
 	while (!is_done) {
-		err = read(notify_ctx->fd, buf, sizeof(buf));
-		if (err > 0) {
-			status = emsmdb_transaction_null((struct emsmdb_context *)session->emsmdb->ctx, &mapi_response);
-			if (!NT_STATUS_IS_OK(status)) {
-				err = -1;
-			} else {
-				retval = ProcessNotification(notify_ctx, mapi_response);
-				OPENCHANGE_RETVAL_IF(retval, retval, NULL);
-			}
+	        FD_ZERO(&read_fds);
+		FD_SET(notify_ctx->fd, &read_fds);
+
+		err = select(notify_ctx->fd + 1, &read_fds, NULL, NULL, tv);
+		if (FD_ISSET(notify_ctx->fd, &read_fds)) {
+		        do {
+			         nread = read(notify_ctx->fd, buf, sizeof(buf));
+				 if (nread > 0) {
+			                status = emsmdb_transaction_null((struct emsmdb_context *)session->emsmdb->ctx,
+									 &mapi_response);
+					if (!NT_STATUS_IS_OK(status))
+					         err = -1;
+					else {
+					         retval = ProcessNotification(notify_ctx, mapi_response);
+						 OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+					}
+				 }
+			} while (nread > 0 && err != -1);
 		}
-		if (err <= 0) is_done = 1;
+		if ((callback != NULL && callback (data)) || err < 0)
+		        is_done = 1;
 	}
 
 	return MAPI_E_SUCCESS;

Modified: trunk/openchange/libmapi/IMAPITable.c
===================================================================
--- trunk/openchange/libmapi/IMAPITable.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMAPITable.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -98,7 +98,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -115,7 +115,7 @@
 	table = (mapi_object_table_t *)obj_table->private_data;
 	if (table) {
 		table->proptags.cValues = properties->cValues;
-		table->proptags.aulPropTag = talloc_array((TALLOC_CTX *)obj_table->private_data,
+		table->proptags.aulPropTag = talloc_array((TALLOC_CTX *) table,
 							  enum MAPITAGS, table->proptags.cValues);
 		memcpy((void*)table->proptags.aulPropTag, (void*)properties->aulPropTag,
 		       table->proptags.cValues * sizeof(enum MAPITAGS));
@@ -190,7 +190,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -291,7 +291,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -379,7 +379,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -481,7 +481,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -581,7 +581,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -681,7 +681,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -758,7 +758,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -875,7 +875,7 @@
 			mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 			mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-			status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+			status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 			OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 			OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 			retval = mapi_response->mapi_repl->error_code;
@@ -969,7 +969,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1103,7 +1103,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1207,7 +1207,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1335,7 +1335,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1428,7 +1428,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 	
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1498,7 +1498,7 @@
 	mapi_req->handle_idx = 0;
 	size += 5;
 
-	/* Fill the mapi_request stucture */
+	/* Fill the mapi_request structure */
 	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
 	mapi_request->mapi_len = size + sizeof (uint32_t);
 	mapi_request->length = size;
@@ -1506,7 +1506,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1617,7 +1617,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1719,7 +1719,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 	
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1817,7 +1817,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 	
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1913,7 +1913,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_table);
 	
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IMSProvider.c
===================================================================
--- trunk/openchange/libmapi/IMSProvider.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMSProvider.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,7 +1,7 @@
 /*
    OpenChange MAPI implementation.
 
-   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Julien Kerihuel 2007-2009.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -32,7 +32,6 @@
    \brief Provider operations
 */
 
-
 /*
  * Log MAPI to one instance of a message store provider
  */
@@ -70,17 +69,60 @@
 
 
 /**
+   \details Build the binding string and flags given profile and
+   global options.
+
+   \param mem_ctx pointer to the memory allocation context
+   \param server string representing the server FQDN or IP address
+   \param profile pointer to the MAPI profile structure
+
+   \return valid allocated string on success, otherwise NULL
+ */
+static char *build_binding_string(TALLOC_CTX *mem_ctx, 
+				  const char *server, 
+				  struct mapi_profile *profile)
+{
+	char	*binding;
+
+	/* Sanity Checks */
+	if (!profile) return NULL;
+	if (!server) return NULL;
+	if (!global_mapi_ctx) return NULL;
+
+	binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s[", server);
+	/* If dump-data option is enabled */
+	if (global_mapi_ctx->dumpdata == true) {
+		binding = talloc_strdup_append(binding, "print,");
+	}
+	/* If seal option is enabled in the profile */
+	if (profile->seal == true) {
+		binding = talloc_strdup_append(binding, "seal");
+	}
+
+	binding = talloc_strdup_append(binding, "]");
+
+	return binding;
+}
+
+/**
    \details Returns the name of an NSPI server
 
    \param session pointer to the MAPI session context
    \param server the Exchange server address (IP or FQDN)
    \param userDN optional user mailbox DN
 
-   \return a valid string on success, otherwise NULL
+   \return a valid allocated string on success, otherwise NULL.
+
+   \note The string returned can either be RfrGetNewDSA one on
+   success, or a copy of the server's argument one on failure. If no
+   server string is provided, NULL is returned.
+
+   It is up to the developer to free the returned string when
+   not needed anymore.
  */
-_PUBLIC_ const char *RfrGetNewDSA(struct mapi_session *session,
-				  const char *server, 
-				  const char *userDN)
+_PUBLIC_ char *RfrGetNewDSA(struct mapi_session *session,
+			    const char *server, 
+			    const char *userDN)
 {
 	NTSTATUS		status;
 	TALLOC_CTX		*mem_ctx;
@@ -88,31 +130,40 @@
 	struct RfrGetNewDSA	r;
 	struct dcerpc_pipe	*pipe;
 	char			*binding;
-	const char		*ppszServer = NULL;
+	char			*ppszServer = NULL;
 
 	/* Sanity Checks */
-	if (!global_mapi_ctx) return server;
-	if (!global_mapi_ctx->session) return server;
+	if (!global_mapi_ctx) return NULL;
+	if (!global_mapi_ctx->session) return NULL;
 
-	mem_ctx = (TALLOC_CTX *)session;
+	mem_ctx = talloc_named(NULL, 0, "RfrGetNewDSA");
 	profile = session->profile;
 
-	binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+	binding = build_binding_string(mem_ctx, server, profile);
 	status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, global_mapi_ctx->lp_ctx);
 	talloc_free(binding);
 
-	if (!NT_STATUS_IS_OK(status)) return server;
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
 
 
 	r.in.ulFlags = 0x0;
 	r.in.pUserDN = userDN ? userDN : "";
 	r.in.ppszUnused = NULL;
-	r.in.ppszServer = &ppszServer;
+	r.in.ppszServer = (const char **) &ppszServer;
 
 	status = dcerpc_RfrGetNewDSA(pipe, mem_ctx, &r);
-	if (!NT_STATUS_IS_OK(status)) return server;
+	if ((!NT_STATUS_IS_OK(status) || !ppszServer) && server) {
+		ppszServer = talloc_strdup((TALLOC_CTX *)session, server);
+	} else {
+		ppszServer = talloc_steal((TALLOC_CTX *)session, ppszServer);
+	}
 
-	return (ppszServer ? ppszServer : server);
+	talloc_free(mem_ctx);
+
+	return ppszServer;
 }
 
 
@@ -144,7 +195,7 @@
 	profile = session->profile;
 	*serverFQDN = NULL;
 
-	binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", profile->server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+	binding = build_binding_string(mem_ctx, profile->server, profile);
 	status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, global_mapi_ctx->lp_ctx);
 	talloc_free(binding);
 
@@ -176,6 +227,8 @@
 	struct dcerpc_pipe	*pipe;
 	struct mapi_profile	*profile;
 	char			*binding;
+	char			*server;
+	int			retval = 0;
 
 	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
@@ -185,7 +238,8 @@
 	
 	switch(provider_id) {
 	case PROVIDER_ID_EMSMDB:
-		binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", profile->server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+	emsmdb_retry:
+		binding = build_binding_string(mem_ctx, profile->server, profile);
 		status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_emsmdb, global_mapi_ctx->lp_ctx);
 		talloc_free(binding);
 		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL);
@@ -193,13 +247,19 @@
 		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_PORT_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL);
 		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT), MAPI_E_NETWORK_ERROR, NULL);
 		OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_LOGON_FAILED, NULL);
-		provider->ctx = emsmdb_connect(mem_ctx, session, pipe, profile->credentials);
+		provider->ctx = emsmdb_connect(mem_ctx, session, pipe, profile->credentials, &retval);
+		if (retval == ecNotEncrypted) {
+			profile->seal = true;
+			retval = 0;
+			goto emsmdb_retry;
+		}
 		OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL);
 		break;
 	case PROVIDER_ID_NSPI:
 		/* Call RfrGetNewDSA prior any NSPI call */
-		binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", RfrGetNewDSA(session, profile->server, profile->mailbox), 
-					  ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+		server = RfrGetNewDSA(session, profile->server, profile->mailbox);
+		binding = build_binding_string(mem_ctx, server, profile);
+		talloc_free(server);
 		status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_nsp, global_mapi_ctx->lp_ctx);
 		talloc_free(binding);
 		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL);

Modified: trunk/openchange/libmapi/IMessage.c
===================================================================
--- trunk/openchange/libmapi/IMessage.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMessage.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -121,7 +121,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -205,7 +205,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -287,7 +287,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -371,7 +371,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -461,7 +461,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -525,72 +525,144 @@
 }
 
 
-/*
- * EXPERIMENTAL:
- * bitmask calculation for recipients headers structures
+/**
+   \details RecipientFlags bitmask calculation for RecipientRows
+   structure.
+
+   \param aRow pointer to the SRow structures with the properties to
+   pass to ModifyRecipients.
+
+   According to MS-OXCDATA 2.9.3.1 RecipientFlags structure, the bitmask
+   can be represented as the following:
+
+   0      3   4   5   6   7   8   9  10  11         15   16
+   +------+---+---+---+---+---+---+---+---+----------+---+
+   | Type | E | D | T | S | R | N | U | I | Reserved | O |
+   +------+---+---+---+---+---+---+---+---+----------+---+
+   
+   Type: (0x7 mask) 3-bit enumeration describing the Address Type (PR_ADDRTYPE)
+   E: (0x8)    Email address included (PR_SMTP_ADDRESS)
+   D: (0x10)   Display Name included (PR_DISPLAY_NAME)
+   T: (0x20)   Transmittable Display Name included (PR_TRANSMITTABLE_DISPLAY_NAME)
+   S: (0x40)   If Transmittable Display Name is the same than Display Name (D == T)
+   R: (0x80)   Different transport is responsible for delivery
+   N: (0x100)  Recipient does not support receiving Rich Text messages
+   U: (0x200)  If we are using Unicode properties
+   I: (0x400)  If Simple Display Name is included (PR_7BIT_DISPLAY_NAME)
+   Reserved:   Must be zero
+   O: (0x8000) Non-standard address type is used
+
+   The PidTag property to bitmask mapping was unclear for some
+   fields. mapiproxy between Outlook 2003 and Exchange 2010 has been
+   used for this purpose.
+
+   For further information about PidTagAddressType, refer to
+   [MS-OXCMAIL] section 2.1.1.9
+
+   \return uint16_t holding the RecipientFlags value. 0 is returned
+   when an inconsistency or a failure occurs
+
  */
-uint16_t mapi_recipients_bitmask(struct SRow *aRow)
+uint16_t mapi_recipients_RecipientFlags(struct SRow *aRow)
 {
 	uint16_t		bitmask;
 	struct SPropValue	*lpProp = NULL;
+	bool			unicode = false;
+	const char		*addrtype = NULL;
+	const char		*tmp = NULL;
+	const char		*display_name = NULL;
+	const char		*transmit_display_name = NULL;
 
+	/* Sanity Checks */
+	if (!aRow) return 0;
+
 	bitmask = 0;
 
-	/* recipient type: EXCHANGE or SMTP */
+	/* (Type) - 0x0 to 0x7: PR_ADDRTYPE */
 	lpProp = get_SPropValue_SRow(aRow, PR_ADDRTYPE);
 	if (lpProp && lpProp->value.lpszA) {
-		if (!strcmp("SMTP", lpProp->value.lpszA)) {
-			bitmask |= 0xB;
-		}
+		addrtype = lpProp->value.lpszA;
 	} else {
-		/* (Bit 8) doesn't seem to work if unset */
-		bitmask |= 0x81;
+		lpProp = get_SPropValue_SRow(aRow, PR_ADDRTYPE_UNICODE);
+		if (lpProp && lpProp->value.lpszW) {
+			unicode = true;
+			addrtype = lpProp->value.lpszW;
+		} 
 	}
 
-	/* Bit 15: DISPLAY_NAME */
-	lpProp = get_SPropValue_SRow(aRow, PR_DISPLAY_NAME);
-	if (lpProp && lpProp->value.lpszA) {
-		bitmask |= 0x400;
+	if (!addrtype) {
+		return 0;
 	}
+	/* WARNING: This check is yet incomplete */
+	if (!strcmp("EX", addrtype)) { 
+		bitmask |= 0x1;
+	} else if (!strcmp("SMTP", addrtype)) {
+		bitmask |= 0x3;
+	}
 
-	lpProp = get_SPropValue_SRow(aRow, PR_DISPLAY_NAME_UNICODE);
-	if (lpProp && lpProp->value.lpszW) {
-		bitmask |= 0x600;
+	/* (E) - 0x8: PR_SMTP_ADDRESS (If we have Exchange type, we don't need it) */
+	if (strcmp(addrtype, "EX")) {
+		lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_SMTP_ADDRESS_UNICODE: PR_SMTP_ADDRESS);
+		if (lpProp) {
+			tmp = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA;
+			if (tmp) {
+				bitmask |= 0x8;
+			}
+		}
 	}
 
-	/* Bit 6: PR_GIVEN_NAME */
-	lpProp = get_SPropValue_SRow(aRow, PR_GIVEN_NAME);
-	if (lpProp && lpProp->value.lpszA) {
-		bitmask |= 0x20;
+	/* (D) - 0x10: PR_DISPLAY_NAME */
+	lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME);
+	if (lpProp) {
+		display_name = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA;
+		if (display_name) {
+			bitmask |= 0x10;
+		}
 	}
 
-	lpProp = get_SPropValue_SRow(aRow, PR_GIVEN_NAME_UNICODE);
-	if (lpProp && lpProp->value.lpszW) {
-		bitmask |= 0x220;
+	/* (T) - 0x20: PR_TRANSMITTABLE_DISPLAY_NAME */
+	lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE : PR_TRANSMITTABLE_DISPLAY_NAME);
+	if (lpProp) {
+		transmit_display_name = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA;
+		if (transmit_display_name) {
+			if (!display_name) {
+				bitmask |= 0x20;
+			} else if (display_name && strcmp(display_name, transmit_display_name)) {
+				bitmask |= 0x20;
+			}
+		}
 	}
 
-	/* Bit 5. PR_7BIT_DISPLAY_NAME */
-	lpProp = get_SPropValue_SRow(aRow, PR_7BIT_DISPLAY_NAME);
-	if (lpProp && lpProp->value.lpszA) {
-		bitmask |= 0x10;
+	/* (S) - 0x40: Does D equals T? If so, we shouldn't include PR_TRANSMITTABLE_DISPLAY_NAME within RecipientRows */
+	if (display_name && transmit_display_name) {
+		if (!strcmp(display_name, transmit_display_name)) {
+			bitmask |= 0x40;
+		}
 	}
 
-	lpProp = get_SPropValue_SRow(aRow, PR_7BIT_DISPLAY_NAME_UNICODE);
-	if (lpProp && lpProp->value.lpszW) {
-		bitmask |= 0x210;
+	/* (R) - 0x80: Different transport is responsible for delivery */
+	if (addrtype && strcmp(addrtype, "EX")) {
+		bitmask |= 0x80;
 	}
 
-	/* Bit 4: PR_EMAIL_ADDRESS */
-	if (bitmask & 0xA) {
-		lpProp = get_SPropValue_SRow(aRow, PR_SMTP_ADDRESS);
-		if (lpProp && lpProp->value.lpszA) {
-			bitmask |= 0x8;
+	/* (N) - 0x100: Recipient doesn't support rich-text messages */
+	lpProp = get_SPropValue_SRow(aRow, PR_SEND_RICH_INFO);
+	if (lpProp && (lpProp->value.b == false)) {
+		bitmask |= 0x100;
+	}
+
+	/* (U) - 0x200: Unicode properties */
+	if (unicode == true) {
+		bitmask |= 0x200;
+	}
+
+	/* (I) - 0x400: PR_7BIT_DISPLAY_NAME */
+	lpProp = get_SPropValue_SRow(aRow, (unicode == true) ? PR_7BIT_DISPLAY_NAME_UNICODE : PR_7BIT_DISPLAY_NAME);
+	if (lpProp) {
+		tmp = (unicode == true) ? lpProp->value.lpszW : lpProp->value.lpszA;
+		if (tmp) {
+			bitmask |= 0x400;
 		}
-		
-		lpProp = get_SPropValue_SRow(aRow, PR_SMTP_ADDRESS_UNICODE);
-		if (lpProp && lpProp->value.lpszW) {
-			bitmask |= 0x208;
-		}
 	}
 
 	return bitmask;
@@ -658,16 +730,25 @@
 	 */
 	request.properties = get_MAPITAGS_SRow(mem_ctx, &SRowSet->aRow[0]);
 	count = SRowSet->aRow[0].cValues - 1;
- 	request.prop_count = MAPITAGS_delete_entries(request.properties, count, 7,
+ 	request.prop_count = MAPITAGS_delete_entries(request.properties, count, 17,
+						     PR_ENTRYID,
 						     PR_DISPLAY_NAME,
 						     PR_DISPLAY_NAME_UNICODE,
+						     PR_DISPLAY_NAME_ERROR,
 						     PR_GIVEN_NAME,
 						     PR_GIVEN_NAME_UNICODE,
 						     PR_GIVEN_NAME_ERROR,
+						     PR_EMAIL_ADDRESS,
+						     PR_EMAIL_ADDRESS_UNICODE,
+						     PR_TRANSMITTABLE_DISPLAY_NAME,
+						     PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
 						     PR_RECIPIENT_TYPE,
-						     PR_ADDRTYPE);
+						     PR_ADDRTYPE,
+						     PR_ADDRTYPE_UNICODE,
+						     PR_ADDRTYPE_ERROR,
+						     PR_SEND_INTERNET_ENCODING,
+						     PR_SEND_INTERNET_ENCODING_ERROR);
 	size += request.prop_count * sizeof(uint32_t);
-
 	request.cValues = SRowSet->cRows;
 	size += sizeof(uint16_t);
 	request.RecipientRow = talloc_array(mem_ctx, struct ModifyRecipientRow, request.cValues);
@@ -693,77 +774,86 @@
 		request.RecipientRow[i_recip].RecipClass = (enum ulRecipClass) *RecipClass;
 		size += sizeof(uint8_t);
 		
-		RecipientRow->RecipientFlags = mapi_recipients_bitmask(aRow);
+		RecipientRow->RecipientFlags = mapi_recipients_RecipientFlags(aRow);
 		
-		/* recipient type EXCHANGE or SMTP */
-		switch (RecipientRow->RecipientFlags & 0xB) {
+		/* (Type) - 0x0 to 0x7: Recipient type (Exchange, SMTP or other?) */
+		switch (RecipientRow->RecipientFlags & 0x7) {
 		case 0x1: 
-			RecipientRow->type.EXCHANGE.organization_length = mapi_recipients_get_org_length(session->profile);
+		  //			RecipientRow->type.EXCHANGE.organization_length = mapi_recipients_get_org_length(session->profile);
+			RecipientRow->type.EXCHANGE.organization_length = 0;
 			RecipientRow->type.EXCHANGE.addr_type = SINGLE_RECIPIENT;
-			RecipientRow->type.EXCHANGE.username = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME);
+			switch (RecipientRow->RecipientFlags & 0x200) {
+			case 0x0:
+				RecipientRow->type.EXCHANGE.username = (const char *) find_SPropValue_data(aRow, PR_EMAIL_ADDRESS);
+				break;
+			case 0x200:
+				RecipientRow->type.EXCHANGE.username = (const char *) find_SPropValue_data(aRow, PR_EMAIL_ADDRESS_UNICODE);
+				break;
+			}
 			size += sizeof(uint32_t) + strlen(RecipientRow->type.EXCHANGE.username) + 1;
 			break;
-		case 0xB:
+		case 0x3:
 			size += sizeof(uint16_t);
 			break;
 		}
-		
-		/* Bit 15: PR_DISPLAY_NAME */
-		switch(RecipientRow->RecipientFlags & 0x600) {
-		case (0x400):
-			RecipientRow->SimpleDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME);
-			size += strlen(RecipientRow->SimpleDisplayName.lpszA) + 1;
-			break;
-		case (0x600):
-			RecipientRow->SimpleDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME_UNICODE);
-			size += strlen(RecipientRow->SimpleDisplayName.lpszW) * 2 + 2;
-			break;
-		default:
-			break;
-		}
 
-		/* Bit 6: PR_GIVEN_NAME */
-		switch (RecipientRow->RecipientFlags & 0x220) {
-		case (0x20):
-			RecipientRow->TransmittableDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_GIVEN_NAME);
-			size += strlen(RecipientRow->TransmittableDisplayName.lpszA) + 1;
+		/* (E) - 0x8: PR_SMTP_ADDRESS */
+		switch (RecipientRow->RecipientFlags & 0x208) {
+		case (0x8):
+			RecipientRow->EmailAddress.lpszA = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS);
+			size += strlen(RecipientRow->EmailAddress.lpszA) + 1;
 			break;
-		case (0x220):
-			RecipientRow->TransmittableDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_GIVEN_NAME_UNICODE);
-			size += strlen(RecipientRow->TransmittableDisplayName.lpszW) * 2 + 2;
+		case (0x208):
+			RecipientRow->EmailAddress.lpszW = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS_UNICODE);
+			size += strlen(RecipientRow->EmailAddress.lpszW) * 2 + 2;
 			break;
 		default:
 			break;
 		}
 
-		/* Bit 5: PR_7BIT_DISPLAY_NAME */
+		/* (D) - 0x10: PR_DISPLAY_NAME */
 		switch (RecipientRow->RecipientFlags & 0x210) {
 		case (0x10):
-			RecipientRow->DisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME);
+			RecipientRow->DisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME);
 			size += strlen(RecipientRow->DisplayName.lpszA) + 1;
 			break;
 		case (0x210):
-			RecipientRow->DisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME_UNICODE);
+			RecipientRow->DisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_DISPLAY_NAME_UNICODE);
 			size += strlen(RecipientRow->DisplayName.lpszW) * 2 + 2;
 			break;
 		default:
 			break;
 		}
 
-		/* Bit 4: PR_SMTP_ADDRESS */
-		switch (RecipientRow->RecipientFlags & 0x208) {
-		case (0x8):
-			RecipientRow->EmailAddress.lpszA = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS);
-			size += strlen(RecipientRow->EmailAddress.lpszA) + 1;
+		/* (T) - 0x20: PR_TRANSMITTABLE_DISPLAY_NAME */
+		switch (RecipientRow->RecipientFlags & 0x260) {
+		case (0x20):
+			RecipientRow->TransmittableDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_TRANSMITTABLE_DISPLAY_NAME);
+			size += strlen(RecipientRow->TransmittableDisplayName.lpszA) + 1;
 			break;
-		case (0x208):
-			RecipientRow->EmailAddress.lpszW = (const char *) find_SPropValue_data(aRow, PR_SMTP_ADDRESS_UNICODE);
-			size += strlen(RecipientRow->EmailAddress.lpszW) * 2 + 2;
+		case (0x220):
+			RecipientRow->TransmittableDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE);
+			size += strlen(RecipientRow->TransmittableDisplayName.lpszW) * 2 + 2;
 			break;
 		default:
 			break;
 		}
 		
+		
+		/* (I) - 0x400: PR_7BIT_DISPLAY_NAME */
+		switch(RecipientRow->RecipientFlags & 0x600) {
+		case (0x400):
+			RecipientRow->SimpleDisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME);
+			size += strlen(RecipientRow->SimpleDisplayName.lpszA) + 1;
+			break;
+		case (0x600):
+			RecipientRow->SimpleDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME_UNICODE);
+			size += strlen(RecipientRow->SimpleDisplayName.lpszW) * 2 + 2;
+			break;
+		default:
+			break;
+		}
+
 		RecipientRow->prop_count = request.prop_count;
 		size += sizeof(uint16_t);
 		RecipientRow->layout = 0;
@@ -809,7 +899,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -896,7 +986,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 	
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -977,7 +1067,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1058,7 +1148,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1152,7 +1242,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1248,7 +1338,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(parent);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1313,7 +1403,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1448,7 +1538,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_child);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1583,7 +1673,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_attach);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_embeddedmsg);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IMsgStore.c
===================================================================
--- trunk/openchange/libmapi/IMsgStore.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IMsgStore.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -93,7 +93,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -187,7 +187,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -275,7 +275,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -363,7 +363,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -454,7 +454,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -533,7 +533,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -635,7 +635,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -737,7 +737,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -829,7 +829,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -953,7 +953,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IProfAdmin.c
===================================================================
--- trunk/openchange/libmapi/IProfAdmin.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IProfAdmin.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,7 +1,7 @@
 /*
    OpenChange MAPI implementation.
 
-   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Julien Kerihuel 2007-2009.
    Copyright (C) Fabien Le Mentec 2007.
 
    This program is free software; you can redistribute it and/or modify
@@ -74,6 +74,7 @@
 	profile->mailbox = ldb_msg_find_attr_as_string(msg, "EmailAddress", NULL);
 	profile->homemdb = ldb_msg_find_attr_as_string(msg, "HomeMDB", NULL);
 	profile->server = ldb_msg_find_attr_as_string(msg, "binding", NULL);
+	profile->seal = ldb_msg_find_attr_as_bool(msg, "seal", false);
 	profile->org = ldb_msg_find_attr_as_string(msg, "Organization", NULL);
 	profile->ou = ldb_msg_find_attr_as_string(msg, "OrganizationUnit", NULL);
 	profile->codepage = ldb_msg_find_attr_as_int(msg, "codepage", 0);
@@ -1240,6 +1241,7 @@
 _PUBLIC_ enum MAPISTATUS ProcessNetworkProfile(struct mapi_session *session, const char *username,
 					       mapi_profile_callback_t callback, const void *private_data)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi;
 	struct SPropTagArray	*SPropTagArray = NULL;
@@ -1257,16 +1259,17 @@
 	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
 	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL);
 	
+	mem_ctx = talloc_named(NULL, 0, "ProcessNetworkProfile");
 	nspi = (struct nspi_context *) session->nspi->ctx;
 	profname = session->profile->profname;
 	index = 0;
 
-	SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
-	retval = nspi_GetSpecialTable(nspi, 0x0, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi, mem_ctx, 0x0, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
-	if (retval != MAPI_E_SUCCESS) return retval;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
-	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0xc,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xc,
 					  PR_DISPLAY_NAME,
 					  PR_OFFICE_TELEPHONE_NUMBER,
 					  PR_OFFICE_LOCATION,
@@ -1284,11 +1287,11 @@
 	/* Retrieve the username to match */
 	if (!username) {
 		username = cli_credentials_get_username(nspi->cred);
-		OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+		OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, mem_ctx);
 	}
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(nspi->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_ANR_UNICODE;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.lpszW = username;
@@ -1298,26 +1301,27 @@
 	Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(lpProp);
 	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
 		MAPIFreeBuffer(SRowSet);
+		talloc_free(mem_ctx);
 		return retval;
 	}
 
 	/* if there's no match */
-	OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_NOT_FOUND, NULL);
-	OPENCHANGE_RETVAL_IF(!SRowSet->cRows, MAPI_E_NOT_FOUND, NULL);
-	OPENCHANGE_RETVAL_IF(!MIds, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_NOT_FOUND, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!SRowSet->cRows, MAPI_E_NOT_FOUND, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!MIds, MAPI_E_NOT_FOUND, mem_ctx);
 
 	/* if SRowSet count is superior than 1 an callback is specified, call it */
 	if (SRowSet->cRows > 1 && callback) {
 		index = callback(SRowSet, private_data);
-		OPENCHANGE_RETVAL_IF((index >= SRowSet->cRows), MAPI_E_USER_CANCEL, NULL);
+		OPENCHANGE_RETVAL_IF((index >= SRowSet->cRows), MAPI_E_USER_CANCEL, mem_ctx);
 		instance_key = MIds->aulPropTag[index];
 	} else {
 		instance_key = MIds->aulPropTag[0];
@@ -1325,14 +1329,14 @@
 	MAPIFreeBuffer(MIds);
 	
 	MIds2.cValues = 0x1;
-	MIds2.aulPropTag = &instance_key;
+	MIds2.aulPropTag = (enum MAPITAGS *) &instance_key;
 
 	set_profile_attribute(profname, *SRowSet, index, PR_EMAIL_ADDRESS, "EmailAddress");
 	set_profile_attribute(profname, *SRowSet, index, PR_DISPLAY_NAME, "DisplayName");
 	set_profile_attribute(profname, *SRowSet, index, PR_ACCOUNT, "Account");
 	set_profile_attribute(profname, *SRowSet, index, PR_ADDRTYPE, "AddrType");
 
-	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x7,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x7,
 					  PR_DISPLAY_NAME,
 					  PR_EMAIL_ADDRESS,
 					  PR_DISPLAY_TYPE,
@@ -1348,19 +1352,19 @@
 	nspi->pStat->TotalRecs = 0x1;
 
 	MAPIFreeBuffer(SRowSet);
-	SRowSet = talloc(nspi->mem_ctx, struct SRowSet);
-	retval = nspi_QueryRows(nspi, SPropTagArray, &MIds2, 1, &SRowSet);
+	SRowSet = talloc(mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi, mem_ctx, SPropTagArray, &MIds2, 1, &SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
-	if (retval != MAPI_E_SUCCESS) return retval;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	lpProp = get_SPropValue_SRowSet(SRowSet, PR_EMS_AB_HOME_MDB);
-	OPENCHANGE_RETVAL_IF(!lpProp, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!lpProp, MAPI_E_NOT_FOUND, mem_ctx);
 
-	nspi->org = x500_get_dn_element(nspi->mem_ctx, lpProp->value.lpszA, ORG);
-	nspi->org_unit = x500_get_dn_element(nspi->mem_ctx, lpProp->value.lpszA, ORG_UNIT);
+	nspi->org = x500_get_dn_element(mem_ctx, lpProp->value.lpszA, ORG);
+	nspi->org_unit = x500_get_dn_element(mem_ctx, lpProp->value.lpszA, ORG_UNIT);
 	
-	OPENCHANGE_RETVAL_IF(!nspi->org_unit, MAPI_E_INVALID_PARAMETER, NULL);
-	OPENCHANGE_RETVAL_IF(!nspi->org, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!nspi->org_unit, MAPI_E_INVALID_PARAMETER, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!nspi->org, MAPI_E_INVALID_PARAMETER, mem_ctx);
 
 	retval = mapi_profile_add_string_attr(profname, "Organization", nspi->org);
 	retval = mapi_profile_add_string_attr(profname, "OrganizationUnit", nspi->org_unit);
@@ -1371,29 +1375,27 @@
 	set_profile_mvstr_attribute(profname, *SRowSet, 0, PR_EMS_AB_PROXY_ADDRESSES, "ProxyAddress");
 
 	pNames.Count = 0x1;
-	pNames.Strings = (const char **) talloc_array(nspi->mem_ctx, char **, 1);
-	pNames.Strings[0] = (const char *) talloc_asprintf(nspi->mem_ctx, SERVER_DN, 
+	pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
+	pNames.Strings[0] = (const char *) talloc_asprintf(mem_ctx, SERVER_DN, 
 							   nspi->org, nspi->org_unit, 
 							   nspi->servername);
-	MId_server = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
-	retval = nspi_DNToMId(nspi, &pNames, &MId_server);
+	MId_server = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_DNToMId(nspi, mem_ctx, &pNames, &MId_server);
 	MAPIFreeBuffer((char *)pNames.Strings[0]);
 	MAPIFreeBuffer((char **)pNames.Strings);
-	if (retval != MAPI_E_SUCCESS) return retval;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	MAPIFreeBuffer(SRowSet);
-	SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
-	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
-	retval = nspi_GetProps(nspi, SPropTagArray, MId_server, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
+	retval = nspi_GetProps(nspi, mem_ctx, SPropTagArray, MId_server, &SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(MId_server);
-	if (retval != MAPI_E_SUCCESS) {
-		MAPIFreeBuffer(SRowSet);
-		return retval;
-	}
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	set_profile_mvstr_attribute(profname, *SRowSet, 0, PR_EMS_AB_NETWORK_ADDRESS, "NetworkAddress");
 	MAPIFreeBuffer(SRowSet);
+	talloc_free(mem_ctx);
 
 	return MAPI_E_SUCCESS;
 }

Modified: trunk/openchange/libmapi/IStoreFolder.c
===================================================================
--- trunk/openchange/libmapi/IStoreFolder.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IStoreFolder.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -46,6 +46,7 @@
    - 0x0: read only access
    - 0x1: ReadWrite
    - 0x3: Create
+   - 0x4: OpenSoftDeleted
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 
@@ -72,6 +73,7 @@
 	struct mapi_session		*session;
 	mapi_object_message_t		*message;
 	struct SPropValue		lpProp;
+	const char			*tstring;
 	NTSTATUS			status;
 	enum MAPISTATUS			retval;
 	uint32_t			size = 0;
@@ -115,7 +117,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -132,6 +134,18 @@
 	reply = &mapi_response->mapi_repl->u.mapi_OpenMessage;
 
 	message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t);
+
+	tstring = get_TypedString(&reply->SubjectPrefix);
+	if (tstring) {
+		message->SubjectPrefix = talloc_strdup((TALLOC_CTX *)message, tstring);
+	}
+
+	tstring = get_TypedString(&reply->NormalizedSubject);
+	if (tstring) {
+		message->NormalizedSubject = talloc_strdup((TALLOC_CTX *)message, tstring);
+	}
+	
+
 	message->cValues = reply->RecipientColumns.cValues;
 	message->SRowSet.cRows = reply->RowCount;
 	message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
@@ -173,17 +187,8 @@
    This function is very similar to OpenMessage, but works on an already
    open message object.
 
-   \param obj_store the store to read from
-   \param id_folder the folder ID
-   \param id_message the message ID
-   \param obj_message the resulting message object
-   \param ulFlags
+   \param obj_message the message object to retrieve the properties for.
 
-   Possible ulFlags values:
-   - 0x0: read only access
-   - 0x1: ReadWrite
-   - 0x3: Create
-
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
 
    \note Developers may also call GetLastError() to retrieve the last
@@ -243,7 +248,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_message);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IStream.c
===================================================================
--- trunk/openchange/libmapi/IStream.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IStream.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -49,7 +49,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI
    error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_PARAMETER: A problem occured obtaining the session context
+   - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
 
@@ -112,7 +112,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_related);
 	mapi_request->handles[1] = 0xffffffff;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -149,7 +149,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error. Possible MAPI
    error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_PARAMETER: A problem occured obtaining the session context
+   - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session context
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
 
@@ -210,7 +210,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -250,7 +250,7 @@
    \note Developers may also call GetLastError() to retrieve the last
    MAPI error code. Possible MAPI error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_PARAMETER: A problem occured obtaining the session
+   - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session
      context, or blob was null.
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
@@ -312,7 +312,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -386,7 +386,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -458,7 +458,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -555,7 +555,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -634,7 +634,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -734,7 +734,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
 
-	status = emsmdb_transaction(session[0]->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session[0]->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -825,7 +825,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -908,7 +908,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -985,7 +985,7 @@
 	mapi_request->handles[0] = mapi_object_get_handle(obj_src);
 	mapi_request->handles[1] = 0xFFFFFFFF;
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -1017,7 +1017,7 @@
    \note Developers may also call GetLastError() to retrieve the last
    MAPI error code. Possible MAPI error codes are:
    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
-   - MAPI_E_INVALID_PARAMETER: A problem occured obtaining the session
+   - MAPI_E_INVALID_PARAMETER: A problem occurred obtaining the session
      context, or the stream or blob were null.
    - MAPI_E_CALL_FAILED: A network problem was encountered during the
      transaction
@@ -1080,7 +1080,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IUnknown.c
===================================================================
--- trunk/openchange/libmapi/IUnknown.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IUnknown.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -146,7 +146,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 
 	OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
@@ -165,8 +165,9 @@
    This function returns the error code set by a previous function
    call.
 
-   \note Calls to the function won't work in multi-threaded or
-   multisession code.
+   \note Calls to this function may not work reliably in multi-threaded or
+   multisession code. We suggest you capture the return value of the call,
+   and check that instead.
 */
 _PUBLIC_ enum MAPISTATUS GetLastError(void)
 {
@@ -240,7 +241,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -328,7 +329,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/IXPLogon.c
===================================================================
--- trunk/openchange/libmapi/IXPLogon.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/IXPLogon.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -90,7 +90,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -166,7 +166,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;
@@ -257,7 +257,7 @@
 	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
 	mapi_request->handles[0] = mapi_object_get_handle(obj_store);
 
-	status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+	status = emsmdb_transaction(session->emsmdb->ctx, mem_ctx, mapi_request, &mapi_response);
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
 	OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
 	retval = mapi_response->mapi_repl->error_code;

Modified: trunk/openchange/libmapi/cdo_mapi.c
===================================================================
--- trunk/openchange/libmapi/cdo_mapi.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/cdo_mapi.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -20,7 +20,6 @@
 
 #include <libmapi/libmapi.h>
 #include <libmapi/proto_private.h>
-#include <libmapi/dlinklist.h>
 #include <param.h>
 #include <ldb.h>
 
@@ -242,7 +241,7 @@
 	setup_logging(NULL, DEBUG_STDOUT);
 
 	/* profile store */
-	retval = OpenProfileStore(mem_ctx, &global_mapi_ctx->ldb_ctx, profiledb);
+	retval = OpenProfileStore(global_mapi_ctx, &global_mapi_ctx->ldb_ctx, profiledb);
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
 
 	/* Initialize dcerpc subsystem */

Modified: trunk/openchange/libmapi/conf/build.sh
===================================================================
--- trunk/openchange/libmapi/conf/build.sh	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/conf/build.sh	2010-02-11 11:16:26 UTC (rev 3288)
@@ -3,3 +3,4 @@
 ./libmapi/conf/mparse.pl --parser=mapitags --outputdir=libmapi/ libmapi/conf/mapi-properties
 ./libmapi/conf/mparse.pl --parser=mapicodes --outputdir=libmapi/ libmapi/conf/mapi-codes
 ./libmapi/conf/mparse.pl --parser=mapi_nameid --outputdir=libmapi/ libmapi/conf/mapi-named-properties
+./libmapi/conf/mparse.pl --parser=codepage_lcid --outputdir=libmapi/ libmapi/conf/codepage-lcid
\ No newline at end of file

Added: trunk/openchange/libmapi/conf/codepage-lcid
===================================================================
--- trunk/openchange/libmapi/conf/codepage-lcid	                        (rev 0)
+++ trunk/openchange/libmapi/conf/codepage-lcid	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,224 @@
+
+#   OpenChange MAPI implementation.
+#
+#   Copyright (C) Julien Kerihuel 2010.
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 3 of the License, or
+#   (at your option) any later version.
+#   
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#   
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Lines starting with # are commented and not processed.
+# Locale using '_' underscore characters will automatically be
+# replaced by space once processed.
+
+#
+# Defines for Language group
+#
+DEFINE	CP_UNICODE_ONLY			0
+DEFINE	CP_WESTERN_EUROPE_AND_US	1
+DEFINE	CP_CENTRAL_EUROPE		2
+DEFINE	CP_BALTIC			3
+DEFINE	CP_GREEK			4
+DEFINE	CP_CYRILLIC			5
+DEFINE	CP_TURKIC			6
+DEFINE	CP_JAPANESE			7
+DEFINE	CP_KOREAN			8
+DEFINE	CP_TRADITIONAL_CHINESE		9
+DEFINE	CP_SIMPLIFIED_CHINESE		10
+DEFINE	CP_THAI				11
+DEFINE	CP_HEBREW			12
+DEFINE	CP_ARABIC			13
+DEFINE	CP_VIETNAMESE			14
+DEFINE	CP_INDIC			15
+DEFINE	CP_GEORGIAN			16
+DEFINE	CP_ARMENIAN			17
+
+#Language     	     Locale		Language Tag	LCID (hex)	CodePage (dec)	Language Group
+
+Afrikaans      	      NULL     		 af_ZA	    	  0x0436	    1252     	CP_WESTERN_EUROPE_AND_US
+Albanian     	      NULL     		 sq_AL	    	  0x041c	    1250	CP_CENTRAL_EUROPE
+Amharic     	      Ethiopia 		 am_ET	 	  0x045e	    0		CP_UNICODE_ONLY
+Arabic	     	      Algeria		 ar_DZ	 	  0x1401	    1256	CP_ARABIC
+Arabic	     	      Bahrain		 ar_BH	 	  0x3c01	    1256	CP_ARABIC
+Arabic	     	      Egypt		 ar_EG	 	  0x0c01	    1256	CP_ARABIC
+Arabic	     	      Iraq		 ar_SA	 	  0x0801	    1256	CP_ARABIC
+Arabic	     	      Jordan		 ar_JO	 	  0x2c01	    1256	CP_ARABIC
+Arabic	     	      Kuwait		 ar_KW	 	  0x3401	    1256	CP_ARABIC
+Arabic	     	      Lebanon		 ar_LB	 	  0x3001	    1256	CP_ARABIC
+Arabic	     	      Libya		 ar_LY	 	  0x1001	    1256	CP_ARABIC
+Arabic	     	      Morocco		 ar_MA	 	  0x1801	    1256	CP_ARABIC
+Arabic	     	      Oman		 ar_OM	 	  0x2001	    1256	CP_ARABIC
+Arabic	     	      Qatar		 ar_QA	 	  0x4001	    1256	CP_ARABIC
+Arabic	     	      Saudi_Arabia	 ar_SA	 	  0x0401	    1256	CP_ARABIC
+Arabic	     	      Syria		 ar_SY	 	  0x2801	    1256	CP_ARABIC
+Arabic	     	      Tunisia		 ar_TN	 	  0x1c01	    1256	CP_ARABIC
+Arabic	     	      U.A.E.		 ar_AE	 	  0x3801	    1256	CP_ARABIC
+Arabic	     	      Yemen		 ar_YE	 	  0x2401	    1256	CP_ARABIC
+Armenian     	      NULL		 hy_AM	 	  0x042b	    0		CP_ARMENIAN
+Assamese   	      NULL		 as_IN 	 	  0x044d	    0		CP_INDIC
+Azeri	     	      Cyrillic		 az_Cyrl_AZ	  0x082c	    1251	CP_CYRILLIC
+Azeri	     	      Latin		 az_Latn_AZ	  0x042c	    1254	CP_TURKIC
+Basque	     	      NULL		 eu_ES		  0x042d	    1252	CP_WESTERN_EUROPE_AND_US
+Belarusian   	      NULL		 be_BY		  0x0423	    1251	CP_CYRILLIC
+Bengali     	      India		 bn_IN		  0x0445	    0		CP_INDIC
+Bosnian     	      Bosnia/Herzegovina bs_Latn_BA	  0x141A	    1250	CP_CENTRAL_EUROPE
+Breton		      France		 br_FR		  0x047e	    1252	CP_WESTERN_EUROPE_AND_US
+Bulgarian    	      NULL		 bg_BG		  0x0402	    1251	CP_CYRILLIC
+Catalan	     	      NULL		 ca_ES		  0x0403	    1252	CP_WESTERN_EUROPE_AND_US
+Chinese	     	      Hong_Kong_S.A.R.	 zh_HK		  0x0c04	    950		CP_TRADITIONAL_CHINESE
+Chinese	     	      Macau_S.A.R.	 zh_MO		  0x1404	    950		CP_TRADITIONAL_CHINESE
+Chinese	     	      PRC		 zh_CN		  0x0804	    936		CP_SIMPLIFIED_CHINESE
+Chinese	     	      Singapore		 zh_SG		  0x1004	    936		CP_SIMPLIFIED_CHINESE
+Chinese	     	      Taiwan		 zh_TW		  0x0404	    950		CP_TRADITIONAL_CHINESE
+Croatian     	      NULL		 hr_HR		  0x041a	    1250	CP_CENTRAL_EUROPE
+Croatian    	      Bosnia/Herzegovina hr_BA	 	  0x101a	    1250	CP_CENTRAL_EUROPE
+Czech	     	      NULL		 cz_CZ		  0x0405	    1250	CP_CENTRAL_EUROPE
+Danish	     	      NULL		 da_DK		  0x0406	    1252	CP_WESTERN_EUROPE_AND_US
+Dari		      Afghanistan	 gbz_AF		  0x048c	    1256	CP_ARABIC
+Divehi	     	      NULL		 dv_MV		  0x0465	    0		CP_UNICODE_ONLY
+Dutch	     	      Belgium		 nl_BE		  0x0813	    1252	CP_WESTERN_EUROPE_AND_US
+Dutch	     	      Netherlands	 nl_NL		  0x0413	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Australia		 en_AU		  0x0c09	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Belize		 en_BZ		  0x2809	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Canada		 en_CA		  0x1009	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Caribbean		 en_CB		  0x2409	    1252	CP_WESTERN_EUROPE_AND_US
+English     	      India		 en_IN		  0x4009	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Ireland		 en_IE		  0x1809	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Jamaica		 en_JM		  0x2009	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      New_Zealand	 en_NZ		  0x1409	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Philippines	 en_PH		  0x3409	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      South_Africa	 en_ZA		  0x1c09	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Trinidad		 en_TT		  0x2c09	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      United_Kingdom	 en_GB		  0x0809	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      United_States	 en_US		  0x0409	    1252	CP_WESTERN_EUROPE_AND_US
+English	     	      Zimbabwe		 en_ZW		  0x3009	    1252	CP_WESTERN_EUROPE_AND_US
+Estonian     	      NULL		 et_EE		  0x0425	    1257	CP_BALTIC
+Faroese	     	      NULL		 fo_FO		  0x0438	    1252	CP_WESTERN_EUROPE_AND_US
+Farsi	     	      NULL		 fa_IR		  0x0429	    1256	CP_ARABIC
+Filipino    	      NULL		 fil_PH		  0x0464	    1252	CP_WESTERN_EUROPE_AND_US
+Finnish	     	      NULL		 fi_FI		  0x040b	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Belgium		 fr_BE		  0x080c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Cameroon		 fr_CM		  0x2c0c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Canada		 fr_CA		  0x0c0c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Congo,DRC		 fr_CG		  0x240c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Cote_d'Ivoire	 fr_CI		  0x300c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      France		 fr_FR		  0x040c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Luxembourg	 fr_LU		  0x140c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Mali		 fr_ML		  0x340c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Monaco		 fr_MC		  0x180c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Morocco		 fr_MA		  0x380c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Senegal		 fr_SN		  0x280c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      Switzerland	 fr_CH		  0x100c	    1252	CP_WESTERN_EUROPE_AND_US
+French	     	      West_Indies	 fr_West_Indies	  0x1c0c	    1252	CP_WESTERN_EUROPE_AND_US
+Frisian     	      Netherlands	 fy_NL		  0x0462	    1252	CP_WESTERN_EUROPE_AND_US
+FYRO_Macedonian	      NULL		 mk_MK	  	  0x042f	    1251	CP_CYRILLIC
+Gaelic_Ireland	      NULL		 ga_IE		  0x083c	    1252	CP_WESTERN_EUROPE_AND_US
+Galician	      Spain		 gl_ES		  0x0456	    1252	CP_WESTERN_EUROPE_AND_US
+Georgian	      NULL		 ka_GE		  0x0437	    0		CP_GEORGIAN
+German		      Austria		 de_AT		  0x0c07	    1252	CP_WESTERN_EUROPE_AND_US
+German		      Germany		 de_DE		  0x0407	    1252	CP_WESTERN_EUROPE_AND_US
+German		      Liechtenstein	 de_LI		  0x1407	    1252	CP_WESTERN_EUROPE_AND_US
+German		      Luxembourg	 de_LU		  0x1007	    1252	CP_WESTERN_EUROPE_AND_US
+German		      Switzerland	 de_CH		  0x0807	    1252	CP_WESTERN_EUROPE_AND_US
+Greek		      NULL		 el_GR		  0x0408	    1253	CP_GREEK
+Gujarati	      NULL		 gu_IN		  0x0447	    0		CP_INDIC
+Hebrew		      NULL		 he_IL		  0x040d	    1255	CP_HEBREW
+Hindi		      NULL		 hi_IN		  0x0439	    0		CP_INDIC
+Hungarian	      NULL		 hu_HU		  0x040e	    1250	CP_CENTRAL_EUROPE
+Icelandic	      NULL		 is_IS		  0x040f	    1252	CP_WESTERN_EUROPE_AND_US
+Igbo		      Nigeria		 ig_NG		  0x0470	    1252	CP_WESTERN_EUROPE_AND_US
+Indonesian	      NULL		 id_ID		  0x0421	    1252	CP_WESTERN_EUROPE_AND_US
+Italian		      Italy		 it_IT		  0x0410	    1252	CP_WESTERN_EUROPE_AND_US
+Italian		      Switzerland	 it_CH		  0x0810	    1252	CP_WESTERN_EUROPE_AND_US
+Japanese	      NULL		 ja_JP		  0x0411	    932		CP_JAPANESE
+Kannada	      	      NULL		 kn_IN		  0x044b	    0		CP_UNICODE_ONLY
+Kazakh		      NULL		 kk_KZ		  0x043f	    1251	CP_CYRILLIC
+Khmer		      NULL		 km_KH		  0x0453	    0		CP_UNICODE_ONLY
+Konkani	      	      NULL		 kok_IN		  0x0457	    0		CP_INDIC
+Korean		      NULL		 ko_KR		  0x0412	    949		CP_KOREAN
+Kyrgyz		      Cyrillic		 ky_KG		  0x0440	    1251	CP_CYRILLIC
+Lao		      NULL		 lo_LA		  0x0454	    0		CP_UNICODE_ONLY
+Latvian		      NULL		 lv_LV		  0x0426	    1257	CP_BALTIC
+Lithuanian	      NULL		 lt_LT		  0x0427	    1257	CP_BALTIC
+Macedonian	      NULL		 mk_MK		  0x042f	    1251	CP_CYRILLIC
+Malay		      Brunei_Darussalam	 ms_BN		  0x083e	    1252	CP_WESTERN_EUROPE_AND_US
+Malay		      Malaysia		 ms_MY		  0x043e	    1252	CP_WESTERN_EUROPE_AND_US
+Malayalam	      NULL		 ml_IN		  0x044c	    0		CP_UNICODE_ONLY
+Maltese	      	      NULL		 mt_MT		  0x043a	    1252	CP_WESTERN_EUROPE_AND_US
+Maori		      New_Zealand	 mi_NZ	  	  0x0481	    1252	CP_WESTERN_EUROPE_AND_US
+Marathi		      NULL		 ms_IN		  0x044e	    0		CP_INDIC
+Mongolian	      Cyrillic		 mn_MN		  0x0450	    1251	CP_CYRILLIC
+Mongolian	      Mongolia		 mn_Mong_CN	  0x0850	    0		CP_UNICODE_ONLY
+Nepali		      NULL		 ne_NP		  0x0461	    0		CP_UNICODE_ONLY
+Norwegian	      Bokmal		 nb_NO		  0x0414	    1252	CP_WESTERN_EUROPE_AND_US
+Norwegian	      Nynorsk		 nn_NO		  0x0814	    1252	CP_WESTERN_EUROPE_AND_US
+Oriya		      NULL		 or_IN		  0x0448	    0		CP_INDIC
+Polish		      NULL		 pl_PL		  0x0415	    1250	CP_CENTRAL_EUROPE
+Portuguese	      Brazil		 pt_BR		  0x0416	    1252	CP_WESTERN_EUROPE_AND_US
+Portuguese	      Portugal		 pt_PT		  0x0816	    1252	CP_WESTERN_EUROPE_AND_US
+Punjabi	      	      NULL		 pa_IN		  0x0446	    0		CP_INDIC
+Rhaeto-Romanic	      NULL		 rm_CH		  0x0417	    1252	CP_WESTERN_EUROPE_AND_US
+Romanian	      NULL		 ro_RM		  0x0418	    1250	CP_CENTRAL_EUROPE
+Romanian	      Moldova		 ro_MO		  0x0818	    819		CP_CENTRAL_EUROPE
+Russian		      NULL		 ru_RU		  0x0419	    1251	CP_CYRILLIC
+Sami_Lappish	      NULL		 se_NO		  0x043b	    1252	CP_WESTERN_EUROPE_AND_US
+Sanskrit	      NULL		 sa_IN		  0x044f	    0		CP_INDIC
+Serbian		      Cyrillic		 sr_Cyrl_CS	  0x0c1a	    1251	CP_CYRILLIC
+Serbian		      Latin		 sr_Latn_CS	  0x081a	    1250	CP_CENTRAL_EUROPE
+Sindhi		      NULL		 sd_IN		  0x0459	    0		CP_INDIC
+Sinhalese	      Sri_Lanka		 si_LK		  0x045b	    0		CP_UNICODE_ONLY
+Slovak		      NULL		 sk_SK		  0x041b	    1250	CP_CENTRAL_EUROPE
+Slovenian	      NULL		 sl_SI		  0x0424	    1250	CP_CENTRAL_EUROPE
+Spanish		      Argentina		 es_AR		  0x2c0a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Bolivia		 es_BO		  0x400a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Chile		 es_CL		  0x340a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Colombia		 es_CO		  0x240a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Costa_Rica	 es_CR		  0x140a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Dominican_Republic es_DO		  0x1c0a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Ecuador		 es_EC		  0x300a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      El_Salvador	 es_SV		  0x440a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Guatemala		 es_GT		  0x100a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Honduras		 es_HN		  0x480a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      International_Sort es_ES	  	  0x0c0a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Mexico		 es_MX		  0x080a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Nicaragua		 es_NI		  0x4c0a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Panama		 es_PA		  0x180a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Paraguay		 es_PY		  0x3c0a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Peru		 es_PE		  0x280a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Puerto_Rico	 es_PR		  0x500a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Traditional_Sort	 es_ES_tradnl	  0x040a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Uruguay		 es_UY		  0x380a	    1252	CP_WESTERN_EUROPE_AND_US
+Spanish		      Venezuela		 es_VE		  0x200a	    1252	CP_WESTERN_EUROPE_AND_US
+Swahili		      NULL		 sw_KE		  0x0441	    1252	CP_WESTERN_EUROPE_AND_US
+Swedish		      NULL		 sv_SE		  0x041d	    1252	CP_WESTERN_EUROPE_AND_US
+Swedish		      Finland		 sv_FI		  0x081d	    1252	CP_WESTERN_EUROPE_AND_US
+Tajik		      NULL	 	 tg_Cyrl_TJ	  0x0428	    1251	CP_CYRILLIC
+Tamil		      NULL		 ta_IN		  0x0449	    0		CP_INDIC
+Tatar		      NULL		 tt_RU		  0x0444	    1251	CP_CYRILLIC
+Telegu		      NULL		 te_IN		  0x044a	    0		CP_INDIC
+Thai		      NULL		 th_TH		  0x041e	    874		CP_THAI
+Tibetan	      	      NULL		 bo_CN		  0x0451	    0		CP_UNICODE_ONLY
+Tsonga		      NULL		 ts_ZA		  0x0431	    1252	CP_WESTERN_EUROPE_AND_US
+Twana		      NULL		 tn_ZA		  0x0432	    1252	CP_WESTERN_EUROPE_AND_US
+Turkish		      NULL		 tr_TR		  0x041f	    1254	CP_TURKIC
+Turkmen	      	      NULL		 tk_TM		  0x0442	    1251	CP_CYRILLIC
+Ukrainian	      NULL		 uk_UA		  0x0422	    1251	CP_CYRILLIC 
+Urdu		      NULL		 ur_PK		  0x0420	    1256	CP_ARABIC
+Uzbek		      Cyrillic		 uz_Cyrl_UZ	  0x0843	    1251	CP_CYRILLIC
+Uzbek		      Latin		 uz_Latn_UZ	  0x0443	    1254	CP_TURKIC
+Venda		      NULL		 ven_ZA		  0x0433	    1252	CP_WESTERN_EUROPE_AND_US
+Vietnamese	      NULL		 vi_VN		  0x042a	    1258	CP_VIETNAMESE
+Welsh		      NULL		 cy_GB		  0x0452	    1252	CP_WESTERN_EUROPE_AND_US
+Wolof		      Senegal		 wo_SN		  0x0488	    1252	CP_WESTERN_EUROPE_AND_US
+Xhosa		      NULL		 xh_ZA		  0x0434	    1252	CP_WESTERN_EUROPE_AND_US
+Zulu		      NULL		 zu_ZA		  0x0435	    1252	CP_WESTERN_EUROPE_AND_US

Modified: trunk/openchange/libmapi/conf/mapi-codes
===================================================================
--- trunk/openchange/libmapi/conf/mapi-codes	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/conf/mapi-codes	2010-02-11 11:16:26 UTC (rev 3288)
@@ -55,7 +55,7 @@
 0x80040200  MAPI_E_END_OF_SESSION
 0x80040201  MAPI_E_UNKNOWN_ENTRYID
 0x80040202  MAPI_E_MISSING_REQUIRED_COLUMN
-0x80040203  MAPI_W_NO_SERVICE
+0x00040203  MAPI_W_NO_SERVICE
 0x80040301  MAPI_E_BAD_VALUE
 0x80040302  MAPI_E_INVALID_TYPE
 0x80040303  MAPI_E_TYPE_NO_SUPPORT
@@ -63,18 +63,18 @@
 0x80040305  MAPI_E_TOO_BIG
 0x80040306  MAPI_E_DECLINE_COPY
 0x80040307  MAPI_E_UNEXPECTED_ID
-0x80040380  MAPI_W_ERRORS_RETURNED
+0x00040380  MAPI_W_ERRORS_RETURNED
 0x80040400  MAPI_E_UNABLE_TO_COMPLETE
 0x80040401  MAPI_E_TIMEOUT
 0x80040402  MAPI_E_TABLE_EMPTY
 0x80040403  MAPI_E_TABLE_TOO_BIG
 0x80040405  MAPI_E_INVALID_BOOKMARK
-0x80040481  MAPI_W_POSITION_CHANGED
-0x80040482  MAPI_W_APPROX_COUNT
+0x00040481  MAPI_W_POSITION_CHANGED
+0x00040482  MAPI_W_APPROX_COUNT
 0x80040500  MAPI_E_WAIT
 0x80040501  MAPI_E_CANCEL
 0x80040502  MAPI_E_NOT_ME
-0x80040580  MAPI_W_CANCEL_MESSAGE
+0x00040580  MAPI_W_CANCEL_MESSAGE
 0x80040600  MAPI_E_CORRUPT_STORE
 0x80040601  MAPI_E_NOT_IN_QUEUE
 0x80040602  MAPI_E_NO_SUPPRESS
@@ -87,7 +87,7 @@
 0x8004060A  MAPI_E_HAS_MESAGES
 0x8004060B  MAPI_E_FOLDER_CYCLE
 0x8004060D  MAPI_E_LOCKID_LIMIT
-0x80040680  MAPI_W_PARTIAL_COMPLETION
+0x00040680  MAPI_W_PARTIAL_COMPLETION
 0x80040700  MAPI_E_AMBIGUOUS_RECIP
 0x80040800  SYNC_E_OBJECT_DELETED
 0x80040801  SYNC_E_IGNORE
@@ -95,8 +95,8 @@
 0x80040803  SYNC_E_NO_PARENT
 0x80040804  SYNC_E_CYCLE_DETECTED
 0x80040805  SYNC_E_UNSYNCHRONIZED
-0x80040820  SYNC_W_PROGRESS
-0x80040821  SYNC_W_CLIENT_CHANGE_NEWER
+0x00040820  SYNC_W_PROGRESS
+0x00040821  SYNC_W_CLIENT_CHANGE_NEWER
 0x80040900  MAPI_E_NAMED_PROP_QUOTA_EXCEEDED
 0x80070005  MAPI_E_NO_ACCESS
 0x8007000E  MAPI_E_NOT_ENOUGH_MEMORY

Modified: trunk/openchange/libmapi/conf/mapi-properties
===================================================================
--- trunk/openchange/libmapi/conf/mapi-properties	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/conf/mapi-properties	2010-02-11 11:16:26 UTC (rev 3288)
@@ -569,7 +569,7 @@
 0x3fdb0003  PR_DL_REPORT_FLAGS
 0x3fdc0102  PR_BILATERAL_INFO
 0x3fdd0003  PR_MSG_BODY_ID
-0x3fde0003  PR_INTERNET_CPID
+0x3fde0003  PR_INTERNET_CPID		PidTagInternetCodepage
 0x3fdf0003  PR_AUTO_RESPONSE_SUPPRESS
 0x3fe0000d  PR_ACL_TABLE
 0x3fe00102  PR_ACL_DATA
@@ -602,7 +602,7 @@
 0x3ffa001e  PR_LAST_MODIFIER_NAME
 0x3ffb0102  PR_LAST_MODIFIER_ENTRYID
 0x3ffc001e  PR_REPLY_RECIPIENT_SMTP_PROXIES
-0x3ffd0003  PR_MESSAGE_CODEPAGE
+0x3ffd0003  PR_MESSAGE_CODEPAGE			PidTagMessageCodepage
 0x3ffe0102  PR_EXTENDED_ACL_DATA
 0x3fff000b  PR_FROM_I_HAVE
 0x40000003  PR_NEW_ATTACH

Modified: trunk/openchange/libmapi/conf/mparse.pl
===================================================================
--- trunk/openchange/libmapi/conf/mparse.pl	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/conf/mparse.pl	2010-02-11 11:16:26 UTC (rev 3288)
@@ -38,8 +38,9 @@
     0x1e	=> "PT_STRING8",
     0x1f	=> "PT_UNICODE",
     0x40	=> "PT_SYSTIME",
+    0x48	=> "PT_CLSID",
+    0xFD	=> "PT_SRESTRICT",
     0xFE	=> "PT_ACTIONS",
-    0x48	=> "PT_CLSID",
     0x102	=> "PT_BINARY",
 # Multi-valued property types
     0x1002	=> "PT_MV_SHORT",
@@ -73,6 +74,7 @@
     "PT_UNICODE"	=>	0x1f,
     "PT_SYSTIME"	=>	0x40,
     "PT_CLSID"		=>	0x48,
+    "PT_SRESTRICT"	=>	0xfd,
     "PT_ACTIONS"	=>	0xfe,
     "PT_BINARY"		=>	0x102,
 # Multi-valued property types
@@ -523,6 +525,20 @@
     mparse "	}				\\";
     mparse "} while (0);";
     mparse "";
+    mparse "#define OPENCHANGE_RETVAL_CALL_IF(x,e,r,c)	\\";
+    mparse "do {					\\";
+    mparse "	if (x) {				\\";
+    mparse "		set_errno(e);			\\";
+    mparse "		if (r) {			\\";
+    mparse "			talloc_free(r);		\\";
+    mparse "		}				\\";
+    mparse "		if (c) {			\\";
+    mparse "			talloc_free(c);		\\";
+    mparse "		}				\\";
+    mparse "		return (e);			\\";
+    mparse "	}					\\";
+    mparse " } while (0);";
+    mparse "";
     mparse "#define OPENCHANGE_RETVAL_ERR(e,c)	\\";
     mparse "do {				\\";
     mparse "	set_errno(e);			\\";
@@ -778,6 +794,472 @@
 }
 
 #####################################################################
+# generate codepage_lcid.c file
+sub codepage_lcid_interface($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @params;
+    my $locale;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#include <libmapi/libmapi.h>";
+    mparse "#include <libmapi/proto_private.h>";
+    mparse "#include <locale.h>";
+    mparse "#include <langinfo.h>";
+    mparse "";
+    mparse "/**";
+    mparse "  \\file codepage_lcid.c";
+    mparse "";
+    mparse "  \\brief Codepage and Locale ID operations";
+    mparse " */";
+    mparse "";
+
+    # Step 1. Generate code for defines
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @params = split(/\s+/, $line);
+	    if ($params[0] eq "DEFINE") {
+		mparse sprintf "#define	%-30s %15d", $params[1], $params[2];
+	    }
+	}
+    }
+
+## We do not have yet convenient functions making use of this struct. This causes warning
+#    mparse "";
+#    mparse "static const char *language_group[] =";
+#    mparse "{";
+#    indent;
+#    foreach $line (@lines) {
+#	$line =~ s/^\#+.*$//;
+#	if ($line) {
+#	    @params = split(/\s+/, $line);
+#	    if ($params[0] eq "DEFINE") {
+#		mparse sprintf "\"%s\",", $params[1];
+#	    }
+#	}
+#    }
+#    mparse "NULL";
+#    deindent;
+#    mparse "};";
+#    mparse "";
+
+    # Step 2. Generate the locales array
+    mparse "struct cpid_lcid {";
+    indent;
+    mparse "const char	*language;";
+    mparse "const char	*locale;";
+    mparse "uint32_t	lcid;";
+    mparse "uint32_t	cpid;";
+    mparse "uint32_t	language_group;";
+    deindent;
+    mparse "};";
+    mparse "";
+
+    mparse "static const struct cpid_lcid locales[] =";
+    mparse "{";
+    indent;
+
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @params = split(/\s+/, $line);
+	    if ($params[0] ne "DEFINE") {
+
+		$params[0] = ($params[1] eq "NULL") ? (sprintf "\"%s\",", $params[0]) : 
+		    (sprintf "\"%s (%s)\",", $params[0], $params[1]);
+		$params[0] =~ s/_/ /g;
+		$params[2] = sprintf "\"%s\",", $params[2];
+		mparse sprintf "{ %-32s %-18s %-6s, %-4s, %-24s },", 
+		$params[0], $params[2], $params[3], $params[4], $params[5];		    
+	    }
+	}
+    }
+
+    mparse "{ NULL, NULL, 0, 0, 0 }";
+    deindent;
+    mparse "};";
+    mparse "";
+
+    # mapi_get_system_locale
+    mparse "/**";
+    mparse "  \\details Returns current locale used by the system";
+    mparse "";
+    mparse " \\return pointer to locale string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ char *mapi_get_system_locale(void)";
+    mparse "{";
+    indent;
+    mparse "char	*locale;";
+    mparse "";
+    mparse "locale = setlocale(LC_CTYPE, \"\");";
+    mparse "return locale;";
+    deindent;
+    mparse "}";
+    mparse "";   
+
+    # mapi_verify_cpid
+    mparse "/**";
+    mparse "  \\details Verify if the specified codepage is valid";
+    mparse "";
+    mparse "  \\param cpid the codepage to lookup";
+    mparse "";
+    mparse "  \\return 0 on success, otherwise 1";
+    mparse " */";
+    mparse "_PUBLIC_ bool mapi_verify_cpid(uint32_t cpid)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "for (i = 0; locales[i].lcid; i++) {";
+    indent;
+    mparse "if (cpid == locales[i].cpid) {";
+    indent;
+    mparse "return true;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return false;";
+    deindent;
+    mparse "}";
+    mparse "";   
+
+    # mapi_get_cpid_from_lcid
+    mparse "/**";
+    mparse "  \\details Returns codepage for a given LCID (Locale ID)";
+    mparse "";
+    mparse "  \\param lcid the locale ID to lookup";
+    mparse "";
+    mparse "  \\return non-zero codepage on success, otherwise 0 if";
+    mparse "   only unicode is supported for this language";
+    mparse " */";
+    mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_lcid(uint32_t lcid)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "for (i = 0; locales[i].lcid; i++) {";
+    indent;
+    mparse "if (lcid == locales[i].lcid) {";
+    indent;
+    mparse "return locales[i].cpid;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_cpid_from_locale
+    mparse "/**";
+    mparse "  \\details Return codepage associated to specified locale";
+    mparse "";
+    mparse "  \\param locale The locale string to lookup";
+    mparse "";
+    mparse "  \\return non-zero codepage on success, otherwise 0";
+    mparse " */";
+    mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_locale(const char *locale)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!locale) return 0;";
+    mparse "";
+    mparse "for (i = 0; locales[i].locale; i++) {";
+    indent;
+    mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {";
+    indent;
+    mparse "return locales[i].cpid;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_cpid_from_language
+    mparse "/**";
+    mparse "  \\details Return codepage associated to specified language";
+    mparse "";
+    mparse "  \\param language The language string to lookup";
+    mparse "";
+    mparse "  \\return non-zero codepage on success, otherwise 0";
+    mparse " */";
+    mparse "_PUBLIC_ uint32_t mapi_get_cpid_from_language(const char *language)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!language) return 0;";
+    mparse "";
+    mparse "for (i = 0; locales[i].language; i++) {";
+    indent;
+    mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {";
+    indent;
+    mparse "return locales[i].cpid;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_lcid_from_locale
+    mparse "/**";
+    mparse "  \\details Returns LCID (Locale ID) for a given locale";
+    mparse "";
+    mparse "  \\param locale the locale string to lookup";
+    mparse "";
+    mparse "  \\return non-zero LCID on success, otherwise 0";
+    mparse " */";
+    mparse "_PUBLIC_ uint32_t mapi_get_lcid_from_locale(const char *locale)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!locale) return 0;";
+    mparse "";
+    mparse "for (i = 0; locales[i].locale; i++) {";
+    indent;
+    mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {";
+    indent;
+    mparse "return locales[i].lcid;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_lcid_from_language
+    mparse "/**";
+    mparse "  \\details Returns LCID (Locale ID) for a given language";
+    mparse "";
+    mparse "  \\param language the language string to lookup";
+    mparse "";
+    mparse "  \\return non-zero LCID on success, otherwise 0";
+    mparse " */";
+    mparse "_PUBLIC_ uint32_t mapi_get_lcid_from_language(const char *language)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!language) return 0;";
+    mparse "";
+    mparse "for (i = 0; locales[i].language; i++) {";
+    indent;
+    mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {";
+    indent;
+    mparse "return locales[i].lcid;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_locale_from_lcid
+    mparse "/**";
+    mparse "  \\details Returns Locale for a given Locale ID";
+    mparse "";
+    mparse "  \\param lcid the locale ID to lookup";
+    mparse "";
+    mparse "  \\return locale string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ const char *mapi_get_locale_from_lcid(uint32_t lcid)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "for (i = 0; locales[i].lcid; i++) {";
+    indent;
+    mparse "if (locales[i].lcid == lcid) {";
+    indent;
+    mparse "return locales[i].locale;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_locale_from_language
+    mparse "/**";
+    mparse "  \\details Returns Locale for a given language";
+    mparse "";
+    mparse "  \\param language the language string to lookup";
+    mparse "";
+    mparse "  \\return Locale string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ const char *mapi_get_locale_from_language(const char *language)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!language) return NULL;";
+    mparse "";
+    mparse "for (i = 0; locales[i].language; i++) {";
+    indent;
+    mparse "if (locales[i].language && !strncmp(locales[i].language, language, strlen(locales[i].language))) {";
+    indent;
+    mparse "return locales[i].locale;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_language_from_locale
+       mparse "/**";
+    mparse "  \\details Returns Language for a given Locale";
+    mparse "";
+    mparse "  \\param locale the language string to lookup";
+    mparse "";
+    mparse "  \\return Language string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ const char *mapi_get_language_from_locale(const char *locale)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!locale) return NULL;";
+    mparse "";
+    mparse "for (i = 0; locales[i].locale; i++) {";
+    indent;
+    mparse "if (locales[i].locale && !strncmp(locales[i].locale, locale, strlen(locales[i].locale))) {";
+    indent;
+    mparse "return locales[i].language;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+ 
+    # mapi_get_language_from_lcid
+    mparse "/**";
+    mparse "  \\details Returns Language for a given Locale ID";
+    mparse "";
+    mparse "  \\param lcid the locale ID to lookup";
+    mparse "";
+    mparse "  \\return language string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ const char *mapi_get_language_from_lcid(uint32_t lcid)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "for (i = 0; locales[i].lcid; i++) {";
+    indent;
+    mparse "if (locales[i].lcid == lcid) {";
+    indent;
+    mparse "return locales[i].language;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # mapi_get_language_by_group
+        mparse "/**";
+    mparse "  \\details Returns List of languages for a given Language Group";
+    mparse "";
+    mparse "  \\param mem_ctx pointer to the memory context";
+    mparse "  \\param group the locale group to lookup";
+    mparse "";
+    mparse "  \\return Array of languages string on success, otherwise NULL";
+    mparse " */";
+    mparse "_PUBLIC_ char **mapi_get_language_from_group(TALLOC_CTX *mem_ctx, uint32_t group)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "uint32_t	counter = 0;";
+    mparse "char		**languages;";
+    mparse "";
+    mparse "/* Sanity Checks */";
+    mparse "if (!mem_ctx) return NULL;";
+    mparse "";
+    mparse "languages = talloc_array(mem_ctx, char *, counter + 1);";
+    mparse "for (i = 0; locales[i].language; i++) {";
+    indent;
+    mparse "if (locales[i].language_group == group) {";
+    indent;
+    mparse "languages = talloc_realloc(mem_ctx, languages, char *, counter + 1);";
+    mparse "languages[counter] = talloc_strdup(languages, locales[i].language);";
+    mparse "counter += 1;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "if (!counter) {";
+    indent;
+    mparse "talloc_free(languages);";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return languages;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    # assessor for mapidump_get_languages
+    mparse "void mapi_get_language_list(void)";
+    mparse "{";
+    indent;
+    mparse "uint32_t	i;";
+    mparse "";
+    mparse "for (i = 0; locales[i].language; i++) {";
+    indent;
+    mparse "printf(\"%s\\n\", locales[i].language);";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+}
+
+#####################################################################
 # generate swig_mapicodes.h file
 sub mapicodes_swig($)
 {
@@ -862,6 +1344,13 @@
 	FileSave($nameid_parser, mapi_nameid_header($contents));
     }
 
+    if ($opt_parser eq "codepage_lcid") {
+	print "Generating $outputdir" . "codepage_lcid.c\n";
+	$ret = '';
+	my $code_parser = ("$outputdir/codepage_lcid.c");
+	FileSave($code_parser, codepage_lcid_interface($contents));
+    }
+
     if ($opt_parser eq "swig_mapitags") {
 	print "Generating $outputdir" . "swig_mapitags.h\n";
 	$ret = '';

Deleted: trunk/openchange/libmapi/dlinklist.h
===================================================================
--- trunk/openchange/libmapi/dlinklist.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/dlinklist.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,110 +0,0 @@
-/* 
-   Unix SMB/CIFS implementation.
-   some simple double linked list macros
-   Copyright (C) Andrew Tridgell 1998
-   
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* To use these macros you must have a structure containing a next and
-   prev pointer */
-
-
-/* hook into the front of the list */
-#define DLIST_ADD(list, p) \
-do { \
-        if (!(list)) { \
-		(list) = (p); \
-		(p)->next = (p)->prev = NULL; \
-	} else { \
-		(list)->prev = (p); \
-		(p)->next = (list); \
-		(p)->prev = NULL; \
-		(list) = (p); \
-	}\
-} while (0)
-
-/* remove an element from a list - element doesn't have to be in list. */
-#ifndef DLIST_REMOVE
-#define DLIST_REMOVE(list, p) \
-do { \
-	if ((p) == (list)) { \
-		(list) = (p)->next; \
-		if (list) (list)->prev = NULL; \
-	} else { \
-		if ((p)->prev) (p)->prev->next = (p)->next; \
-		if ((p)->next) (p)->next->prev = (p)->prev; \
-	} \
-	if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
-} while (0)
-#endif
-
-/* promote an element to the top of the list */
-#define DLIST_PROMOTE(list, p) \
-do { \
-          DLIST_REMOVE(list, p); \
-          DLIST_ADD(list, p); \
-} while (0)
-
-/* hook into the end of the list - needs a tmp pointer */
-#define DLIST_ADD_END(list, p, type) \
-do { \
-		if (!(list)) { \
-			(list) = (p); \
-			(p)->next = (p)->prev = NULL; \
-		} else { \
-			type tmp; \
-			for (tmp = (list); tmp->next; tmp = tmp->next) ; \
-			tmp->next = (p); \
-			(p)->next = NULL; \
-			(p)->prev = tmp; \
-		} \
-} while (0)
-
-/* insert 'p' after the given element 'el' in a list. If el is NULL then
-   this is the same as a DLIST_ADD() */
-#define DLIST_ADD_AFTER(list, p, el) \
-do { \
-        if (!(list) || !(el)) { \
-		DLIST_ADD(list, p); \
-	} else { \
-		p->prev = el; \
-		p->next = el->next; \
-		el->next = p; \
-		if (p->next) p->next->prev = p; \
-	}\
-} while (0)
-
-/* demote an element to the end of the list, needs a tmp pointer */
-#define DLIST_DEMOTE(list, p, tmp) \
-do { \
-		DLIST_REMOVE(list, p); \
-		DLIST_ADD_END(list, p, tmp); \
-} while (0)
-
-/* concatenate two lists - putting all elements of the 2nd list at the
-   end of the first list */
-#define DLIST_CONCATENATE(list1, list2, type) \
-do { \
-		if (!(list1)) { \
-			(list1) = (list2); \
-		} else { \
-			type tmp; \
-			for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
-			tmp->next = (list2); \
-			if (list2) { \
-				(list2)->prev = tmp;	\
-			} \
-		} \
-} while (0)

Modified: trunk/openchange/libmapi/emsmdb.c
===================================================================
--- trunk/openchange/libmapi/emsmdb.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/emsmdb.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -18,6 +18,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <unistd.h>
+#include <fcntl.h>
 #include <libmapi/libmapi.h>
 #include <libmapi/proto_private.h>
 #include <gen_ndr/ndr_exchange.h>
@@ -70,13 +72,15 @@
    \param session pointer to the MAPI session context
    \param p pointer to the DCERPC pipe
    \param cred pointer to the user credentials
+   \param return_value pointer on EcDoConnect MAPI return value
 
    \return an allocated emsmdb_context on success, otherwise NULL
  */
 struct emsmdb_context *emsmdb_connect(TALLOC_CTX *parent_mem_ctx, 
 				      struct mapi_session *session,
 				      struct dcerpc_pipe *p, 
-				      struct cli_credentials *cred)
+				      struct cli_credentials *cred,
+				      int *return_value)
 {
 	TALLOC_CTX		*mem_ctx;
 	struct EcDoConnect	r;
@@ -89,6 +93,7 @@
 	if (!session) return NULL;
 	if (!p) return NULL;
 	if (!cred) return NULL;
+	if (!return_value) return NULL;
 
 	mem_ctx = talloc_named(NULL, 0, "emsmdb_connect");
 
@@ -119,14 +124,12 @@
 	r.out.pcRetry = &ret->info.pcRetry;
 	r.out.pcmsRetryDelay = &ret->info.pcmsRetryDelay;
 	r.out.picxr = &ret->info.picxr;
-	r.out.rgwServerVersion[0] = ret->info.rgwServerVersion[0];
-	r.out.rgwServerVersion[1] = ret->info.rgwServerVersion[1];
-	r.out.rgwServerVersion[2] = ret->info.rgwServerVersion[2];
 	r.out.pullTimeStamp = &pullTimeStamp;
 
 	status = dcerpc_EcDoConnect(p, mem_ctx, &r);
 	retval = r.out.result;
 	if (!NT_STATUS_IS_OK(status) || retval) {
+		*return_value = retval;
 		mapi_errstr("EcDoConnect", retval);
 		talloc_free(mem_ctx);
 		return NULL;
@@ -135,6 +138,10 @@
 	ret->info.szDisplayName = talloc_strdup(parent_mem_ctx, r.out.szDisplayName);
 	ret->info.szDNPrefix = talloc_strdup(parent_mem_ctx, r.out.szDNPrefix);
 
+	ret->info.rgwServerVersion[0] = r.out.rgwServerVersion[0];
+	ret->info.rgwServerVersion[1] = r.out.rgwServerVersion[1];
+	ret->info.rgwServerVersion[2] = r.out.rgwServerVersion[2];
+
 	ret->cred = cred;
 	ret->max_data = 0xFFF0;
 	ret->setup = false;
@@ -256,6 +263,8 @@
 {
 	struct mapi_response	*mapi_response = (struct mapi_response *)data;
 
+	if (!mapi_response) return 0;
+
 	if (mapi_response->mapi_repl) {
 		if (mapi_response->handles) {
 			talloc_free(mapi_response->handles);
@@ -274,6 +283,7 @@
    \details Make a EMSMDB transaction.
 
    \param emsmdb_ctx pointer to the EMSMDB connection context
+   \param mem_ctx pointer to the memory context
    \param req pointer to the MAPI request to send
    \param repl pointer on pointer to the MAPI reply returned by the
    server
@@ -281,10 +291,10 @@
    \return NT_STATUS_OK on success, otherwise NT status error
  */
 _PUBLIC_ NTSTATUS emsmdb_transaction(struct emsmdb_context *emsmdb_ctx, 
+				     TALLOC_CTX *mem_ctx,
 				     struct mapi_request *req, 
 				     struct mapi_response **repl)
 {
-	TALLOC_CTX		*mem_ctx;
 	struct EcDoRpc		r;
 	struct mapi_response	*mapi_response;
 	uint16_t		*length;
@@ -293,8 +303,6 @@
 	uint8_t			i = 0;
 
 start:
-	mem_ctx = talloc_named(NULL, 0, "emsmdb_transaction");
-
 	r.in.handle = r.out.handle = &emsmdb_ctx->handle;
 	r.in.size = emsmdb_ctx->max_data;
 	r.in.offset = 0x0;
@@ -326,18 +334,16 @@
 	r.in.length = r.out.length = length;
 	r.in.max_data = (*length >= 0x4000) ? 0x7FFF : emsmdb_ctx->max_data;
 
-	status = dcerpc_EcDoRpc(emsmdb_ctx->rpc_connection, emsmdb_ctx->mem_ctx, &r);
+	status = dcerpc_EcDoRpc(emsmdb_ctx->rpc_connection, mem_ctx, &r);
 	if (!NT_STATUS_IS_OK(status)) {
 		if (emsmdb_ctx->setup == false) {
 			errno = 0;
 			emsmdb_ctx->max_data = 0x7FFF;
 			emsmdb_ctx->setup = true;
 			talloc_free(mapi_response);
-			talloc_free(mem_ctx);
 			goto start;
 		} else {
 			talloc_free(mapi_response);
-			talloc_free(mem_ctx);
 			return status;
 		}
 	} else {
@@ -346,13 +352,12 @@
 	emsmdb_ctx->cache_size = emsmdb_ctx->cache_count = 0;
 
 	if (r.out.mapi_response->mapi_repl && r.out.mapi_response->mapi_repl->error_code) {
+		talloc_set_destructor((void *)mapi_response, NULL);
 		r.out.mapi_response->handles = NULL;
 	}
 
 	*repl = r.out.mapi_response;
 
-	talloc_free(mem_ctx);
-
 	return status;
 }
 
@@ -407,6 +412,8 @@
 		return NULL;
 	}
 
+	fcntl(notify_ctx->fd, F_SETFL, O_NONBLOCK);
+
 	if (bind(notify_ctx->fd, notify_ctx->addr, sizeof(struct sockaddr)) == -1) {
 		shutdown(notify_ctx->fd, SHUT_RDWR);
 		close(notify_ctx->fd);
@@ -507,6 +514,39 @@
 
 
 /**
+   \details Free property values retrieved with pull_emsmdb_property
+
+   \param lpProp pointer to SPropValue structure
+   \param data generic pointer to associated lpProp data
+
+ */
+void free_emsmdb_property(struct SPropValue *lpProp, void *data)
+{
+	if (!data) return;
+	if (!lpProp) return;
+
+	switch (lpProp->ulPropTag & 0xFFFF) {
+	case PT_I2:
+		talloc_free((uint16_t *)data);
+		break;
+	case PT_ERROR:
+	case PT_LONG:
+		talloc_free((uint32_t *)data);
+		break;
+	case PT_I8:
+		talloc_free((uint64_t *)data);
+		break;
+	case PT_BOOLEAN:
+		talloc_free((uint8_t *)data);
+		break;
+	default:
+		break;
+		
+	}
+}
+
+
+/**
    \details Retrieves a property value from a DATA blob
 
    \param mem_ctx pointer to the memory context
@@ -555,26 +595,26 @@
 		ndr_pull_uint16(ndr, NDR_SCALARS, pt_i2);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_i2;
+		return (const void *) pt_i2;
 	case PT_ERROR:
 	case PT_LONG:
 		pt_long = talloc_zero(mem_ctx, uint32_t);
 		ndr_pull_uint32(ndr, NDR_SCALARS, pt_long);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_long;
+		return (const void *) pt_long;
 	case PT_BOOLEAN:
 		pt_boolean = talloc_zero(mem_ctx, uint8_t);
 		ndr_pull_uint8(ndr, NDR_SCALARS, pt_boolean);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_boolean;
+		return (const void *) pt_boolean;
 	case PT_I8:
 		pt_i8 = talloc_zero(mem_ctx, uint64_t);
 		ndr_pull_hyper(ndr, NDR_SCALARS, pt_i8);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_i8;
+		return (const void *) pt_i8;
 	case PT_UNICODE:
 		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
 		ndr_pull_string(ndr, NDR_SCALARS, &pt_unicode);
@@ -592,13 +632,13 @@
 		ndr_pull_hyper(ndr, NDR_SCALARS, (uint64_t *) pt_filetime);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_filetime;
+		return (const void *) pt_filetime;
 	case PT_CLSID:
 		pt_clsid = talloc_zero(mem_ctx, struct GUID);
 		ndr_pull_GUID(ndr, NDR_SCALARS, pt_clsid);
 		*offset = ndr->offset;
 		talloc_free(ndr);
-		return (void *) pt_clsid;
+		return (const void *) pt_clsid;
 	case 0xFB:
 	case PT_BINARY:
 		ndr_pull_SBinary_short(ndr, NDR_SCALARS, &pt_binary);
@@ -607,7 +647,7 @@
 		sbin->cb = pt_binary.cb;
 		sbin->lpb = talloc_memdup(sbin, pt_binary.lpb, pt_binary.cb);
 		talloc_free(ndr);
-		return (void *) sbin;
+		return (const void *) sbin;
 	case PT_MV_LONG:
 		ndr_pull_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, &pt_MVl);
 		*offset = ndr->offset;
@@ -693,11 +733,13 @@
 
 		data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, tags->aulPropTag[i_tag], content);
 		if (data) {
-			talloc_steal(*propvals, data);
+			data = talloc_steal(*propvals, data);
 			p_propval = &((*propvals)[i_propval]);
 			p_propval->ulPropTag = tags->aulPropTag[i_tag];
 			p_propval->dwAlignPad = 0x0;
+
 			set_SPropValue(p_propval, data);
+			free_emsmdb_property(p_propval, (void *) data);
 			i_propval++;
 		}
 	}
@@ -782,6 +824,7 @@
 				data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, lpProps[prop].ulPropTag, content);
 				talloc_steal(lpProps, data);
 				set_SPropValue(&lpProps[prop], data);
+				free_emsmdb_property(&lpProps[prop], (void *) data);
 			}
 		}
 
@@ -840,6 +883,7 @@
 		aRow->lpProps[i].ulPropTag = aulPropTag;
 		aRow->lpProps[i].dwAlignPad = 0x0;
 		set_SPropValue(&(aRow->lpProps[i]), data);
+		free_emsmdb_property(&aRow->lpProps[i], (void *) data);
 	}
 	if (align) {
 		offset += align;

Modified: trunk/openchange/libmapi/freebusy.c
===================================================================
--- trunk/openchange/libmapi/freebusy.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/freebusy.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -104,7 +104,15 @@
 	o = x500_get_dn_element(mem_ctx, email, ORG);
 	ou = x500_get_dn_element(mem_ctx, email, ORG_UNIT);
 	username = x500_get_dn_element(mem_ctx, email, "/cn=Recipients/cn=");
-	
+
+	if (!username) {
+		MAPIFreeBuffer(o);
+		MAPIFreeBuffer(ou);
+		MAPIFreeBuffer(pRowSet);
+		
+		return MAPI_E_NOT_FOUND;
+	}
+
 	/* toupper username */
 	for (i = 0; username[i]; i++) {
 		username[i] = toupper((unsigned char)username[i]);

Modified: trunk/openchange/libmapi/libmapi.h
===================================================================
--- trunk/openchange/libmapi/libmapi.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/libmapi.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -35,6 +35,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <string.h>
 #include <stdarg.h>
@@ -49,12 +50,12 @@
 #include <util/debug.h>
 #include <tevent.h>
 #include <param.h>
+#include <dlinklist.h>
 
 /* OpenChange includes */
 #include <gen_ndr/exchange.h>
 #include <gen_ndr/property.h>
 
-#include <libmapi/dlinklist.h>
 #include <libmapi/version.h>
 #include <libmapi/nspi.h>
 #include <libmapi/emsmdb.h>

Modified: trunk/openchange/libmapi/mapi_notification.h
===================================================================
--- trunk/openchange/libmapi/mapi_notification.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/mapi_notification.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -27,6 +27,8 @@
 */
 typedef int (*mapi_notify_callback_t)(uint16_t, void *, void *);
 
+typedef int (*mapi_notify_continue_callback_t)(void *);
+
 struct notifications {
 	uint32_t		ulConnection;		/* connection number */
 	uint32_t		NotificationFlags;	/* events mask associated */
@@ -45,6 +47,12 @@
 	struct notifications	*notifications;
 };
 
+struct mapi_notify_continue_callback_data {
+        mapi_notify_continue_callback_t callback; /* Consulted for continuing processing events*/
+        void *data;                               /* Data for callback */
+        struct timeval tv;                        /* Timeout for Select call */
+};
+
 #define	DFLT_NOTIF_PORT	2500
 
 #endif /*!__MAPI_NOTIFICATION_H__ */

Modified: trunk/openchange/libmapi/mapi_object.h
===================================================================
--- trunk/openchange/libmapi/mapi_object.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/mapi_object.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -49,45 +49,53 @@
  * Interface objects
  */
 
+/**
+  IMsgStore store type
+  */
+enum MsgStoreType {
+	PrivateFolderWithoutCachedFids, /*!< Private folder store without the cached folder values filled in */
+	PrivateFolderWithCachedFids,  /*!< Private folder store with the cached folder values filled in */
+	PublicFolder  /*!< Public folder store */
+};
 
 /**
  * IMsgStore object 
  */
 typedef struct mapi_obj_store
 {
+	enum MsgStoreType	store_type;
 	/* Mailbox */
-	uint64_t	fid_mailbox_root;
-	uint64_t	fid_deferred_actions;
-	uint64_t	fid_spooler_queue;
-	uint64_t	fid_top_information_store;
-	uint64_t	fid_inbox;
-	uint64_t	fid_outbox;
-	uint64_t	fid_sent_items;
-	uint64_t	fid_deleted_items;
-	uint64_t	fid_common_views;
-	uint64_t	fid_schedule;
-	uint64_t	fid_search;
-	uint64_t	fid_views;
-	uint64_t	fid_shortcuts;
+	uint64_t		fid_mailbox_root;
+	uint64_t		fid_deferred_actions;
+	uint64_t		fid_spooler_queue;
+	uint64_t		fid_top_information_store;
+	uint64_t		fid_inbox;
+	uint64_t		fid_outbox;
+	uint64_t		fid_sent_items;
+	uint64_t		fid_deleted_items;
+	uint64_t		fid_common_views;
+	uint64_t		fid_schedule;
+	uint64_t		fid_search;
+	uint64_t		fid_views;
+	uint64_t		fid_shortcuts;
 	/* Public Folders */
-	uint64_t	fid_pf_public_root;
-	uint64_t	fid_pf_ipm_subtree;
-	uint64_t	fid_pf_non_ipm_subtree;
-	uint64_t	fid_pf_EFormsRegistryRoot;
-	uint64_t	fid_pf_FreeBusyRoot;
-	uint64_t	fid_pf_OfflineAB;
-	uint64_t	fid_pf_EFormsRegistry;
-	uint64_t	fid_pf_LocalSiteFreeBusy;
-	uint64_t	fid_pf_LocalSiteOfflineAB;
-	uint64_t	fid_pf_NNTPArticle;
+	uint64_t		fid_pf_public_root;
+	uint64_t		fid_pf_ipm_subtree;
+	uint64_t		fid_pf_non_ipm_subtree;
+	uint64_t		fid_pf_EFormsRegistryRoot;
+	uint64_t		fid_pf_FreeBusyRoot;
+	uint64_t		fid_pf_OfflineAB;
+	uint64_t		fid_pf_EFormsRegistry;
+	uint64_t		fid_pf_LocalSiteFreeBusy;
+	uint64_t		fid_pf_LocalSiteOfflineAB;
+	uint64_t		fid_pf_NNTPArticle;
 	/* cached data */
-	bool		cached_mailbox_fid;
-	uint64_t	fid_calendar;
-	uint64_t	fid_contact;
-	uint64_t	fid_journal;
-	uint64_t	fid_note;
-	uint64_t	fid_task;
-	uint64_t	fid_drafts;
+	uint64_t		fid_calendar;
+	uint64_t		fid_contact;
+	uint64_t		fid_journal;
+	uint64_t		fid_note;
+	uint64_t		fid_task;
+	uint64_t		fid_drafts;
 } mapi_object_store_t;
 
 
@@ -112,6 +120,8 @@
 
 typedef struct mapi_obj_message {
 	uint32_t			cValues;
+	char				*SubjectPrefix;
+	char				*NormalizedSubject;
 	struct SPropTagArray   		SPropTagArray;
 	struct SRowSet			SRowSet;
 } mapi_object_message_t;

Modified: trunk/openchange/libmapi/mapi_profile.h
===================================================================
--- trunk/openchange/libmapi/mapi_profile.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/mapi_profile.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,7 +1,7 @@
 /*
    OpenChange MAPI implementation.
 
-   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Julien Kerihuel 2007-2009.
    Copyright (C) Fabien Le Mentec 2007.
 
    This program is free software; you can redistribute it and/or modify
@@ -46,6 +46,7 @@
 	const char     		*domain;
 	const char     		*realm;
 	const char     		*server;
+	bool			seal;
 	uint32_t		codepage;
 	uint32_t		language;
 	uint32_t		method;

Modified: trunk/openchange/libmapi/mapidefs.h
===================================================================
--- trunk/openchange/libmapi/mapidefs.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/mapidefs.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -82,6 +82,11 @@
 #define MAPI_AMBIGUOUS		0x1
 #define MAPI_RESOLVED		0x2
 
+/* Positioning Minimal Entry IDs */
+#define	MID_BEGINNING_OF_TABLE	0x0
+#define	MID_CURRENT		0x1
+#define	MID_END_OF_TABLE	0x2
+
 /* Object Type */
 #define MAPI_STORE		0x1    	/* Message Store */
 #define MAPI_ADDRBOOK		0x2    	/* Address Book */

Modified: trunk/openchange/libmapi/mapidump.c
===================================================================
--- trunk/openchange/libmapi/mapidump.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/mapidump.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -20,8 +20,16 @@
 #include <libmapi/libmapi.h>
 #include <libmapi/mapidump.h>
 #include <libmapi/defs_private.h>
+#include <libmapi/proto_private.h>
 #include <time.h>
 
+#ifdef ENABLE_ASSERTS
+#include <assert.h>
+#define OC_ASSERT(x) assert(x)
+#else
+#define OC_ASSERT(x)
+#endif
+
 /**
    \file mapidump.c
 
@@ -44,6 +52,10 @@
 	
 
 	switch(lpProp.ulPropTag & 0xFFFF) {
+	case PT_SHORT:
+		data = get_SPropValue_data(&lpProp);
+		printf("%s%s: 0x%x\n", sep?sep:"", proptag, (*(const uint16_t *)data));
+		break;
 	case PT_BOOLEAN:
 		data = get_SPropValue_data(&lpProp);
 		printf("%s%s: 0x%x\n", sep?sep:"", proptag, (*(const uint8_t *)data));
@@ -58,11 +70,11 @@
 		printf("%s%s: %s\n", sep?sep:"", proptag, (data && (*(const uint32_t *)data) != MAPI_E_NOT_FOUND) ? (const char *)data : "NULL");
 		break;
 	case PT_SYSTIME:
-		mapidump_date_SPropValue(lpProp, proptag);
+		mapidump_date_SPropValue(lpProp, proptag, sep);
 		break;
 	case PT_ERROR:
 		data = get_SPropValue_data(&lpProp);
-		printf("%s%s: 0x%.8x\n", sep?sep:"", proptag, (*(const uint32_t *)data));
+		printf("%s%s_ERROR: 0x%.8x\n", sep?sep:"", proptag, (*(const uint32_t *)data));
 		break;
 	case PT_LONG:
 		data = get_SPropValue_data(&lpProp);
@@ -70,7 +82,7 @@
 		break;
 	case PT_BINARY:
 		data = get_SPropValue_data(&lpProp);
-		printf("%s%s\n", sep?sep:"", proptag);
+		printf("%s%s:\n", sep?sep:"", proptag);
 		dump_data(0, ((const struct Binary_r *)data)->lpb, ((const struct Binary_r *)data)->cb);
 		break;
 	case PT_MV_STRING8:
@@ -82,6 +94,8 @@
 		printf("%s\n", StringArray_r->lppszA[i]);
 		break;
 	default:
+		/* If you hit this assert, you'll need to implement whatever type is missing */
+		OC_ASSERT(0);
 		break;
 	}
 
@@ -131,7 +145,17 @@
 	}
 }
 
-
+/**
+  Output a row of the public address book
+  
+  \param aRow one row of the public address book (Global Address List)
+  
+  This function is usually used with GetGALTable, which can obtain several
+  rows at once - you'll need to iterate over the rows.
+  
+  The SRow is assumed to contain entries for PR_ADDRTYPE_UNICODE, PR_DISPLAY_NAME_UNICODE,
+  PR_EMAIL_ADDRESS_UNICODE and PR_ACCOUNT_UNICODE.
+*/
 _PUBLIC_ void mapidump_PAB_entry(struct SRow *aRow)
 {
 	const char	*addrtype;
@@ -196,8 +220,19 @@
 	talloc_free(mem_ctx);
 }
 
-
-_PUBLIC_ void mapidump_date_SPropValue(struct SPropValue lpProp, const char *label)
+/**
+  \details This function dumps a property containing a date / time to standard output
+  
+  If the property does not contain a PT_SYSTIME type value, then no output will occur.
+  
+  \param lpProp the property to dump
+  \param label the label to display prior to the time (e.g. the property tag)
+  \param sep a separator / spacer to insert in front of the label
+  
+  \note Prior to OpenChange 0.9, this function took 2 arguments, assuming a default separator of
+  a tab. You can get the old behaviour by using "\t" for sep.
+*/
+_PUBLIC_ void mapidump_date_SPropValue(struct SPropValue lpProp, const char *label, const char *sep)
 {
 	TALLOC_CTX		*mem_ctx;
 	NTTIME			time;
@@ -212,7 +247,7 @@
 		time = time << 32;
 		time |= filetime->dwLowDateTime;
 		date = nt_time_string(mem_ctx, time);
-		printf("\t%s:   %s\n", label, date);
+		printf("%s%s:   %s\n", sep, label, date);
 		fflush(0);
 	}
 
@@ -220,17 +255,74 @@
 }
 
 /**
-   \details This function dumps the properties relating to a message to standard output
+   \details This function dumps message information retrieved from
+   OpenMessage call. It provides a quick method to print message
+   summaries with information such as subject and recipients.
 
+   \param obj_message pointer to the MAPI message object to use
+ */
+_PUBLIC_ void mapidump_message_summary(mapi_object_t *obj_message)
+{
+	mapi_object_message_t		*msg;
+	int				*recipient_type;
+	const char			*recipient;
+	int				i;
+
+	if (!obj_message) return;
+	if (!obj_message->private_data) return;
+
+	msg = (mapi_object_message_t *) obj_message->private_data;
+
+	printf("Subject: ");
+	if (msg->SubjectPrefix) {
+		printf("[%s] ", msg->SubjectPrefix);
+	}
+
+	if (msg->NormalizedSubject) {
+		printf("%s", msg->NormalizedSubject);
+	}
+	printf("\n");
+
+	if (!&(msg->SRowSet)) return;
+	for (i = 0; i < msg->SRowSet.cRows; i++) {
+		recipient_type = (int *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_RECIPIENT_TYPE);
+		recipient = (const char *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_SMTP_ADDRESS_UNICODE);
+		if (!recipient) {
+			recipient = (const char *) find_SPropValue_data(&(msg->SRowSet.aRow[i]), PR_SMTP_ADDRESS);
+		}
+		if (recipient_type && recipient) {
+			switch (*recipient_type) {
+			case MAPI_ORIG:
+				printf("From: %s\n", recipient);
+				break;
+			case MAPI_TO:
+				printf("To: %s\n", recipient);
+				break;
+			case MAPI_CC:
+				printf("Cc: %s\n", recipient);
+				break;
+			case MAPI_BCC:
+				printf("Bcc: %s\n", recipient);
+				break;
+			}
+		}
+	}
+	printf("\n");
+}
+
+/**
+   \details This function dumps the properties relating to an email message to standard output
+
    The expected way to obtain the properties array is to use OpenMessage() to obtain the
    message object, then to use GetPropsAll() to obtain all the properties.
 
    \param properties array of message properties
    \param id identification to display for the message (can be NULL)
+   \param obj_msg pointer to the message MAPI object (can be NULL)
 
    \sa mapidump_appointment, mapidump_contact, mapidump_task, mapidump_note
 */
-_PUBLIC_ void mapidump_message(struct mapi_SPropValue_array *properties, const char *id)
+_PUBLIC_ void mapidump_message(struct mapi_SPropValue_array *properties, const char *id, mapi_object_t *obj_msg)
 {
 	const char			*msgid;
 	const char			*from;
@@ -288,11 +380,15 @@
 
 	printf("+-------------------------------------+\n");
 	printf("message id: %s %s\n", msgid ? msgid : "", id?id:"");
-	printf("subject: %s\n", subject ? subject : "");
-	printf("From: %s\n", from ? from : "");
-	printf("To:  %s\n", to ? to : "");
-	printf("Cc:  %s\n", cc ? cc : "");
-	printf("Bcc: %s\n", bcc ? bcc : "");
+	if (obj_msg) {
+		mapidump_message_summary(obj_msg);
+	} else {
+		printf("subject: %s\n", subject ? subject : "");
+		printf("From: %s\n", from ? from : "");
+		printf("To:  %s\n", to ? to : "");
+		printf("Cc:  %s\n", cc ? cc : "");
+		printf("Bcc: %s\n", bcc ? bcc : "");
+	}
 	if (has_attach) {
 		printf("Attachment: %s\n", *has_attach ? "True" : "False");
 	}
@@ -645,7 +741,107 @@
 	fflush(0);
 }
 
+_PUBLIC_ void mapidump_tags(enum MAPITAGS *Tags, uint16_t TagCount, const char *sep)
+{
+	uint32_t	i;
+	const char      *proptag;
+	for (i = 0; i < TagCount; i++) {
+		proptag = get_proptag_name(Tags[i]);
+		printf("%s Tag: %s\n", sep?sep:"", proptag);
+		fflush(0);
+	}
+}
 
+_PUBLIC_ void mapidump_foldercreated(struct FolderCreatedNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID);
+	fflush(0);
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+	mapidump_tags (data->Tags, data->TagCount, sep);
+}
+
+_PUBLIC_ void mapidump_folderdeleted(struct FolderDeletedNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID);
+	fflush(0);
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+}
+
+_PUBLIC_ void mapidump_foldermoved(struct FolderMoveCopyNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sParent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->ParentFID);
+	fflush(0);
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+	printf("%sOld Parent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldParentFID);
+	fflush(0);
+	printf("%sOld Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldFID);
+	fflush(0);
+}
+
+_PUBLIC_ void mapidump_foldercopied(struct FolderMoveCopyNotification *data, const char *sep)
+{
+	mapidump_foldermoved(data, sep);
+}
+
+_PUBLIC_ void mapidump_messagedeleted(struct MessageDeletedNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+	printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID);
+	fflush(0);
+}
+
+_PUBLIC_ void mapidump_messagecreated(struct MessageCreatedNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+	printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID);
+	fflush(0);
+	mapidump_tags (data->Tags, data->TagCount, sep);
+}
+
+_PUBLIC_ void mapidump_messagemodified(struct MessageModifiedNotification *data, const char *sep)
+{
+	mapidump_messagecreated((struct MessageCreatedNotification *)data, sep);
+}
+
+_PUBLIC_ void mapidump_messagemoved(struct MessageMoveCopyNotification *data, const char *sep)
+{
+	if (!data) {
+		return;
+	}
+	printf("%sFolder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->FID);
+	fflush(0);
+	printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->MID);
+	fflush(0);
+	printf("%sOld Parent Folder Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldFID);
+	fflush(0);
+	printf("%sOld Message Entry ID: 0x%"PRIx64"\n", sep?sep:"", data->OldMID);
+}
+
+_PUBLIC_ void mapidump_messagecopied(struct MessageMoveCopyNotification *data, const char *sep)
+{
+	mapidump_messagemoved(data, sep);
+}
+
 _PUBLIC_ const char *mapidump_freebusy_month(uint32_t month, uint32_t year)
 {
 	uint32_t	realmonth;
@@ -764,3 +960,11 @@
 		
 	}	
 }
+
+/**
+   \details print the list of languages OpenChange supports
+ */
+_PUBLIC_ void mapidump_languages_list(void)
+{
+	mapi_get_language_list();
+}

Modified: trunk/openchange/libmapi/nspi.c
===================================================================
--- trunk/openchange/libmapi/nspi.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/nspi.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -63,7 +63,7 @@
 /**
    \details Initiates a session between a client and the NSPI server.
 
-   \param mem_ctx pointer to the memory context
+   \param parent_ctx pointer to the memory context
    \param p pointer to the DCERPC pipe
    \param cred pointer to the user credentials
    \param codepage the code to set in the STAT structure
@@ -73,13 +73,14 @@
    \return Allocated pointer to a nspi_context structure on success,
    otherwise NULL
  */
-_PUBLIC_ struct nspi_context *nspi_bind(TALLOC_CTX *mem_ctx, 
+_PUBLIC_ struct nspi_context *nspi_bind(TALLOC_CTX *parent_ctx, 
 					struct dcerpc_pipe *p,
 					struct cli_credentials *cred, 
 					uint32_t codepage,
 					uint32_t language, 
 					uint32_t method)
 {
+	TALLOC_CTX		*mem_ctx;
 	struct NspiBind		r;
 	NTSTATUS		status;
 	enum MAPISTATUS		retval;
@@ -90,18 +91,20 @@
 	if (!p) return NULL;
 	if (!cred) return NULL;
 
-	ret = talloc(mem_ctx, struct nspi_context);
+	ret = talloc(parent_ctx, struct nspi_context);
 	ret->rpc_connection = p;
-	ret->mem_ctx = mem_ctx;
+	ret->mem_ctx = parent_ctx;
 	ret->cred = cred;
 	ret->version = 0;
 
 	/* Sanity Checks */
-	if (!(ret->pStat = nspi_set_STAT(mem_ctx, codepage, language, method))) {
+	if (!(ret->pStat = nspi_set_STAT((TALLOC_CTX *) ret, codepage, language, method))) {
 		talloc_free(ret);
 		return NULL;
 	}
 
+	mem_ctx = talloc_named(NULL, 0, "nspi_bind");
+
 	r.in.dwFlags = 0;
 
 	r.in.pStat = ret->pStat;
@@ -117,14 +120,15 @@
 
 	r.out.handle = &ret->handle;
 
-
 	status = dcerpc_NspiBind(p, mem_ctx, &r);
 	retval = r.out.result;
 	if ((!NT_STATUS_IS_OK(status)) || (retval != MAPI_E_SUCCESS)) {
 		talloc_free(ret);
+		talloc_free(mem_ctx);
 		return NULL;
 	}
 	
+	talloc_free(mem_ctx);
 	return ret;
 }
 
@@ -180,6 +184,7 @@
    reflect positioning changes requested by the client.
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param plDelta pointer to an unsigned long indicating movement
    within the address book container specified by the input parameter
    pStat.
@@ -187,6 +192,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_UpdateStat(struct nspi_context *nspi_ctx, 
+					 TALLOC_CTX *mem_ctx,
 					 uint32_t *plDelta)
 {
 	struct NspiUpdateStat		r;
@@ -195,6 +201,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!plDelta, MAPI_E_INVALID_PARAMETER, NULL);
 
 	r.in.handle = &nspi_ctx->handle;
@@ -206,7 +213,7 @@
 	r.out.pStat = nspi_ctx->pStat;
 	r.out.plDelta = r.in.plDelta;
 
-	status = dcerpc_NspiUpdateStat(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiUpdateStat(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -219,6 +226,7 @@
    \details Returns a number of Rows from a specified table.
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param pPropTags pointer to the list of proptags that the client
    requires to be returned for each row.
    \param MIds pointer to a list of values representing an Explicit
@@ -230,12 +238,12 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_QueryRows(struct nspi_context *nspi_ctx, 
+					TALLOC_CTX *mem_ctx,
 					struct SPropTagArray *pPropTags,
 					struct SPropTagArray *MIds, 
 					uint32_t count,
 					struct SRowSet **ppRows)
 {
-	TALLOC_CTX			*mem_ctx;
 	struct NspiQueryRows		r;
 	NTSTATUS			status;
 	enum MAPISTATUS			retval;
@@ -243,16 +251,15 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "nspi_QueryRows");
-
 	r.in.handle = &nspi_ctx->handle;
 	r.in.dwFlags = 0x0;
 	r.in.pStat = nspi_ctx->pStat;
 
 	if (MIds && MIds->cValues) {
 		r.in.dwETableCount = MIds->cValues;
-		r.in.lpETable = MIds->aulPropTag;
+		r.in.lpETable = (uint32_t *) MIds->aulPropTag;
 		/* We set CurrentRec to the first entry */
 		r.in.pStat->CurrentRec = MIds->aulPropTag[0];
 	} else {
@@ -268,18 +275,16 @@
 
 	r.out.ppRows = ppRows;
 
-	status = dcerpc_NspiQueryRows(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiQueryRows(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
 	nspi_ctx->pStat->CurrentRec = r.out.pStat->CurrentRec;
 	nspi_ctx->pStat->Delta = r.out.pStat->Delta;
 	nspi_ctx->pStat->NumPos = r.out.pStat->NumPos;
 	nspi_ctx->pStat->TotalRecs = r.out.pStat->TotalRecs;
 
-	talloc_free(mem_ctx);
-
 	return MAPI_E_SUCCESS;
 
 }
@@ -292,6 +297,7 @@
    the table.
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param SortType the table sort order to use
    \param pTarget SPropValue struct holding the value being sought
    \param pPropTags pointer to an array of property tags of columns
@@ -316,6 +322,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_SeekEntries(struct nspi_context *nspi_ctx,
+					  TALLOC_CTX *mem_ctx,
 					  enum TableSortOrders SortType,
 					  struct SPropValue *pTarget,
 					  struct SPropTagArray *pPropTags,
@@ -329,6 +336,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pTarget, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pRows, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(((SortType != SortTypeDisplayName) 
@@ -363,10 +371,10 @@
 
 	r.out.pRows = pRows;
 
-	pStat = talloc(nspi_ctx->mem_ctx, struct STAT);
+	pStat = talloc(mem_ctx, struct STAT);
 	r.out.pStat = pStat;
 
-	status = dcerpc_NspiSeekEntries(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiSeekEntries(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, pStat);
 	OPENCHANGE_RETVAL_IF(retval, retval, pStat);
@@ -379,6 +387,7 @@
    \details Returns an explicit table.
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param pPropTags pointer to an array of property tags of columns
    \param Filter pointer to the Restriction to apply to the table
    \param ppRows pointer to pointer to a SRowSet structure holding the
@@ -389,12 +398,12 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetMatches(struct nspi_context *nspi_ctx, 
+					 TALLOC_CTX *mem_ctx,
 					 struct SPropTagArray *pPropTags,
 					 struct Restriction_r *Filter,
 					 struct SRowSet **ppRows,
 					 struct SPropTagArray **ppOutMIds)
 {
-	TALLOC_CTX			*mem_ctx;
 	struct NspiGetMatches		r;
 	NTSTATUS			status;
 	enum MAPISTATUS			retval;
@@ -402,11 +411,10 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppRows, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppOutMIds, MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "nspi_GetMatches");
-
 	r.in.handle = &nspi_ctx->handle;
 	r.in.Reserved = 0;
 	
@@ -429,13 +437,11 @@
 	r.out.ppOutMIds = ppOutMIds;
 	r.out.ppRows = ppRows;
 
-	status = dcerpc_NspiGetMatches(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetMatches(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
-	talloc_free(mem_ctx);
-
 	return MAPI_E_SUCCESS;
 }
 
@@ -445,6 +451,7 @@
    address book container
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param SortType the table sort order to use
    \param pInMIds pointer on a list of MIds that comprise a
    restricted addess book container
@@ -458,11 +465,11 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_ResortRestriction(struct nspi_context *nspi_ctx,
+						TALLOC_CTX *mem_ctx,
 						enum TableSortOrders SortType,
 						struct SPropTagArray *pInMIds,
 						struct SPropTagArray **ppMIds)
 {
-	TALLOC_CTX			*mem_ctx;
 	struct NspiResortRestriction	r;
 	enum MAPISTATUS			retval;
 	NTSTATUS			status;
@@ -471,6 +478,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pInMIds, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppMIds, MAPI_E_INVALID_PARAMETER, NULL);
 
@@ -478,8 +486,6 @@
 	OPENCHANGE_RETVAL_IF(((SortType != SortTypeDisplayName) && (SortType != SortTypePhoneticDisplayName)),
 		       MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "nspi_ResortRestriction");
-
 	r.in.handle = &nspi_ctx->handle;
 	r.in.Reserved = 0;
 	r.in.pStat = nspi_ctx->pStat;
@@ -491,13 +497,11 @@
 	r.out.pStat = pStat;
 	r.out.ppMIds = ppMIds;
 
-	status = dcerpc_NspiResortRestriction(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiResortRestriction(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
-	talloc_free(mem_ctx);
-
 	return MAPI_E_SUCCESS;
 }
 
@@ -506,6 +510,7 @@
    \details Maps a set of DN to a set of MId
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param pNames pointer to a StringsArray_r structure with the DN to
    map
    \param ppMIds pointer on pointer to the returned list of MIds
@@ -513,6 +518,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_DNToMId(struct nspi_context *nspi_ctx, 
+				      TALLOC_CTX *mem_ctx,
 				      struct StringsArray_r *pNames,
 				      struct SPropTagArray **ppMIds)
 {
@@ -522,6 +528,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pNames, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pNames->Count, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppMIds, MAPI_E_INVALID_PARAMETER, NULL);
@@ -532,7 +539,7 @@
 
 	r.out.ppMIds = ppMIds;
 
-	status = dcerpc_NspiDNToMId(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiDNToMId(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL)
@@ -546,6 +553,7 @@
    the specified object
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param WantObject boolean value defining whether we want the server
    to include properties with the type set to PT_OBJECT
    \param dwMId the MId of the specified object
@@ -555,6 +563,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetPropList(struct nspi_context *nspi_ctx,
+					  TALLOC_CTX *mem_ctx,
 					  bool WantObject,
 					  uint32_t dwMId,
 					  struct SPropTagArray **ppPropTags)
@@ -565,6 +574,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL);
 	
 	r.in.handle = &nspi_ctx->handle;
@@ -574,7 +584,7 @@
 	
 	r.out.ppPropTags = ppPropTags;
 
-	status = dcerpc_NspiGetPropList(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetPropList(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -589,6 +599,7 @@
    properties and values that exists on an object
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param pPropTags pointer to the list of property tags that the
    client wants to be returned
    \param MId pointer to the MId of the record
@@ -597,6 +608,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetProps(struct nspi_context *nspi_ctx, 
+				       TALLOC_CTX *mem_ctx,
 				       struct SPropTagArray *pPropTags, 
 				       struct SPropTagArray *MId,
 				       struct SRowSet **SRowSet)
@@ -609,6 +621,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!MId, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!MId->cValues, MAPI_E_INVALID_PARAMETER, NULL);
 
@@ -623,16 +636,16 @@
 
  	r.in.pPropTags = pPropTags;
 
-	ppRows = talloc(nspi_ctx->mem_ctx, struct SRow);
+	ppRows = talloc(mem_ctx, struct SRow);
 	r.out.ppRows = &ppRows;
 
-	status = dcerpc_NspiGetProps(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetProps(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL)
 
 	SRowSet[0]->cRows = 1;
-	SRowSet[0]->aRow = talloc(nspi_ctx->mem_ctx, struct SRow);
+	SRowSet[0]->aRow = talloc(mem_ctx, struct SRow);
 	SRowSet[0]->aRow->ulAdrEntryPad = ppRows->ulAdrEntryPad;
 	SRowSet[0]->aRow->cValues = ppRows->cValues;
 	SRowSet[0]->aRow->lpProps = ppRows->lpProps;
@@ -646,6 +659,7 @@
    objects identified by MId and returns the value of the comparison
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param MId1 the first MId to compare
    \param MId2 the second MId to compare
    \param plResult pointer to the value of the comparison
@@ -653,6 +667,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_CompareMIds(struct nspi_context *nspi_ctx,
+					  TALLOC_CTX *mem_ctx,
 					  uint32_t MId1, uint32_t MId2,
 					  uint32_t *plResult)
 {
@@ -662,6 +677,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!plResult, MAPI_E_INVALID_PARAMETER, NULL);
 
 	r.in.handle = &nspi_ctx->handle;
@@ -672,7 +688,7 @@
 
 	r.out.plResult = plResult;
 
-	status = dcerpc_NspiCompareMIds(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiCompareMIds(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -685,6 +701,7 @@
    \details Modify the properties of an object in the address book
    
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param MId the MId of the address book object
    \param pPropTags pointer to the list of properties to be modified
    on the object
@@ -693,6 +710,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_ModProps(struct nspi_context *nspi_ctx,
+				       TALLOC_CTX *mem_ctx,
 				       uint32_t MId,
 				       struct SPropTagArray *pPropTags,
 				       struct SRow *pRow)
@@ -703,6 +721,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pPropTags, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pRow, MAPI_E_INVALID_PARAMETER, NULL);
 
@@ -717,7 +736,7 @@
 	r.in.pPropTags = pPropTags;
 	r.in.pRow = pRow;
 
-	status = dcerpc_NspiModProps(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiModProps(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -732,6 +751,7 @@
    special table can be a Hierarchy Table or an Address Creation Table
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param Type bitmap of flags defining the type of the special table
    \param ppRows pointer on pointer to the rows returned by the server
 
@@ -748,6 +768,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetSpecialTable(struct nspi_context *nspi_ctx, 
+					      TALLOC_CTX *mem_ctx,
 					      uint32_t Type,
 					      struct SRowSet **ppRows)
 {
@@ -757,6 +778,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(((Type != 0x0) && (Type != 0x2) && (Type != 0x4)),
 		       MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppRows, MAPI_E_INVALID_PARAMETER, NULL);
@@ -770,7 +792,7 @@
 	r.out.lpVersion = &nspi_ctx->version;
 	r.out.ppRows = ppRows;
 
-	status = dcerpc_NspiGetSpecialTable(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetSpecialTable(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -784,6 +806,7 @@
    book.
 
    \param nspi_ctx pointer to the NSPI memory context
+   \param mem_ctx pointer to the memory context
    \param dwFlags set of bit flags
    \param ulType specifies the display type of the template
    \param pDN the DN of the template requested
@@ -800,6 +823,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo(struct nspi_context *nspi_ctx,
+					      TALLOC_CTX *mem_ctx,
 					      uint32_t dwFlags,
 					      uint32_t ulType,
 					      char *pDN,
@@ -811,6 +835,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppData, MAPI_E_INVALID_PARAMETER, NULL);
 
 	r.in.handle = &nspi_ctx->handle;
@@ -822,7 +847,7 @@
 	
 	r.out.ppData = ppData;
 
-	status = dcerpc_NspiGetTemplateInfo(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetTemplateInfo(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -886,12 +911,14 @@
    aware off.
 
    \param nspi_ctx pointer to the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param WantUnicode whether we want UNICODE properties or not
    \param ppColumns pointer on pointer to a property tag array
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
  */
 _PUBLIC_ enum MAPISTATUS nspi_QueryColumns(struct nspi_context *nspi_ctx,
+					   TALLOC_CTX *mem_ctx,
 					   bool WantUnicode,
 					   struct SPropTagArray **ppColumns)
 {
@@ -901,6 +928,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppColumns, MAPI_E_INVALID_PARAMETER, NULL);
 
 	r.in.handle = &nspi_ctx->handle;
@@ -909,7 +937,7 @@
 	
 	r.out.ppColumns = ppColumns;
 
-	status = dcerpc_NspiQueryColumns(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiQueryColumns(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -922,6 +950,7 @@
    \details Returns a list of property names for a set of proptags
 
    \param nspi_ctx pointer on the NSPI connection text
+   \param mem_ctx pointer to the memory context
    \param lpGuid the property set about which the client is requesting
    information
    \param pPropTags pointer to the proptags list
@@ -933,6 +962,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetNamesFromIDs(struct nspi_context *nspi_ctx,
+					      TALLOC_CTX *mem_ctx,
 					      struct FlatUID_r *lpGuid,
 					      struct SPropTagArray *pPropTags,
 					      struct SPropTagArray **ppReturnedPropTags,
@@ -944,6 +974,7 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppReturnedPropTags, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppNames, MAPI_E_INVALID_PARAMETER, NULL);
 
@@ -955,7 +986,7 @@
 	r.out.ppReturnedPropTags = ppReturnedPropTags;
 	r.out.ppNames = ppNames;
 
-	status = dcerpc_NspiGetNamesFromIDs(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetNamesFromIDs(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
 	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
 	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
@@ -969,6 +1000,7 @@
    from the NSPI server.
 
    \param nspi_ctx pointer on the NSPI connection context
+   \param mem_ctx pointer to the memoty context
    \param VerifyNames boolean value defining whether the NSPI server
    must verify that all client specified names are recognized by the
    server
@@ -981,12 +1013,12 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_GetIDsFromNames(struct nspi_context *nspi_ctx,
+					      TALLOC_CTX *mem_ctx,
 					      bool VerifyNames,
 					      uint32_t cNames,
 					      struct PropertyName_r *ppNames,
 					      struct SPropTagArray **ppPropTags)
 {
-	TALLOC_CTX			*mem_ctx;
 	struct NspiGetIDsFromNames	r;
 	NTSTATUS			status;
 	enum MAPISTATUS			retval;
@@ -994,11 +1026,10 @@
 
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppNames, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "nspi_GetIDsFromNames");
-
 	r.in.handle = &nspi_ctx->handle;
 	r.in.Reserved = 0;
 	r.in.dwFlags = (VerifyNames == true) ? 0x2 : 0x0;
@@ -1011,13 +1042,11 @@
 
 	r.out.ppPropTags = ppPropTags;
 	
-	status = dcerpc_NspiGetIDsFromNames(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiGetIDsFromNames(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
-	talloc_free(mem_ctx);
-
 	errno = retval;
 	return MAPI_E_SUCCESS;
 }
@@ -1028,6 +1057,7 @@
    performs ANR on those strings
 
    \param nspi_ctx pointer on the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param usernames pointer on pointer to the list of values we want
    to perform ANR on
    \param pPropTags pointer on the property tags list we want for each
@@ -1040,12 +1070,12 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_ResolveNames(struct nspi_context *nspi_ctx, 
+					   TALLOC_CTX *mem_ctx,
 					   const char **usernames, 
 					   struct SPropTagArray *pPropTags, 
 					   struct SRowSet ***pppRows,
 					   struct SPropTagArray ***pppMIds)
 {
-	TALLOC_CTX		*mem_ctx;
 	struct NspiResolveNames r;
 	struct StringsArray_r	*paStr;
 	NTSTATUS		status;
@@ -1054,6 +1084,7 @@
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!usernames, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pppRows, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pppMIds, MAPI_E_INVALID_PARAMETER, NULL);
@@ -1061,8 +1092,6 @@
 	for (count = 0; usernames[count]; count++);
 	OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "nspi_ResolveNames");
-
 	r.in.handle = &nspi_ctx->handle;
 
 	r.in.pStat = nspi_ctx->pStat;
@@ -1077,13 +1106,11 @@
 	r.out.ppMIds = *pppMIds;
 	r.out.ppRows = *pppRows;
 
-	status = dcerpc_NspiResolveNames(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiResolveNames(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
-	talloc_free(mem_ctx);
-
 	return MAPI_E_SUCCESS;
 }
 
@@ -1093,6 +1120,7 @@
    and performs ANR on those strings
 
    \param nspi_ctx pointer on the NSPI connection context
+   \param mem_ctx pointer to the memory context
    \param usernames pointer on pointer to the list of values we want
    to perform ANR on
    \param pPropTags pointer on the property tags list we want for each
@@ -1105,12 +1133,12 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS nspi_ResolveNamesW(struct nspi_context *nspi_ctx, 
+					    TALLOC_CTX *mem_ctx,
 					    const char **usernames, 
 					    struct SPropTagArray *pPropTags, 
 					    struct SRowSet ***pppRows,
 					    struct SPropTagArray ***pppMIds)
 {
-	TALLOC_CTX			*mem_ctx;
 	struct NspiResolveNamesW	r;
 	struct WStringsArray_r		*paWStr;
 	NTSTATUS			status;
@@ -1118,6 +1146,7 @@
 	uint32_t			count;
 
 	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!usernames, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pppRows, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!pppMIds, MAPI_E_INVALID_PARAMETER, NULL);
@@ -1125,8 +1154,6 @@
 	for (count = 0; usernames[count]; count++);
 	OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL);
 
-	mem_ctx = talloc_named(NULL, 0, "mapi_ResolveNamesW");
-
 	r.in.handle = &nspi_ctx->handle;
 
 	r.in.pStat = nspi_ctx->pStat;
@@ -1141,12 +1168,10 @@
 	r.out.ppMIds = *pppMIds;
 	r.out.ppRows = *pppRows;
 
-	status = dcerpc_NspiResolveNamesW(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	status = dcerpc_NspiResolveNamesW(nspi_ctx->rpc_connection, mem_ctx, &r);
 	retval = r.out.result;
-	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, mem_ctx);
-	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 
-	talloc_free(mem_ctx);
-
 	return MAPI_E_SUCCESS;
 }

Modified: trunk/openchange/libmapi/property.c
===================================================================
--- trunk/openchange/libmapi/property.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/property.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -29,6 +29,20 @@
    \brief Functions for manipulating MAPI properties
  */
 
+/**
+  \details Create a property tag array
+  
+  \param mem_ctx talloc memory context to use for allocation
+  \param PropCount the number of properties in the array
+  
+  The varargs (the third and subsequent arguments) are the property
+  tags to make up the array. So the normal way to use this to create
+  an array of two tags is like:
+  \code
+  struct SPropTagArray *array
+  array = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
+  \endcode
+*/
 _PUBLIC_ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *mem_ctx, 
 						 uint32_t PropCount, ...)
 {
@@ -46,7 +60,7 @@
 	va_end(ap);
 
 	SPropTagArray = talloc(mem_ctx, struct SPropTagArray);
-	SPropTagArray->aulPropTag = aulPropTag;
+	SPropTagArray->aulPropTag = (enum MAPITAGS *) aulPropTag;
 	SPropTagArray->cValues = PropCount;
 	return SPropTagArray;
 }
@@ -74,8 +88,8 @@
 	OPENCHANGE_RETVAL_IF(!SPropTagArray->cValues, MAPI_E_INVALID_PARAMETER, NULL);
 
 	SPropTagArray->cValues += 1;
-	SPropTagArray->aulPropTag = talloc_realloc(mem_ctx, SPropTagArray->aulPropTag,
-						   uint32_t, SPropTagArray->cValues + 1);
+	SPropTagArray->aulPropTag = (enum MAPITAGS *) talloc_realloc(mem_ctx, SPropTagArray->aulPropTag,
+								     uint32_t, SPropTagArray->cValues + 1);
 	SPropTagArray->aulPropTag[SPropTagArray->cValues - 1] = aulPropTag;
 	SPropTagArray->aulPropTag[SPropTagArray->cValues] = 0;
 
@@ -469,7 +483,7 @@
 	case PT_UNICODE:
 		mapi_sprop->value.lpszW = sprop->value.lpszW;
 		if (!mapi_sprop->value.lpszW) return 0;
-		return (strlen(sprop->value.lpszW) * 2 + 2);
+		return get_utf8_utf16_conv_length(mapi_sprop->value.lpszW);
 	case PT_SYSTIME:
 		mapi_sprop->value.ft.dwLowDateTime = sprop->value.ft.dwLowDateTime;
 		mapi_sprop->value.ft.dwHighDateTime = sprop->value.ft.dwHighDateTime;
@@ -610,12 +624,11 @@
  */
 _PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue SPropValue)
 {
-	uint32_t	rows;
-	uint32_t	cValues;
-	struct SPropValue lpProp;
+	uint32_t		rows;
+	uint32_t		cValues;
+	struct SPropValue	lpProp;
 
 	/* Sanity checks */
-
 	if (!SRowSet) return 1;
 
 	for (rows = 0; rows < SRowSet->cRows; rows++) {
@@ -766,11 +779,71 @@
                 talloc_free(RecurrencePattern);
                 return NULL;
         }
+	
+	/*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/ 
+	RecurrencePattern->DeletedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->DeletedInstanceDates, 
+							      sizeof(uint32_t) * RecurrencePattern->DeletedInstanceCount);
+							      
+	RecurrencePattern->ModifiedInstanceDates=talloc_memdup(mem_ctx, RecurrencePattern->ModifiedInstanceDates, 
+							      sizeof(uint32_t) * RecurrencePattern->ModifiedInstanceCount);
+	
+	/*Set reference to parent so arrays get free with RecurrencePattern struct*/
+	RecurrencePattern->DeletedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->DeletedInstanceDates);
+	RecurrencePattern->ModifiedInstanceDates=talloc_reference(RecurrencePattern, RecurrencePattern->ModifiedInstanceDates);
 
         return RecurrencePattern;
 }
+_PUBLIC_ struct AppointmentRecurrencePattern *get_AppointmentRecurrencePattern(TALLOC_CTX *mem_ctx, 
+							 struct Binary_r *bin)
+{
+        struct AppointmentRecurrencePattern		*arp = NULL;
+        struct ndr_pull					*ndr;
+        enum ndr_err_code				ndr_err_code;
 
+        /* Sanity checks */
+        if (!bin) return NULL;
+        if (!bin->cb) return NULL;
+        if (!bin->lpb) return NULL;
 
+        ndr = talloc_zero(mem_ctx, struct ndr_pull);
+        ndr->offset = 0;
+        ndr->data = bin->lpb;
+        ndr->data_size = bin->cb;
+
+        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+        ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
+        arp = talloc_zero(mem_ctx, struct AppointmentRecurrencePattern);
+        ndr_err_code = ndr_pull_AppointmentRecurrencePattern(ndr, NDR_SCALARS, arp);
+
+        talloc_free(ndr);
+
+        if (ndr_err_code != NDR_ERR_SUCCESS) {
+                talloc_free(arp);
+                return NULL;
+        }
+
+	/*Copy ExceptionInfo array into memory*/ 
+	arp->ExceptionInfo=talloc_memdup(mem_ctx,arp->ExceptionInfo, sizeof(struct ExceptionInfo) * arp->ExceptionCount);
+	
+	/*Copy DeletedInstanceDates and ModifiedInstanceDates into memory*/ 
+	arp->RecurrencePattern.DeletedInstanceDates=talloc_memdup(mem_ctx, arp->RecurrencePattern.DeletedInstanceDates, 
+							      sizeof(uint32_t) * arp->RecurrencePattern.DeletedInstanceCount);
+							      
+	arp->RecurrencePattern.ModifiedInstanceDates=talloc_memdup(mem_ctx, arp->RecurrencePattern.ModifiedInstanceDates, 
+							      sizeof(uint32_t) * arp->RecurrencePattern.ModifiedInstanceCount);
+	
+	/*Set reference to parent so arrays get free with rest*/
+	arp->ExceptionInfo = talloc_reference(arp, arp->ExceptionInfo);
+	arp->RecurrencePattern.DeletedInstanceDates = talloc_reference(arp,arp->RecurrencePattern.DeletedInstanceDates);
+	arp->RecurrencePattern.ModifiedInstanceDates = talloc_reference(arp, arp->RecurrencePattern.ModifiedInstanceDates);
+	
+
+	
+
+        return arp;
+}
+
+
 /**
    \details Retrieve a TimeZoneStruct structure from a binary blob
 
@@ -861,3 +934,131 @@
 
 	return GlobalObjectId;
 }
+
+/**
+   \details Return the effective value used in a TypedString
+   structure.
+
+   \param tstring pointer to TypedString structure
+
+   \return pointer to a valid string on success, otherwise NULL
+ */
+_PUBLIC_ const char *get_TypedString(struct TypedString *tstring)
+{
+	if (!tstring) return NULL;
+
+	switch (tstring->StringType) {
+	case StringType_STRING8:
+		return tstring->String.lpszA;
+	case StringType_UNICODE_REDUCED:
+		return tstring->String.lpszW_reduced;
+	case StringType_UNICODE:
+		return tstring->String.lpszW;
+	case StringType_NONE:
+	case StringType_EMPTY:
+	default:
+		return NULL;
+	}
+
+	return NULL;
+}
+
+/**
+   \details Return the expected size of the utf8 string after
+   conversion to utf16 by iconv() function.
+
+   \param inbuf pointer to the input string
+
+   \return expected length of the converted string
+
+   \note This routine is based upon utf8_pull() function from
+   samba4/lib/util/charset/iconv.c
+ */
+size_t get_utf8_utf16_conv_length(const char *inbuf)
+{
+	size_t		in_left;
+	size_t		out_left;
+	size_t		max_out;
+	const uint8_t	*c = (const uint8_t *) inbuf;
+
+	/* Sanity checks */
+	if (!inbuf) return 0;
+
+	in_left = strlen(inbuf);
+	out_left = in_left;
+	out_left = ( out_left * 3);
+	/* includes null-termination bytes */
+	max_out = out_left + 2;
+
+	while (in_left >= 1 && out_left >= 2) {
+		if ((c[0] & 0x80) == 0) {
+			c += 1;
+			in_left -= 1;
+			out_left -= 2;
+			continue;
+		}
+
+		if ((c[0] & 0xe0) == 0xc0) {
+			if (in_left < 2 || (c[1] & 0xc0) != 0x80) {
+				return -1;
+			}
+			c += 2;
+			in_left -= 2;
+			out_left -= 2;
+			continue;
+		}
+
+		if ((c[0] & 0xf0) == 0xe0) {
+			if (in_left < 3 ||
+			    (c[1] & 0xc0) != 0x80 ||
+			    (c[2] & 0xc0) != 0x80) {
+				return -1;
+			}
+			c += 3;
+			in_left -= 3;
+			out_left -= 2;
+			continue;
+		}
+
+		if ((c[0] & 0xf8) == 0xf0) {
+			unsigned int codepoint;
+			if (in_left < 4 ||
+			    (c[1] & 0xc0) != 0x80 ||
+			    (c[2] & 0xc0) != 0x80 ||
+			    (c[3] & 0xc0) != 0x80) {
+				return -1;
+			}
+			codepoint = 
+				(c[3]&0x3f) | 
+				((c[2]&0x3f)<<6) | 
+				((c[1]&0x3f)<<12) |
+				((c[0]&0x7)<<18);
+			if (codepoint < 0x10000) {
+				c += 4;
+				in_left -= 4;
+				out_left -= 2;
+				continue;
+			}
+
+			codepoint -= 0x10000;
+
+			if (out_left < 4) {
+				return -1;
+			}
+
+			c += 4;
+			in_left -= 4;
+			out_left -= 4;
+			continue;
+		}
+		
+		/* we don't handle 5 byte sequences */
+		return -1;
+	}
+
+	if (in_left > 0) {
+		return -1;
+	}
+
+	return (max_out - out_left);
+}

Modified: trunk/openchange/libmapi/simple_mapi.c
===================================================================
--- trunk/openchange/libmapi/simple_mapi.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/simple_mapi.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -184,9 +184,9 @@
 	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
 	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_drafts);
 	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	store->store_type = PrivateFolderWithCachedFids;
 	
-	store->cached_mailbox_fid = true;
-	
 	mapi_object_release(&obj_inbox);
 	talloc_free(mem_ctx);
 
@@ -249,7 +249,7 @@
 	store = (mapi_object_store_t *)obj_store->private_data;
 	OPENCHANGE_RETVAL_IF(!store, MAPI_E_NOT_INITIALIZED, NULL);
 
-	if ((id > 6) && (store->cached_mailbox_fid == false)) {
+	if ((id > 6) && (store->store_type == PrivateFolderWithoutCachedFids)) {
 		retval = CacheDefaultFolders(obj_store);
 		OPENCHANGE_RETVAL_IF(retval, retval, NULL);
 	} 
@@ -317,16 +317,26 @@
 {
 	enum MAPISTATUS		retval;
 	mapi_object_store_t	*store;
-	uint32_t		olFolderNum;
+	uint32_t		olFolderNum = 0;
 	bool			ret = true;
 
-	if (!obj_store) return false;
+	if (!obj_store) {
+		return false;
+	}
 	store = (mapi_object_store_t *) obj_store->private_data;
-	if (!store) return false;
+	if (!store) {
+		return false;
+	}
 
-	if (store->cached_mailbox_fid == false) {
+	if (fid == 0x0) {
+		return false;
+	}
+
+	if (store->store_type == PrivateFolderWithoutCachedFids) {
 		retval = CacheDefaultFolders(obj_store);
-		if (retval) return false;
+		if (retval) {
+			return false;
+		}
 	}
 
 	if(fid == store->fid_top_information_store) {
@@ -355,8 +365,28 @@
 		olFolderNum = olFolderDrafts;
 	} else if (fid == store->fid_search) {
 		olFolderNum = olFolderFinder;
+	} else if (fid == store->fid_pf_OfflineAB) {
+		olFolderNum = olFolderPublicOfflineAB;
+	} else if (fid == store->fid_pf_FreeBusyRoot) {
+		olFolderNum = olFolderPublicFreeBusyRoot;
+	} else if (fid == store->fid_pf_EFormsRegistryRoot) {
+		olFolderNum = olFolderPublicEFormsRoot;
+	} else if (fid == store->fid_pf_EFormsRegistry) {
+		olFolderNum = olFolderPublicEFormsRegistry;
+	} else if (fid == store->fid_pf_public_root) {
+		olFolderNum = olFolderPublicRoot;
+	} else if (fid == store->fid_pf_ipm_subtree) {
+		olFolderNum = olFolderPublicIPMSubtree;
+	} else if (fid == store->fid_pf_non_ipm_subtree) {
+		olFolderNum = olFolderPublicNonIPMSubtree;
+	} else if (fid == store->fid_pf_LocalSiteFreeBusy) {
+		olFolderNum = olFolderPublicLocalFreeBusy;
+	} else if (fid == store->fid_pf_LocalSiteOfflineAB) {
+		olFolderNum = olFolderPublicLocalOfflineAB;
+	} else if (fid == store->fid_pf_NNTPArticle) {
+		olFolderNum = olFolderPublicNNTPArticle;
 	} else {
-		olFolderNum = -1;
+		olFolderNum = 0xFFFFFFFF;
 		ret = false;
 	}
 

Modified: trunk/openchange/libmapi/socket/netif.c
===================================================================
--- trunk/openchange/libmapi/socket/netif.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/socket/netif.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -29,6 +29,12 @@
 
 */
 
+#include "config.h"
+
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
 #include <libmapi/libmapi.h>
 
 #ifdef __COMPAR_FN_T

Deleted: trunk/openchange/libmapi/utf8_convert.l
===================================================================
--- trunk/openchange/libmapi/utf8_convert.l	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/utf8_convert.l	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,379 +0,0 @@
-/*
-   OpenChange MAPI implementation.
-
-   Copyright (C) Julien Kerihuel 2007.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-%option nounput
-%option noinput
-
-%{
-#include <stdlib.h>
-#include <string.h>
-
-int yylex(void);
-
-/*
- * Prototypes
- */
-
-int	yyget_lineno(void);
-FILE	*yyget_in(void);
-FILE	*yyget_out(void);
-int	yyget_leng(void);
-char	*yyget_text(void);
-void	yyset_lineno(int);
-void	yyset_in (FILE *);
-void	yyset_out (FILE *);
-int	yyget_debug(void);
-void	yyset_debug(int);
-int	yylex_destroy(void);
-
-int	yyreplace_utf8(char *);
-int	yyparse_utf8(char *, char *);
-
-char *newbuf;
-int  newbuf_idx;
-
-#define	U00A1	"\xc2\xa1"	/* ¡ */
-#define	U00A2	"\xc2\xa2"	/* ¢ */
-#define	U00A3	"\xc2\xa3"	/* £ */
-#define	U00A4	"\xc2\xa4"	/* ¤ */
-#define	U00A5	"\xc2\xa5"	/* ¥ */
-#define	U00A6	"\xc2\xa6"	/* ¦ */
-#define	U00A7	"\xc2\xa7"	/* § */
-#define	U00A8	"\xc2\xa8"	/* ¨ */
-#define	U00A9	"\xc2\xa9"	/* © */
-#define	U00AA	"\xc2\xaa"	/* ª */
-#define	U00AB	"\xc2\xab"	/* « */
-#define	U00AC	"\xc2\xac"	/* ¬ */
-#define U00AD	"\xc2\xad"	/* ­ */
-#define U00AE	"\xc2\xae"	/* ® */
-#define U00AF	"\xc2\xaf"	/* ¯ */
-#define U00B0	"\xc2\xb0"	/* ° */
-#define U00B1	"\xc2\xb1"	/* ± */
-#define U00B2	"\xc2\xb2"	/* ² */
-#define U00B3	"\xc2\xb3"	/* ³ */
-#define U00B4	"\xc2\xb4"	/* ´ */
-#define U00B5	"\xc2\xb5"	/* µ */
-#define U00B6	"\xc2\xb6"	/* ¶ */
-#define U00B7	"\xc2\xb7"	/* · */
-#define U00B8	"\xc2\xb8"	/* ¸ */
-#define U00B9	"\xc2\xb9"	/* ¹ */
-#define U00BA	"\xc2\xba"	/* º */
-#define U00BB	"\xc2\xbb"	/* » */
-#define U00BC	"\xc2\xbc"	/* ¼ */
-#define U00BD	"\xc2\xbd"	/* ½ */
-#define U00BE	"\xc2\xbe"	/* ¾ */
-#define U00BF	"\xc2\xbf"	/* ¿ */
-#define U00C0	"\xc3\x80"	/* À */
-#define U00C1	"\xc3\x81"	/* Á */
-#define U00C2	"\xc3\x82"	/* Â */
-#define U00C3	"\xc3\x83"	/* Ã */
-#define U00C4	"\xc3\x84"	/* Ä */
-#define U00C5	"\xc3\x85"	/* Å */
-#define U00C6	"\xc3\x86"	/* Æ */
-#define U00C7	"\xc3\x87"	/* Ç */
-#define U00C8	"\xc3\x88"	/* È */
-#define	U00C9	"\xc3\x89"	/* É */
-#define	U00CA	"\xc3\x8a"	/* Ê */
-#define	U00CB	"\xc3\x8b"	/* Ë */
-#define	U00CC	"\xc3\x8c"	/* Ì */
-#define	U00CD	"\xc3\x8d"	/* Í */
-#define	U00CE	"\xc3\x8e"	/* Î */
-#define	U00CF	"\xc3\x8f"	/* Ï */
-#define	U00D0	"\xc3\x90"	/* Ð */
-#define	U00D1	"\xc3\x91"	/* Ñ */
-#define	U00D2	"\xc3\x92"	/* Ò */
-#define	U00D3	"\xc3\x93"	/* Ó */
-#define	U00D4	"\xc3\x94"	/* Ô */
-#define	U00D5	"\xc3\x95"	/* Õ */
-#define	U00D6	"\xc3\x96"	/* Ö */
-#define	U00D7	"\xc3\x97"	/* × */
-#define	U00D8	"\xc3\x98"	/* Ø */
-#define	U00D9	"\xc3\x99"	/* Ù */
-#define	U00DA	"\xc3\x9a"	/* Ú */
-#define	U00DB	"\xc3\x9b"	/* Û */
-#define	U00DC	"\xc3\x9c"	/* Ü */
-#define	U00DD	"\xc3\x9d"	/* Ý */
-#define	U00DE	"\xc3\x9e"	/* Þ */
-#define	U00DF	"\xc3\x9f"	/* ß */
-#define	U00E0	"\xc3\xa0"	/* à */
-#define	U00E1	"\xc3\xa1"	/* á */
-#define	U00E2	"\xc3\xa2"	/* â */
-#define	U00E3	"\xc3\xa3"	/* ã */
-#define	U00E4	"\xc3\xa4"	/* ä */
-#define	U00E5	"\xc3\xa5"	/* å */
-#define	U00E6	"\xc3\xa6"	/* æ */
-#define	U00E7	"\xc3\xa7"	/* ç */
-#define	U00E8	"\xc3\xa8"	/* è */
-#define	U00E9	"\xc3\xa9"	/* é */
-#define	U00EA	"\xc3\xaa"	/* ê */
-#define	U00EB	"\xc3\xab"	/* ë */
-#define	U00EC	"\xc3\xac"	/* ì */
-#define	U00ED	"\xc3\xad"	/* í */
-#define	U00EE	"\xc3\xae"	/* î */
-#define	U00EF	"\xc3\xaf"	/* ï */
-#define	U00F0	"\xc3\xb0"	/* ð */
-#define	U00F1	"\xc3\xb1"	/* ñ */
-#define	U00F2	"\xc3\xb2"	/* ò */
-#define	U00F3	"\xc3\xb3"	/* ó */
-#define	U00F4	"\xc3\xb4"	/* ô */
-#define	U00F5	"\xc3\xb5"	/* õ */
-#define	U00F6	"\xc3\xb6"	/* ö */
-#define	U00F7	"\xc3\xb7"	/* ÷ */
-#define	U00F8	"\xc3\xb8"	/* ø */
-#define	U00F9	"\xc3\xb9"	/* ù */
-#define	U00FA	"\xc3\xba"	/* ú */
-#define	U00FB	"\xc3\xbb"	/* û */
-#define	U00FC	"\xc3\xbc"	/* ü */
-#define	U00FD	"\xc3\xbd"	/* ý */
-#define	U00FE	"\xc3\xbe"	/* þ */
-#define	U00FF	"\xc3\xbf"	/* ÿ */
-
-%}
-
-chars [0-9A-za-z\_\'\.\"/\+\-=\{\}:]
-numbers ([0-9])+
-delim [" "\n\t\s]
-whitespace {delim}+
-words {chars}+
-
-WIN_U00A1	"\xc3\xad"
-WIN_U00A2	"\xc3\xb3"
-WIN_U00A3	"\xc3\xba"
-WIN_U00A4	"\xc3\xb1"
-WIN_U00A5	"\xc3\x91"
-WIN_U00A6	"\xc2\xaa"
-WIN_U00A7	"\xc2\xba"
-WIN_U00A8	"\xc2\xbf"
-WIN_U00A9	"\xc2\xae"
-WIN_U00AA	"\xc2\xac"
-WIN_U00AB	"\xc2\xbd"
-WIN_U00AC	"\xc2\xbc"
-WIN_U00AD	"\xc2\xa1"
-WIN_U00AE	"\xc2\xab"
-WIN_U00AF	"\xc2\xbb"
-WIN_U00B0	"\xe2\x96\x91"
-WIN_U00B1	"\xe2\x96\x92"
-WIN_U00B2	"\xe2\x96\x93"
-WIN_U00B3	"\xe2\x94\x82"
-WIN_U00B4	"\xe2\x94\xa4"
-WIN_U00B5	"\xc3\x81"
-WIN_U00B6	"\xc3\x82"
-WIN_U00B7	"\xc3\x80"
-WIN_U00B8	"\xc2\xa9"
-WIN_U00B9	"\xe2\x95\xa3"
-WIN_U00BA	"\xe2\x95\x91"
-WIN_U00BB	"\xe2\x95\x97"
-WIN_U00BC	"\xe2\x95\x9d"
-WIN_U00BD	"\xc2\xa2"
-WIN_U00BE	"\xc2\xa5"
-WIN_U00BF	"\xe2\x94\x90"
-WIN_U00C0	"\xe2\x94\x94"
-WIN_U00C1	"\xe2\x94\xb4"
-WIN_U00C2	"\xe2\x94\xac"
-WIN_U00C3	"\xe2\x94\x9c"
-WIN_U00C4	"\xe2\x94\x80"
-WIN_U00C5	"\xe2\x94\xbc"
-WIN_U00C6	"\xc3\xa3"
-WIN_U00C7	"\xc3\x83"
-WIN_U00C8	"\xe2\x95\x9a"
-WIN_U00C9	"\xe2\x95\x94"
-WIN_U00CA	"\xe2\x95\xa9"
-WIN_U00CB	"\xe2\x95\xa6"
-WIN_U00CC	"\xe2\x95\xa0"
-WIN_U00CD	"\xe2\x95\x90"
-WIN_U00CE	"\xe2\x95\xac"
-WIN_U00CF	"\xc2\xa4"
-WIN_U00D0	"\xc3\xb0"
-WIN_U00D1	"\xc3\x90"
-WIN_U00D2	"\xc3\x8a"
-WIN_U00D3	"\xc3\x8b"
-WIN_U00D4	"\xc3\x88"
-WIN_U00D5	"\xc4\xb1"
-WIN_U00D6	"\xc3\x8d"
-WIN_U00D7	"\xc3\x8e"
-WIN_U00D8	"\xc3\x8f"
-WIN_U00D9	"\xe2\x94\x98"
-WIN_U00DA	"\xe2\x94\x8c"
-WIN_U00DB	"\xe2\x96\x88"
-WIN_U00DC	"\xe2\x96\x84"
-WIN_U00DD	"\xc2\xa6"
-WIN_U00DE	"\xc3\x8c"
-WIN_U00DF	"\xe2\x96\x80"
-WIN_U00E0	"\xc3\x93"
-WIN_U00E1	"\xc3\x9f"
-WIN_U00E2	"\xc3\x94"
-WIN_U00E3	"\xc3\x92"
-WIN_U00E4	"\xc3\xb5"
-WIN_U00E5	"\xc3\x95"
-WIN_U00E6	"\xc2\xb5"
-WIN_U00E7	"\xc3\xbe"
-WIN_U00E8	"\xc3\x9e"
-WIN_U00E9	"\xc3\x9a"
-WIN_U00EA	"\xc3\x9b"
-WIN_U00EB	"\xc3\x99"
-WIN_U00EC	"\xc3\xbd"
-WIN_U00ED	"\xc3\x9d"
-WIN_U00EE	"\xc2\xaf"
-WIN_U00EF	"\xc2\xb4"
-WIN_U00F0	"\xc2\xad"
-WIN_U00F1	"\xc2\xb1"
-WIN_U00F2	"\xe2\x80\x97"
-WIN_U00F3	"\xc2\xbe"
-WIN_U00F4	"\xc2\xb6"
-WIN_U00F5	"\xc2\xa7"
-WIN_U00F6	"\xc3\xb7"
-WIN_U00F7	"\xc2\xb8"
-WIN_U00F8	"\xc2\xb0"
-WIN_U00F9	"\xc2\xa8"
-WIN_U00FA	"\xc2\xb7"
-WIN_U00FB	"\xc2\xb9"
-WIN_U00FC	"\xc2\xb3"
-WIN_U00FD	"\xc2\xb2"
-WIN_U00FE	"\xe2\x96\xa0"
-WIN_U00FF	"\xc2\xa0"
-
-
-%%
-{words} { yyreplace_utf8(yytext); }
-{delim} { yyreplace_utf8(yytext); }
-{whitespace} { yyreplace_utf8(yytext); }
-{WIN_U00A1} { yyreplace_utf8(U00A1);}
-{WIN_U00A2} { yyreplace_utf8(U00A2);}
-{WIN_U00A3} { yyreplace_utf8(U00A3);}
-{WIN_U00A4} { yyreplace_utf8(U00A4);}
-{WIN_U00A5} { yyreplace_utf8(U00A5);}
-{WIN_U00A6} { yyreplace_utf8(U00A6);}
-{WIN_U00A7} { yyreplace_utf8(U00A7);}
-{WIN_U00A8} { yyreplace_utf8(U00A8);}
-{WIN_U00A9} { yyreplace_utf8(U00A9);}
-{WIN_U00AA} { yyreplace_utf8(U00AA);}
-{WIN_U00AB} { yyreplace_utf8(U00AB);}
-{WIN_U00AC} { yyreplace_utf8(U00AC);}
-{WIN_U00AD} { yyreplace_utf8(U00AD);}
-{WIN_U00AE} { yyreplace_utf8(U00AE);}
-{WIN_U00AF} { yyreplace_utf8(U00AF);}
-{WIN_U00B0} { yyreplace_utf8(U00B0);}
-{WIN_U00B1} { yyreplace_utf8(U00B1);}
-{WIN_U00B2} { yyreplace_utf8(U00B2);}
-{WIN_U00B3} { yyreplace_utf8(U00B3);}
-{WIN_U00B4} { yyreplace_utf8(U00B4);}
-{WIN_U00B5} { yyreplace_utf8(U00B5);}
-{WIN_U00B6} { yyreplace_utf8(U00B6);}
-{WIN_U00B7} { yyreplace_utf8(U00B7);}
-{WIN_U00B8} { yyreplace_utf8(U00B8);}
-{WIN_U00B9} { yyreplace_utf8(U00B9);}
-{WIN_U00BA} { yyreplace_utf8(U00BA);}
-{WIN_U00BB} { yyreplace_utf8(U00BB);}
-{WIN_U00BC} { yyreplace_utf8(U00BC);}
-{WIN_U00BD} { yyreplace_utf8(U00BD);}
-{WIN_U00BE} { yyreplace_utf8(U00BE);}
-{WIN_U00BF} { yyreplace_utf8(U00BF);}
-{WIN_U00C0} { yyreplace_utf8(U00C0);}
-{WIN_U00C1} { yyreplace_utf8(U00C1);}
-{WIN_U00C2} { yyreplace_utf8(U00C2);}
-{WIN_U00C3} { yyreplace_utf8(U00C3);}
-{WIN_U00C4} { yyreplace_utf8(U00C4);}
-{WIN_U00C5} { yyreplace_utf8(U00C5);}
-{WIN_U00C6} { yyreplace_utf8(U00C6);}
-{WIN_U00C7} { yyreplace_utf8(U00C7);}
-{WIN_U00C8} { yyreplace_utf8(U00C8);}
-{WIN_U00C9} { yyreplace_utf8(U00C9);}
-{WIN_U00CA} { yyreplace_utf8(U00CA);}
-{WIN_U00CB} { yyreplace_utf8(U00CB);}
-{WIN_U00CC} { yyreplace_utf8(U00CC);}
-{WIN_U00CD} { yyreplace_utf8(U00CD);}
-{WIN_U00CE} { yyreplace_utf8(U00CE);}
-{WIN_U00CF} { yyreplace_utf8(U00CF);}
-{WIN_U00D0} { yyreplace_utf8(U00D0);}
-{WIN_U00D1} { yyreplace_utf8(U00D1);}
-{WIN_U00D2} { yyreplace_utf8(U00D2);}
-{WIN_U00D3} { yyreplace_utf8(U00D3);}
-{WIN_U00D4} { yyreplace_utf8(U00D4);}
-{WIN_U00D5} { yyreplace_utf8(U00D5);}
-{WIN_U00D6} { yyreplace_utf8(U00D6);}
-{WIN_U00D7} { yyreplace_utf8(U00D7);}
-{WIN_U00D8} { yyreplace_utf8(U00D8);}
-{WIN_U00D9} { yyreplace_utf8(U00D9);}
-{WIN_U00DA} { yyreplace_utf8(U00DA);}
-{WIN_U00DB} { yyreplace_utf8(U00DB);}
-{WIN_U00DC} { yyreplace_utf8(U00DC);}
-{WIN_U00DD} { yyreplace_utf8(U00DD);}
-{WIN_U00DE} { yyreplace_utf8(U00DE);}
-{WIN_U00DF} { yyreplace_utf8(U00DF);}
-{WIN_U00E0} { yyreplace_utf8(U00E0);}
-{WIN_U00E1} { yyreplace_utf8(U00E1);}
-{WIN_U00E2} { yyreplace_utf8(U00E2);}
-{WIN_U00E3} { yyreplace_utf8(U00E3);}
-{WIN_U00E4} { yyreplace_utf8(U00E4);}
-{WIN_U00E5} { yyreplace_utf8(U00E5);}
-{WIN_U00E6} { yyreplace_utf8(U00E6);}
-{WIN_U00E7} { yyreplace_utf8(U00E7);}
-{WIN_U00E8} { yyreplace_utf8(U00E8);}
-{WIN_U00E9} { yyreplace_utf8(U00E9);}
-{WIN_U00EA} { yyreplace_utf8(U00EA);}
-{WIN_U00EB} { yyreplace_utf8(U00EB);}
-{WIN_U00EC} { yyreplace_utf8(U00EC);}
-{WIN_U00ED} { yyreplace_utf8(U00ED);}
-{WIN_U00EE} { yyreplace_utf8(U00EE);}
-{WIN_U00EF} { yyreplace_utf8(U00EF);}
-{WIN_U00F0} { yyreplace_utf8(U00F0);}
-{WIN_U00F1} { yyreplace_utf8(U00F1);}
-{WIN_U00F2} { yyreplace_utf8(U00F2);}
-{WIN_U00F3} { yyreplace_utf8(U00F3);}
-{WIN_U00F4} { yyreplace_utf8(U00F4);}
-{WIN_U00F5} { yyreplace_utf8(U00F5);}
-{WIN_U00F6} { yyreplace_utf8(U00F6);}
-{WIN_U00F7} { yyreplace_utf8(U00F7);}
-{WIN_U00F8} { yyreplace_utf8(U00F8);}
-{WIN_U00F9} { yyreplace_utf8(U00F9);}
-{WIN_U00FA} { yyreplace_utf8(U00FA);}
-{WIN_U00FB} { yyreplace_utf8(U00FB);}
-{WIN_U00FC} { yyreplace_utf8(U00FC);}
-{WIN_U00FD} { yyreplace_utf8(U00FD);}
-{WIN_U00FE} { yyreplace_utf8(U00FE);}
-{WIN_U00FF} { yyreplace_utf8(U00FF);}
-
-%%
-
-#ifndef yywrap
-int 
-yywrap(void) 
-{
-	return 1;
-}
-#endif
-
-int
-yyreplace_utf8(char *str)
-{
-	memcpy(&newbuf[newbuf_idx], str, strlen(str));
-	newbuf_idx += strlen(str);
-	return 0;
-}
-
-int
-yyparse_utf8(char *mybuf, char *str)
-{
-	newbuf = mybuf;
-	newbuf_idx = 0;
-	yy_scan_string(str);
-	yylex();
-	newbuf[newbuf_idx] = 0;
-	libmapi_utf8_convert_lex_destroy();
-	return 0;
-}

Modified: trunk/openchange/libmapi/utils.c
===================================================================
--- trunk/openchange/libmapi/utils.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/utils.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -21,10 +21,13 @@
 #include <libmapi/proto_private.h>
 #include <gen_ndr/ndr_exchange.h>
 
-/*
-  Constructs a PR_ENTRYID value for recipients.
+/**
+   \file utils.c
+
+   \brief General utility functions
  */
 
+
 /* 
    FIXME: 
    nor     0x00 0x00 0x00 0x00 at the beginning 
@@ -64,6 +67,9 @@
 	return guid;
 }
 
+/*
+  Constructs a PR_ENTRYID value for recipients.
+ */
 _PUBLIC_ struct Binary_r *generate_recipient_entryid(TALLOC_CTX *mem_ctx, const char *recipient_id)
 {
 	struct Binary_r	*entryid;
@@ -95,36 +101,12 @@
 }
 
 /**
- * convert utf8 windows string into classic utf8
- * NOTE: windows utf8 encoding is equal or larger to classic utf8
- *       we should anyway find a better way to allocate the output buf
- */
-
-int yyparse_utf8(char *, const char *);
-
-_PUBLIC_ char *windows_to_utf8(TALLOC_CTX *mem_ctx, const char *input)
-{
-	char	*tmp = NULL;
-	char	*output;
-
-	if (!input) return NULL;
-
-	tmp = malloc(strlen(input) + 1);
-	yyparse_utf8(tmp, input);
-	output = talloc_strdup(mem_ctx, tmp);
-	free(tmp);
-	
-	return output;
-}
-
-
-/**
    \details Create a FID from an EntryID
 
    \param cb count of lpb bytes
    \param lpb pointer on an array of bytes
    \param parent_fid the parent folder identifier
-   \param pointer on the returned fid
+   \param fid pointer to the returned fid
 
    \return MAPI_E_SUCCESS on success, otherwise
    MAPI_E_INVALID_PARAMETER

Modified: trunk/openchange/libmapi/x500.c
===================================================================
--- trunk/openchange/libmapi/x500.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi/x500.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -19,7 +19,25 @@
 
 #include <libmapi/libmapi.h>
 
+#include "config.h"
 
+#ifndef HAVE_STRCASESTR
+static char *strcasestr(const char *haystack, const char *needle)
+{
+       const char *s;
+       size_t nlen = strlen(needle);
+
+       for (s=haystack;*s;s++) {
+               if (toupper(*needle) == toupper(*s) &&
+                               strncasecmp(s, needle, nlen) == 0) {
+                       return (char *)((uintptr_t)s);
+               }
+       }
+       return NULL;
+}
+#endif
+
+
 /**
    \details Extract a DN element from a given DN
 

Modified: trunk/openchange/libmapi++/attachment.h
===================================================================
--- trunk/openchange/libmapi++/attachment.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/attachment.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -49,66 +49,8 @@
 		 *  \param mapi_message the message that this attachment belongs to.
 		 *  \param attach_num Attachment Number.
 		 */
-		attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception)
-		: object(mapi_message.get_session(), "attachment"), m_attach_num(attach_num), m_bin_data(NULL), m_data_size(0), m_filename("")
-		{
-			if (OpenAttach(&mapi_message.data(), attach_num, &m_object) != MAPI_E_SUCCESS)
-				throw mapi_exception(GetLastError(), "attachment::attachment : OpenAttach");
+		attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception);
 
-			property_container properties = get_property_container();
-			properties << PR_ATTACH_FILENAME << PR_ATTACH_LONG_FILENAME << PR_ATTACH_SIZE << PR_ATTACH_DATA_BIN << PR_ATTACH_METHOD;
-			properties.fetch();
-			
-			const char* filename = static_cast<const char*>(properties[PR_ATTACH_LONG_FILENAME]);
-			if (!filename) {
-				filename = static_cast<const char*>(properties[PR_ATTACH_FILENAME]);
-			}
-
-			if (filename) {
-				m_filename = filename;
-			}
-
-			m_data_size = *(static_cast<const uint32_t*>(properties[PR_ATTACH_SIZE]));
-
-			const Binary_r* attachment_data = static_cast<const Binary_r*>(properties[PR_ATTACH_DATA_BIN]);
-
-			// Don't load PR_ATTACH_DATA_BIN if it's embedded in message.
-			// NOTE: Use RopOpenEmbeddedMessage when it is implemented.
-			const uint32_t attach_method = *static_cast<const uint32_t*>(properties[PR_ATTACH_METHOD]);
-			if (attach_method != ATTACH_BY_VALUE)
-				return;
-
-			// Get Binary Data.
-			if (attachment_data) {
-				m_data_size = attachment_data->cb;
-				m_bin_data = new uint8_t[m_data_size];
-				memcpy(m_bin_data, attachment_data->lpb, attachment_data->cb);
-			} else {
-				mapi_object_t obj_stream;
-				mapi_object_init(&obj_stream);
-				if (OpenStream(&m_object, PR_ATTACH_DATA_BIN, OpenStream_ReadOnly, &obj_stream) != MAPI_E_SUCCESS)
-					throw mapi_exception(GetLastError(), "attachment::attachment : OpenStream");
-
-				if (GetStreamSize(&obj_stream, &m_data_size) != MAPI_E_SUCCESS)
-					throw mapi_exception(GetLastError(), "attachment::attachment : GetStreamSize");
-
-                                m_bin_data = new uint8_t[m_data_size];
-
-				uint32_t pos = 0;
-				uint16_t bytes_read = 0;
-				do {
-					if (ReadStream(&obj_stream, m_bin_data+pos, 1024, &bytes_read) != MAPI_E_SUCCESS)
-						throw mapi_exception(GetLastError(), "attachment::attachment : ReadStream");
-
-					pos += bytes_read;
-
-				} while (bytes_read && pos < m_data_size);
-				
-				mapi_object_release(&obj_stream);
-			}
-
-		}
-
 		/**
 		 * \brief The %attachment number
 		 */

Modified: trunk/openchange/libmapi++/folder.h
===================================================================
--- trunk/openchange/libmapi++/folder.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/folder.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -93,105 +93,15 @@
 		 *
 		 * \return A container of message shared pointers.
 		 */
-		message_container_type fetch_messages() throw(mapi_exception)
-		{
-			uint32_t 	contents_table_row_count = 0;
-			mapi_object_t 	contents_table;
+		message_container_type fetch_messages() throw(mapi_exception);
 
-			mapi_object_init(&contents_table);
-			if (GetContentsTable(&m_object, &contents_table, 0, &contents_table_row_count) != MAPI_E_SUCCESS) {
-				mapi_object_release(&contents_table);
-				throw mapi_exception(GetLastError(), "folder::fetch_messages : GetContentsTable");
-			}
-
-			SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x2, PR_FID,
-													       PR_MID);
-
-			if (SetColumns(&contents_table, property_tag_array) != MAPI_E_SUCCESS) {
-				MAPIFreeBuffer(property_tag_array);
-				mapi_object_release(&contents_table);
-				throw mapi_exception(GetLastError(), "folder::fetch_messages : SetColumns");
-			}
-
-			MAPIFreeBuffer(property_tag_array);
-
-			uint32_t rows_to_read = contents_table_row_count;
-			SRowSet  row_set;
-
-			message_container_type message_container;
-			message_container.reserve(contents_table_row_count);
-
-			while( (QueryRows(&contents_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) {
-				rows_to_read -= row_set.cRows;
-				for (unsigned int i = 0; i < row_set.cRows; ++i) {
-					try {
-						message_container.push_back(message_shared_ptr(new message(m_session,
-													   m_id,
-												           row_set.aRow[i].lpProps[1].value.d)));
-					}
-					catch(mapi_exception e) {
-						mapi_object_release(&contents_table);
-						throw;
-					}
-				}
-			}
-
-			mapi_object_release(&contents_table);
-
-			return message_container;
-		}
-
 		/**
 		 * \brief Fetch all subfolders within this %folder
 		 *
 		 * \return A container of %folder shared pointers.
 		 */
-		hierarchy_container_type fetch_hierarchy() throw(mapi_exception)
-		{
-			mapi_object_t 	hierarchy_table;
-			uint32_t	hierarchy_table_row_count = 0;
+		hierarchy_container_type fetch_hierarchy() throw(mapi_exception);
 
-			mapi_object_init(&hierarchy_table);
-			if (GetHierarchyTable(&m_object, &hierarchy_table, 0, &hierarchy_table_row_count) != MAPI_E_SUCCESS) {
-				mapi_object_release(&hierarchy_table);
-				throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : GetHierarchyTable");
-			}
-
-			SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_FID);
-
-			if (SetColumns(&hierarchy_table, property_tag_array)) {
-				MAPIFreeBuffer(property_tag_array);
-				mapi_object_release(&hierarchy_table);
-				throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : SetColumns");
-			}
-
-			MAPIFreeBuffer(property_tag_array);
-
-			uint32_t rows_to_read = hierarchy_table_row_count;
-			SRowSet  row_set;
-			
-			hierarchy_container_type hierarchy_container;
-			hierarchy_container.reserve(hierarchy_table_row_count);
-
-			while( (QueryRows(&hierarchy_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) {
-				rows_to_read -= row_set.cRows;
-				for (unsigned int i = 0; i < row_set.cRows; ++i) {
-					try {
-						hierarchy_container.push_back(folder_shared_ptr(new folder(*this, 
-												           row_set.aRow[i].lpProps[0].value.d)));
-					}
-					catch(mapi_exception e) {
-						mapi_object_release(&hierarchy_table);
-						throw;
-					}
-				}
-			}
-
-                        mapi_object_release(&hierarchy_table);
-
-                        return hierarchy_container;
-		}
-
 		/**
 		 * Destructor
 		 */

Modified: trunk/openchange/libmapi++/mapi_exception.h
===================================================================
--- trunk/openchange/libmapi++/mapi_exception.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/mapi_exception.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -37,21 +37,16 @@
 class mapi_exception : public std::exception
 {
 	public:
-	
-		mapi_exception(enum MAPISTATUS status, const std::string& origin = "") : std::exception(), m_status(status), m_origin(origin)
+		explicit mapi_exception(enum MAPISTATUS status, const std::string& origin = "") : std::exception(), m_status(status), m_origin(origin), m_what_string(origin)
 		{
-		}
-
-		virtual const char* what() const throw()
-		{
 			status_map::iterator iter = sm_status_map.find(m_status);
 
-			std::string ret_string = m_origin; 
-			ret_string += ": ";
-			ret_string += (iter != sm_status_map.end()) ? iter->second : "Unknown MAPISTATUS value";
-
-			return const_cast<const char*>(::strdup(ret_string.c_str()));
+			m_what_string += ": ";
+			m_what_string += (iter != sm_status_map.end()) ? iter->second : "Unknown MAPISTATUS value";
 		}
+
+		virtual const char* what() const throw() { return m_what_string.c_str(); }
+
 		enum MAPISTATUS get_status() const { return m_status; }
 
 		virtual ~mapi_exception() throw() {}
@@ -59,6 +54,7 @@
 	private:
 		enum MAPISTATUS	m_status;
 		std::string	m_origin;
+		std::string	m_what_string;
 		friend class session;
 
 		typedef std::map<enum MAPISTATUS, const char*> status_map;
@@ -143,8 +139,6 @@
 		}	
 };
 
-mapi_exception::status_map mapi_exception::sm_status_map = status_map();
-
 } // namespace libmapipp
 
 #endif //!LIBMAPIPP__EXCEPTION_H__

Modified: trunk/openchange/libmapi++/message.h
===================================================================
--- trunk/openchange/libmapi++/message.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/message.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -24,14 +24,16 @@
 
 #include <iostream> //for debugging
 #include <vector>
+#include <boost/shared_ptr.hpp>
 
 #include <libmapi++/mapi_exception.h>
 #include <libmapi++/session.h>
 #include <libmapi++/clibmapi.h>
+#include <libmapi++/object.h>
+#include <libmapi++/message_store.h>
 
 namespace libmapipp
 {
-class object;
 class attachment;
 
 /** 
@@ -91,6 +93,4 @@
 
 } // namespace libmapipp
 
-#include <libmapi++/impl/message.ipp>
-
 #endif //!LIBMAPIPP__MESSAGE_H__

Modified: trunk/openchange/libmapi++/message_store.h
===================================================================
--- trunk/openchange/libmapi++/message_store.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/message_store.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -64,7 +64,7 @@
 		 * - olFolderDrafts
 		 *
 		 * If you are trying to enumerate all folders, you should open the 
-		 * olFolderTopInformationStore, and then get the hierachy container for
+		 * olFolderTopInformationStore, and then get the hierarchy container for
 		 * that top level folder.
 		 *
 		 * \return The resulting folder id.

Modified: trunk/openchange/libmapi++/object.h
===================================================================
--- trunk/openchange/libmapi++/object.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/object.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -26,7 +26,6 @@
 #include <stdexcept>
 
 #include <libmapi++/clibmapi.h>
-#include <libmapi++/session.h>
 
 /**
  *  The libmapi++ classes and other definitions are all enclosed in
@@ -36,7 +35,7 @@
 {
 // #define INVALID_HANDLE_VALUE 0xffffffff
 class property_container;
-
+class session;
 /**
  * Base Object class
  *
@@ -53,7 +52,7 @@
 		 * \param mapi_session Session this object is to be associated with.
 		 * \param object_type The name of the type of object (to be set in a subclass)
 		 */
-		object(session& mapi_session, const std::string& object_type = "") throw() : m_session(mapi_session), m_object_type(object_type)
+		explicit object(session& mapi_session, const std::string& object_type = "") throw() : m_session(mapi_session), m_object_type(object_type)
 		{
 			mapi_object_init(&m_object);
 		}
@@ -103,6 +102,4 @@
 
 } // namespace libmapipp
 
-#include <libmapi++/impl/object.ipp>
-
 #endif //!LIBMAPIPP__OBJECT_H__

Modified: trunk/openchange/libmapi++/profile.h
===================================================================
--- trunk/openchange/libmapi++/profile.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/profile.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -38,6 +38,31 @@
 {
 	public:
 
+		/* Create an new profile database
+		 *
+		 * \param profiledb the absolute path to the profile database intended to be created
+		 * \param ldif_path the absolute path to the LDIF information to use for initial setup
+		 *
+		 */
+		bool static create_profile_store(const char* profiledb, const char* ldif_path = NULL)
+		{
+                        if (ldif_path == NULL)
+                            ldif_path = ::mapi_profile_get_ldif_path();
+			return (CreateProfileStore(profiledb, ldif_path) == MAPI_E_SUCCESS);
+		}
+ 
+ 		/**
+		 * Create an new profile database
+		 *
+		 * \param profiledb the absolute path to the profile database intended to be created
+		 * \param ldif_path the absolute path to the LDIF information to use for initial setup
+		 *
+		 */
+		bool static create_profile_store(const std::string& profiledb, const std::string& ldif_path)
+		{
+			return create_profile_store(profiledb.c_str(), ldif_path.c_str());
+		}
+
 		/**
 		 * Make the specified profile the default profile
 		 *

Modified: trunk/openchange/libmapi++/property_container.h
===================================================================
--- trunk/openchange/libmapi++/property_container.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/property_container.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -296,7 +296,7 @@
 		{
 			for (uint32_t i = 0; i < m_cn_vals; ++i)
 			{
-				if (m_property_values[i].ulPropTag == property_tag)
+			  if ((uint32_t)m_property_values[i].ulPropTag == property_tag)
 					return get_SPropValue_data(&m_property_values[i]);
 			}
 

Modified: trunk/openchange/libmapi++/session.h
===================================================================
--- trunk/openchange/libmapi++/session.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapi++/session.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -30,13 +30,13 @@
 
 #include <libmapi++/clibmapi.h>
 #include <libmapi++/mapi_exception.h>
+#include <libmapi++/message_store.h>
 
 using std::cout;
 using std::endl;
 
 namespace libmapipp
 {
-class message_store;
 /**
  * This class represents a MAPI %session with the Exchange Server
  *
@@ -70,7 +70,7 @@
 		 *
 		 * \param debug Whether to output debug information to stdout
 		 */
-		session(const std::string& profiledb = "", const bool debug = false) throw(std::runtime_error, mapi_exception);
+		explicit session(const std::string& profiledb = "", const bool debug = false) throw(std::runtime_error, mapi_exception);
 
 		/**
 		 * \brief Log-in to the Exchange Server
@@ -136,11 +136,14 @@
 		message_store		*m_message_store;
 		std::string		m_profile_name;
 
-		void uninitialize() throw();
+		void uninitialize() throw()
+		{
+			talloc_free(m_memory_ctx);
+			MAPIUninitialize();
+			delete m_message_store;
+		}
 };
 
 } // namespace libmapipp
 
-#include <libmapi++/impl/session.ipp>
-
 #endif //!LIBMAPIPP__SESSION_H__

Added: trunk/openchange/libmapi++/src/attachment.cpp
===================================================================
--- trunk/openchange/libmapi++/src/attachment.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/attachment.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,86 @@
+/*
+   libmapi C++ Wrapper
+   Attachment Class implementation.
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/attachment.h>
+#include <libmapi++/property_container.h>
+
+namespace libmapipp {
+
+attachment::attachment(message& mapi_message, const uint32_t attach_num) throw(mapi_exception)
+: object(mapi_message.get_session(), "attachment"), m_attach_num(attach_num), m_bin_data(NULL), m_data_size(0), m_filename("")
+{
+	if (OpenAttach(&mapi_message.data(), attach_num, &m_object) != MAPI_E_SUCCESS)
+		throw mapi_exception(GetLastError(), "attachment::attachment : OpenAttach");
+
+	property_container properties = get_property_container();
+	properties << PR_ATTACH_FILENAME << PR_ATTACH_LONG_FILENAME << PR_ATTACH_SIZE << PR_ATTACH_DATA_BIN << PR_ATTACH_METHOD;
+	properties.fetch();
+
+	const char* filename = static_cast<const char*>(properties[PR_ATTACH_LONG_FILENAME]);
+	if (!filename) {
+		filename = static_cast<const char*>(properties[PR_ATTACH_FILENAME]);
+	}
+
+	if (filename)
+		m_filename = filename;
+
+	m_data_size = *(static_cast<const uint32_t*>(properties[PR_ATTACH_SIZE]));
+
+	const Binary_r* attachment_data = static_cast<const Binary_r*>(properties[PR_ATTACH_DATA_BIN]);
+
+	// Don't load PR_ATTACH_DATA_BIN if it's embedded in message.
+	// NOTE: Use RopOpenEmbeddedMessage when it is implemented.
+	const uint32_t attach_method = *static_cast<const uint32_t*>(properties[PR_ATTACH_METHOD]);
+	if (attach_method != ATTACH_BY_VALUE)
+		return;
+
+	// Get Binary Data.
+	if (attachment_data) {
+		m_data_size = attachment_data->cb;
+		m_bin_data = new uint8_t[m_data_size];
+		memcpy(m_bin_data, attachment_data->lpb, attachment_data->cb);
+	} else {
+		mapi_object_t obj_stream;
+		mapi_object_init(&obj_stream);
+		if (OpenStream(&m_object, PR_ATTACH_DATA_BIN, OpenStream_ReadOnly, &obj_stream) != MAPI_E_SUCCESS)
+			throw mapi_exception(GetLastError(), "attachment::attachment : OpenStream");
+
+		if (GetStreamSize(&obj_stream, &m_data_size) != MAPI_E_SUCCESS)
+			throw mapi_exception(GetLastError(), "attachment::attachment : GetStreamSize");
+
+		m_bin_data = new uint8_t[m_data_size];
+
+		uint32_t pos = 0;
+		uint16_t bytes_read = 0;
+		do {
+			if (ReadStream(&obj_stream, m_bin_data+pos, 1024, &bytes_read) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "attachment::attachment : ReadStream");
+
+			pos += bytes_read;
+
+		} while (bytes_read && pos < m_data_size);
+
+		mapi_object_release(&obj_stream);
+	}
+}
+
+
+} // namespace libmapipp
+

Added: trunk/openchange/libmapi++/src/folder.cpp
===================================================================
--- trunk/openchange/libmapi++/src/folder.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/folder.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,118 @@
+/*
+   libmapi C++ Wrapper
+   Folder Class implementation.
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/folder.h>
+
+namespace libmapipp {
+
+folder::message_container_type folder::fetch_messages() throw(mapi_exception)
+{
+	uint32_t 	contents_table_row_count = 0;
+        mapi_object_t	contents_table;
+
+	mapi_object_init(&contents_table);
+	if (GetContentsTable(&m_object, &contents_table, 0, &contents_table_row_count) != MAPI_E_SUCCESS) {
+		mapi_object_release(&contents_table);
+		throw mapi_exception(GetLastError(), "folder::fetch_messages : GetContentsTable");
+	}
+
+	SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x2, PR_FID,
+											       PR_MID);
+
+	if (SetColumns(&contents_table, property_tag_array) != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(property_tag_array);
+		mapi_object_release(&contents_table);
+		throw mapi_exception(GetLastError(), "folder::fetch_messages : SetColumns");
+	}
+
+	MAPIFreeBuffer(property_tag_array);
+
+	uint32_t rows_to_read = contents_table_row_count;
+	SRowSet  row_set;
+
+	message_container_type message_container;
+	message_container.reserve(contents_table_row_count);
+
+	while( (QueryRows(&contents_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) {
+		rows_to_read -= row_set.cRows;
+		for (unsigned int i = 0; i < row_set.cRows; ++i) {
+			try {
+				message_container.push_back(message_shared_ptr(new message(m_session,
+											   m_id,
+											   row_set.aRow[i].lpProps[1].value.d)));
+			} catch(mapi_exception e) {
+				mapi_object_release(&contents_table);
+				throw;
+			}
+		}
+	}
+
+	mapi_object_release(&contents_table);
+
+	return message_container;
+}
+
+folder::hierarchy_container_type folder::fetch_hierarchy() throw(mapi_exception)
+{
+	mapi_object_t	hierarchy_table;
+	uint32_t	hierarchy_table_row_count = 0;
+
+	mapi_object_init(&hierarchy_table);
+	if (GetHierarchyTable(&m_object, &hierarchy_table, 0, &hierarchy_table_row_count) != MAPI_E_SUCCESS) {
+		mapi_object_release(&hierarchy_table);
+		throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : GetHierarchyTable");
+	}
+
+	SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_FID);
+
+	if (SetColumns(&hierarchy_table, property_tag_array)) {
+		MAPIFreeBuffer(property_tag_array);
+		mapi_object_release(&hierarchy_table);
+		throw mapi_exception(GetLastError(), "folder::fetch_hierarchy : SetColumns");
+	}
+
+	MAPIFreeBuffer(property_tag_array);
+
+	uint32_t rows_to_read = hierarchy_table_row_count;
+	SRowSet  row_set;
+
+	hierarchy_container_type hierarchy_container;
+	hierarchy_container.reserve(hierarchy_table_row_count);
+
+	while( (QueryRows(&hierarchy_table, rows_to_read, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) {
+		rows_to_read -= row_set.cRows;
+		for (unsigned int i = 0; i < row_set.cRows; ++i) {
+			try {
+				hierarchy_container.push_back(folder_shared_ptr(new folder(*this,
+							      row_set.aRow[i].lpProps[0].value.d)));
+			} catch(mapi_exception e) {
+				mapi_object_release(&hierarchy_table);
+				throw;
+			}
+		}
+	}
+
+	mapi_object_release(&hierarchy_table);
+
+	return hierarchy_container;
+}
+
+} // namespace libmapipp
+

Added: trunk/openchange/libmapi++/src/mapi_exception.cpp
===================================================================
--- trunk/openchange/libmapi++/src/mapi_exception.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/mapi_exception.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,28 @@
+/*
+   libmapi C++ Wrapper
+   mapi_exception Class implementation.
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/mapi_exception.h>
+
+namespace libmapipp {
+
+mapi_exception::status_map mapi_exception::sm_status_map = status_map();
+
+} // namespace libmapipp
+

Added: trunk/openchange/libmapi++/src/message.cpp
===================================================================
--- trunk/openchange/libmapi++/src/message.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/message.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,64 @@
+/*
+   libmapi C++ Wrapper
+   Message class implementation
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/attachment.h>
+
+namespace libmapipp {
+
+message::attachment_container_type message::fetch_attachments()
+{
+	mapi_object_t   attachment_table;
+
+	mapi_object_init(&attachment_table);
+	if (GetAttachmentTable(&m_object, &attachment_table) != MAPI_E_SUCCESS) {
+		mapi_object_release(&attachment_table);
+		throw mapi_exception(GetLastError(), "message::fetch_attachments : GetAttachmentTable");
+	}
+
+	SPropTagArray* property_tag_array = set_SPropTagArray(m_session.get_memory_ctx(), 0x1, PR_ATTACH_NUM);
+
+	if (SetColumns(&attachment_table, property_tag_array) != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(property_tag_array);
+		mapi_object_release(&attachment_table);
+		throw mapi_exception(GetLastError(), "message::fetch_attachments : SetColumns");
+	}
+
+	MAPIFreeBuffer(property_tag_array);
+
+	SRowSet  row_set;
+	attachment_container_type attachment_container;
+
+	while( (QueryRows(&attachment_table, 0x32, TBL_ADVANCE, &row_set) == MAPI_E_SUCCESS) && row_set.cRows) {
+		for (unsigned int i = 0; i < row_set.cRows; ++i) {
+			try {
+				attachment_container.push_back(attachment_shared_ptr(new attachment(*this, row_set.aRow[i].lpProps[0].value.l)));
+			}
+			catch(mapi_exception e) {
+				mapi_object_release(&attachment_table);
+				throw;
+			}
+		}
+	}
+	mapi_object_release(&attachment_table);
+
+	return attachment_container;
+}
+
+} // namespace libmapipp

Added: trunk/openchange/libmapi++/src/object.cpp
===================================================================
--- trunk/openchange/libmapi++/src/object.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/object.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,33 @@
+/*
+   libmapi C++ Wrapper
+   Object Class implementation.
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/object.h>
+#include <libmapi++/property_container.h>
+#include <libmapi++/session.h>
+
+namespace libmapipp {
+
+property_container object::get_property_container() 
+{ 
+	return property_container(m_session.get_memory_ctx(), m_object); 
+}
+
+} // namespace libmapipp
+

Added: trunk/openchange/libmapi++/src/session.cpp
===================================================================
--- trunk/openchange/libmapi++/src/session.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/src/session.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,92 @@
+/*
+   libmapi C++ Wrapper
+   Session Class implementation.
+
+   Copyright (C) Alan Alvarez 2008.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi++/message_store.h>
+#include <libmapi++/profile.h>
+#include <libmapi++/session.h>
+
+namespace libmapipp {
+
+inline std::string session::get_default_profile_path()
+{
+	const char* profile_path = getenv("HOME");
+	std::string retval = "";
+	if (profile_path) {
+		retval = profile_path;
+		retval += "/.openchange/profiles.ldb";
+	}
+
+	return retval;
+}
+
+session::session(const std::string& profiledb, bool debug) throw(std::runtime_error, mapi_exception) 
+: m_session(NULL), m_memory_ctx(talloc_named(NULL, 0, "libmapi++")), m_message_store(new message_store(*this))
+{
+	mapi_exception::fill_status_map();
+
+	std::string profile_path;
+
+	// If profile is not provided, attempt to get it from default location
+	// (~/.openchange/profiles.ldb)
+	if (profiledb == "") {
+		profile_path = get_default_profile_path();
+		if (profile_path == "") {
+			talloc_free(m_memory_ctx);
+			delete m_message_store;
+			throw std::runtime_error("libmapipp::session(): Failed to get $HOME env variable");
+		}
+	} else {
+		profile_path = profiledb;
+	}
+
+	if (MAPIInitialize(profile_path.c_str()) != MAPI_E_SUCCESS) {
+		talloc_free(m_memory_ctx);
+		delete m_message_store;
+		throw mapi_exception(GetLastError(), "session::session : MAPIInitialize");
+	}
+
+	if (debug) global_mapi_ctx->dumpdata = true;
+}
+
+void session::login(const std::string& profile_name, const std::string& password) throw (mapi_exception)
+{
+	m_profile_name = profile_name;
+	if (m_profile_name == "") { // if profile is not set, try to get default profile
+		try {
+			m_profile_name = profile::get_default_profile();
+		} catch(mapi_exception e) {
+			uninitialize();
+			throw;
+		}
+	}
+
+	if (MapiLogonEx(&m_session, m_profile_name.c_str(), (password != "") ? password.c_str() : 0 ) != MAPI_E_SUCCESS) {
+		uninitialize();
+		throw mapi_exception(GetLastError(), "session::session : MapiLogonEx");
+	}
+
+	try {
+		m_message_store->open(m_session);
+	} catch (mapi_exception e) {
+		throw;
+	}
+}
+
+} // namespace libmapipp

Added: trunk/openchange/libmapi++/tests/exception_test.cpp
===================================================================
--- trunk/openchange/libmapi++/tests/exception_test.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/tests/exception_test.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,21 @@
+#include <iostream>
+
+#include <libmapi++/libmapi++.h>
+
+static void dotest() throw(libmapipp::mapi_exception)
+{
+	throw libmapipp::mapi_exception(MAPI_E_SUCCESS, "mapi_exception test");
+}
+
+int main()
+{
+	try {
+		dotest();
+	}
+	catch (libmapipp::mapi_exception e) {
+		std::cout << e.what() << std::endl;
+	}
+	
+	return 0;
+}
+

Added: trunk/openchange/libmapi++.pc.in
===================================================================
--- trunk/openchange/libmapi++.pc.in	                        (rev 0)
+++ trunk/openchange/libmapi++.pc.in	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: OpenChange C++ bindings
+Description: C++ bindings for the OpenChange MAPI library
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lmapipp
+Cflags: -I${includedir}
+Requires: libmapi

Modified: trunk/openchange/libmapiadmin/mapiadmin_user.c
===================================================================
--- trunk/openchange/libmapiadmin/mapiadmin_user.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapiadmin/mapiadmin_user.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -226,7 +226,7 @@
 	remote_ldb_url = talloc_asprintf(mem_ctx, "ldap://%s", profile->server);
 	MAPI_RETVAL_IF(!remote_ldb_url, MAPI_E_CORRUPT_DATA, mem_ctx);
 	remote_ldb = ldb_wrap_connect(mem_ctx, ev, global_mapi_ctx->lp_ctx, remote_ldb_url, 
-				      NULL, mapiadmin_ctx->session->profile->credentials, 0, NULL);
+				      NULL, mapiadmin_ctx->session->profile->credentials, 0);
 	MAPI_RETVAL_IF(!remote_ldb, MAPI_E_NETWORK_ERROR, mem_ctx);
 
 	/* Search the user_dn */

Modified: trunk/openchange/libmapiadmin.pc.in
===================================================================
--- trunk/openchange/libmapiadmin.pc.in	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libmapiadmin.pc.in	2010-02-11 11:16:26 UTC (rev 3288)
@@ -8,6 +8,8 @@
 Name: MAPI admin library
 Description: Library supporting MAPI administration actions
 Version: @PACKAGE_VERSION@
-Libs: @LIBS@
-Cflags: @CFLAGS@
-Requires: talloc dcerpc ndr samba-hostconfig ldb
+Libs: -L${libdir} -lmapiadmin
+Libs.private: @LIBS@
+Cflags: -I${includedir}
+Requires: libmapi dcerpc_samr
+

Modified: trunk/openchange/libocpf/ocpf_public.c
===================================================================
--- trunk/openchange/libocpf/ocpf_public.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libocpf/ocpf_public.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -337,7 +337,7 @@
 				mapi_object_release(&obj_htable);
 				mapi_object_release(&obj_folder);
 				return MAPI_E_SUCCESS;
-			} else {
+			} else if (fid) {
 				retval = ocpf_folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret);
 				if (retval == MAPI_E_SUCCESS) {
 					mapi_object_release(&obj_htable);

Modified: trunk/openchange/libocpf.pc.in
===================================================================
--- trunk/openchange/libocpf.pc.in	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/libocpf.pc.in	2010-02-11 11:16:26 UTC (rev 3288)
@@ -8,6 +8,6 @@
 Name: OpenChange Property File
 Description: OCPF file format support
 Version: @PACKAGE_VERSION@
-Libs: @LIBS@ -locpf
-Cflags: @CFLAGS@
+Libs: -L${libdir} -locpf
+Cflags: -I${includedir}
 Requires: libmapi

Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -23,7 +23,7 @@
 
 #include "mapiproxy/dcesrv_mapiproxy.h"
 #include "mapiproxy/dcesrv_mapiproxy_proto.h"
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 #include <libmapi/defs_private.h>
 #include <util/debug.h>
 
@@ -149,7 +149,7 @@
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
-		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
+		dce_call->context->assoc_group->id = private->c_pipe->assoc_group_id;
 		
 	} else {
 		status = dcerpc_pipe_connect(dce_call->context,
@@ -164,7 +164,7 @@
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
-		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
+		dce_call->context->assoc_group->id = private->c_pipe->assoc_group_id;
 	}
 
 	private->connected = true;

Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -21,6 +21,8 @@
 
 #define	_GNU_SOURCE 1
 
+#include "config.h"
+
 #include <sys/types.h>
 
 #include <stdio.h>
@@ -44,7 +46,10 @@
 #include "mapiproxy/dcesrv_mapiproxy_proto.h"
 
 #include <sys/types.h>
+
+#ifdef HAVE_SYS_CDEFS_H
 #include <sys/cdefs.h>
+#endif
 
 /*
    endpoint server for the exchange_store_admin3 pipe

Modified: trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -29,7 +29,7 @@
 #include <tdb.h>
 #include <ldb.h>
 #include <ldb_errors.h>
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 #include <fcntl.h>
 #include <errno.h>
 

Modified: trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -25,7 +25,7 @@
 
 #include <mapiproxy/libmapistore/mapistore.h>
 #include <mapiproxy/libmapistore/mapistore_errors.h>
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 #include <sqlite3.h>
 
 struct sqlite3_context {

Modified: trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -31,7 +31,7 @@
 #include "mapistore.h"
 #include "mapistore_errors.h"
 #include "mapistore_private.h"
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 
 #include <util.h>
 #include <util/debug.h>

Modified: trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -22,7 +22,7 @@
 #include "mapistore.h"
 #include "mapistore_errors.h"
 #include "mapistore_private.h"
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 
 #include <string.h>
 

Modified: trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -28,7 +28,7 @@
 #include "mapistore.h"
 #include "mapistore_errors.h"
 #include "mapistore_private.h"
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 #include <libmapi/defs_private.h>
 
 #include <tdb.h>

Modified: trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -25,7 +25,7 @@
 
 #include "mapistore.h"
 #include "mapistore_private.h"
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 
 static struct tdb_wrap *tdb_list;
 

Modified: trunk/openchange/mapiproxy/modules/mpm_cache.h
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/modules/mpm_cache.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -24,7 +24,7 @@
 
 #include <stdio.h>
 
-#include <libmapi/dlinklist.h>
+#include <dlinklist.h>
 #include <ldb_errors.h>
 #include <ldb.h>
 

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -46,10 +46,10 @@
 	char				*szDisplayName;
 	struct loadparm_context		*lp_ctx;
 	void				*oc_ctx;
-	void				*conf_ctx;
-	void				*users_ctx;
+	struct ldb_context		*samdb_ctx;
 	struct mapistore_context	*mstore_ctx;
 	struct mapi_handles_context	*handles_ctx;
+	TALLOC_CTX			*mem_ctx;
 };
 
 
@@ -128,6 +128,7 @@
 __BEGIN_DECLS
 
 NTSTATUS	samba_init_module(void);
+struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, struct auth_session_info *);
 
 /* definitions from emsmdbp.c */
 struct emsmdbp_context	*emsmdbp_init(struct loadparm_context *, void *);

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -78,81 +78,58 @@
 _PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx,
 					      void *ldb_ctx)
 {
+	TALLOC_CTX		*mem_ctx;
 	struct emsmdbp_context	*emsmdbp_ctx;
 	struct tevent_context	*ev;
-	char			*configuration = NULL;
-	char			*users = NULL;
-	int			ret;
 
 	/* Sanity Checks */
 	if (!lp_ctx) return NULL;
 
-	emsmdbp_ctx = talloc_zero(lp_ctx, struct emsmdbp_context);
+	mem_ctx  = talloc_named(NULL, 0, "emsmdbp_init");
+
+	emsmdbp_ctx = talloc_zero(mem_ctx, struct emsmdbp_context);
 	if (!emsmdbp_ctx) {
+		talloc_free(mem_ctx);
 		return NULL;
 	}
 
-	ev = tevent_context_init(talloc_autofree_context());
+	emsmdbp_ctx->mem_ctx = mem_ctx;
+
+	ev = tevent_context_init(mem_ctx);
 	if (!ev) {
-		talloc_free(emsmdbp_ctx);
+		talloc_free(mem_ctx);
 		return NULL;
 	}
 
 	/* Save a pointer to the loadparm context */
 	emsmdbp_ctx->lp_ctx = lp_ctx;
 
-	/* Return an opaque context pointer on the configuration database */
-	configuration = private_path(emsmdbp_ctx, lp_ctx, "configuration.ldb");
-	emsmdbp_ctx->conf_ctx = ldb_init(emsmdbp_ctx, ev);
-	if (!emsmdbp_ctx->conf_ctx) {
-		talloc_free(configuration);
-		talloc_free(emsmdbp_ctx);
+	/* return an opaque context pointer on samDB database */
+	emsmdbp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx));
+	if (!emsmdbp_ctx->samdb_ctx) {
+		talloc_free(mem_ctx);
+		DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__));
 		return NULL;
 	}
 
-	ret = ldb_connect(emsmdbp_ctx->conf_ctx, configuration, LDB_FLG_RDONLY, NULL);
-	talloc_free(configuration);
-	if (ret != LDB_SUCCESS) {
-		DEBUG(0, ("[%s:%d]: Connection to \"configuration.ldb\" failed\n", __FUNCTION__, __LINE__));
-		talloc_free(emsmdbp_ctx);
-		return NULL;
-	}
-
-	/* Return an opaque pointer on the users database */
-	users = private_path(emsmdbp_ctx, lp_ctx, "users.ldb");
-	emsmdbp_ctx->users_ctx = ldb_init(emsmdbp_ctx, ev);
-	if (!emsmdbp_ctx->users_ctx) {
-		talloc_free(users);
-		talloc_free(emsmdbp_ctx);
-		return NULL;
-	}
-
-	ret = ldb_connect(emsmdbp_ctx->users_ctx, users, LDB_FLG_RDONLY, NULL);
-	talloc_free(users);
-	if (ret != LDB_SUCCESS) {
-		DEBUG(0, ("[%s:%d]: Connection to \"users.ldb\" failed\n", __FUNCTION__, __LINE__));
-		talloc_free(emsmdbp_ctx);
-		return NULL;
-	}
-
 	/* Reference global OpenChange dispatcher database pointer within current context */
 	emsmdbp_ctx->oc_ctx = ldb_ctx;
 
 	/* Initialize the mapistore context */		
-	emsmdbp_ctx->mstore_ctx = mapistore_init(emsmdbp_ctx, NULL);
+	emsmdbp_ctx->mstore_ctx = mapistore_init(mem_ctx, NULL);
 	if (!emsmdbp_ctx->mstore_ctx) {
 		DEBUG(0, ("[%s:%d]: MAPISTORE initialization failed\n", __FUNCTION__, __LINE__));
 
-		talloc_free(emsmdbp_ctx);
+		talloc_free(mem_ctx);
 		return NULL;
 	}
 	talloc_set_destructor((void *)emsmdbp_ctx->mstore_ctx, (int (*)(void *))emsmdbp_mapi_store_destructor);
 
 	/* Initialize MAPI handles context */
-	emsmdbp_ctx->handles_ctx = mapi_handles_init(emsmdbp_ctx);
+	emsmdbp_ctx->handles_ctx = mapi_handles_init(mem_ctx);
 	if (!emsmdbp_ctx->handles_ctx) {
 		DEBUG(0, ("[%s:%d]: MAPI handles context initialization failed\n", __FUNCTION__, __LINE__));
-		talloc_free(emsmdbp_ctx);
+		talloc_free(mem_ctx);
 		return NULL;
 	}
 	talloc_set_destructor((void *)emsmdbp_ctx->handles_ctx, (int (*)(void *))emsmdbp_mapi_handles_destructor);
@@ -213,8 +190,8 @@
 
 	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
 
-	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
-			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+	ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx),
 			 LDB_SCOPE_SUBTREE, recipient_attrs, "CN=%s", username);
 
 	/* If the search failed */
@@ -264,8 +241,8 @@
 	/* Sanity Checks */
 	if (!legacyExchangeDN) return false;
 
-	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
-			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+	ret = ldb_search(emsmdbp_ctx->samdb_ctx, emsmdbp_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx),
 			 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
 			 legacyExchangeDN);
 

Modified: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -147,8 +147,8 @@
 	object->object.mailbox->owner_EssDN = talloc_strdup(object->object.mailbox, request->u.mapi_Logon.EssDN);
 	object->object.mailbox->szUserDN = talloc_strdup(object->object.mailbox, emsmdbp_ctx->szUserDN);
 
-	ret = ldb_search(emsmdbp_ctx->users_ctx, mem_ctx, &res,
-			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+	ret = ldb_search(emsmdbp_ctx->samdb_ctx, mem_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->samdb_ctx),
 			 LDB_SCOPE_SUBTREE, recipient_attrs, "legacyExchangeDN=%s", 
 			 object->object.mailbox->owner_EssDN);
 

Modified: trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -70,7 +70,7 @@
 		r->out.result = MAPI_E_LOGON_FAILED;
 		return MAPI_E_LOGON_FAILED;		
 	}
-	
+
 	/* Step 1. Initialize the emsabp context */
 	emsabp_ctx = emsabp_init(dce_call->conn->dce_ctx->lp_ctx, emsabp_tdb_ctx);
 	if (!emsabp_ctx) {
@@ -105,7 +105,7 @@
 	}
 
 	/* Step 4. Retrieve OpenChange server GUID */
-	guid = emsabp_get_server_GUID(emsabp_ctx);
+	guid = (struct GUID *) samdb_ntds_objectGUID(emsabp_ctx->samdb_ctx);
 	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_FAILONEPROVIDER, emsabp_ctx);
 
 	/* Step 5. Fill NspiBind reply */
@@ -209,6 +209,7 @@
 	struct dcesrv_handle		*h;
 	struct emsabp_context		*emsabp_ctx;
 	struct SPropTagArray		*pPropTags;
+	struct SRowSet			*pRows;
 	uint32_t			i;
 
 	DEBUG(3, ("exchange_nsp: NspiQueryRows (0x3)\n"));
@@ -242,34 +243,60 @@
 		pPropTags = r->in.pPropTags;
 	}
 
-	if (r->in.lpETable == NULL) {
-		/* FIXME */
-		retval = MAPI_E_INVALID_BOOKMARK;
-	}
+	/* Allocate RowSet to be filled in */
+	pRows = talloc_zero(mem_ctx, struct SRowSet);
 
-	if (retval != MAPI_E_SUCCESS) {
-	failure:
-		r->out.pStat = r->in.pStat;
-		r->out.ppRows = talloc(mem_ctx, struct SRowSet *);
-		r->out.ppRows[0] = NULL;
-		r->out.result = retval;
-
-		return retval;
-	}
-
 	/* Step 2. Fill ppRows  */
-	r->out.ppRows = talloc(mem_ctx, struct SRowSet *);
-	r->out.ppRows[0] = talloc(mem_ctx, struct SRowSet);
-	r->out.ppRows[0]->cRows = r->in.Count;
-	r->out.ppRows[0]->aRow = talloc_array(mem_ctx, struct SRow, r->in.Count);
-	for (i = 0; i < r->in.Count; i++) {
-		retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), r->in.lpETable[i], pPropTags);
-		if (retval != MAPI_E_SUCCESS) {
+	if (r->in.lpETable == NULL) {
+		/* Step 2.1 Fill ppRows for supplied Container ID */
+		struct ldb_result	*ldb_res;
+		
+		retval = emsabp_ab_container_enum(mem_ctx, emsabp_ctx,
+						  r->in.pStat->ContainerID, &ldb_res);
+		if (!MAPI_STATUS_IS_OK(retval))  {
 			goto failure;
 		}
+		if (ldb_res->count) {
+			pRows->cRows = ldb_res->count;
+			pRows->aRow = talloc_array(mem_ctx, struct SRow, ldb_res->count);
+		}
+
+		/* fetch required attributes for every entry found */
+		for (i = 0; i < ldb_res->count; i++) {
+			retval = emsabp_fetch_attrs_from_msg(mem_ctx, emsabp_ctx, &(pRows->aRow[i]),
+							     ldb_res->msgs[i], 0, r->in.dwFlags, pPropTags);
+			if (!MAPI_STATUS_IS_OK(retval)) {
+				goto failure;
+			}
+		}
+	} else {
+		/* Step 2.2 Fill ppRows for supplied table of MIds */
+		pRows->cRows = r->in.dwETableCount;
+		pRows->aRow = talloc_array(mem_ctx, struct SRow, r->in.dwETableCount);
+		for (i = 0; i < r->in.dwETableCount; i++) {
+			retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(pRows->aRow[i]), r->in.lpETable[i], r->in.dwFlags, pPropTags);
+			if (retval != MAPI_E_SUCCESS) {
+				goto failure;
+			}
+		}
 	}
 
+	/* Step 3. Fill output params */
+	*r->out.ppRows = pRows;
+
+	memcpy(r->out.pStat, r->in.pStat, sizeof (struct STAT));
+	r->out.pStat->TotalRecs = pRows->cRows;
+	r->out.pStat->NumPos = r->out.pStat->Delta + pRows->cRows;
+	r->out.pStat->CurrentRec = MID_END_OF_TABLE;
+
 	return MAPI_E_SUCCESS;
+
+failure:
+	r->out.pStat = r->in.pStat;
+	*r->out.ppRows = NULL;
+	r->out.result = retval;
+
+	return retval;
 }
 
 
@@ -351,7 +378,7 @@
 
 	for (i = 0; i < ppOutMIds->cValues; i++) {
 		retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), 
-					    ppOutMIds->aulPropTag[i], r->in.pPropTags);
+					    ppOutMIds->aulPropTag[i], fEphID, r->in.pPropTags);
 		if (retval) goto failure;
 	}
 
@@ -402,6 +429,7 @@
 	uint32_t		i;
 	uint32_t		MId;
 	const char		*dn;
+	bool			pbUseConfPartition;
 
 	DEBUG(3, ("exchange_nsp: NspiDNToMId (0x7)\n"));
 
@@ -420,19 +448,20 @@
 	r->out.ppMIds = talloc_array(mem_ctx, struct SPropTagArray *, 2);
 	r->out.ppMIds[0] = talloc_zero(mem_ctx, struct SPropTagArray);
 	r->out.ppMIds[0]->cValues = r->in.pNames->Count;
-	r->out.ppMIds[0]->aulPropTag = talloc_array(mem_ctx, uint32_t, r->in.pNames->Count);
+	r->out.ppMIds[0]->aulPropTag = (enum MAPITAGS *) talloc_array(mem_ctx, uint32_t, r->in.pNames->Count);
 
 	for (i = 0; i < r->in.pNames->Count; i++) {
 		/* Step 1. Check if the input legacyDN exists */
-		retval = emsabp_search_legacyExchangeDN(emsabp_ctx, r->in.pNames->Strings[i], &msg);
+	  retval = emsabp_search_legacyExchangeDN(emsabp_ctx, r->in.pNames->Strings[i], &msg, &pbUseConfPartition);
 		if (retval != MAPI_E_SUCCESS) {
 			r->out.ppMIds[0]->aulPropTag[i] = 0;
 		} else {
+			TDB_CONTEXT *tdb_ctx = (pbUseConfPartition ? emsabp_ctx->tdb_ctx : emsabp_ctx->ttdb_ctx);
 			dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL);
-			retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &MId);
+			retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId);
 			if (retval) {
-				retval = emsabp_tdb_insert(emsabp_ctx->tdb_ctx, dn);
-				retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &MId);
+				retval = emsabp_tdb_insert(tdb_ctx, dn);
+				retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId);
 			}
 			r->out.ppMIds[0]->aulPropTag[i] = MId;
 		}
@@ -479,7 +508,7 @@
 	struct dcesrv_handle	*h;
 	struct emsabp_context	*emsabp_ctx;
 	uint32_t		MId;
-	char			*dn;
+	int			i;
 
 	DEBUG(3, ("exchange_nsp: NspiGetProps (0x9)\n"));
 
@@ -498,35 +527,55 @@
 	/* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */
 	if (r->in.pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) {
 		retval = MAPI_E_INVALID_BOOKMARK;
-		goto failure;
+		r->out.result = retval;
+		return retval;
 	}
 
-	retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, MId, &dn);
-	if (retval != MAPI_E_SUCCESS) {
-	failure:
-		r->out.ppRows = talloc_array(mem_ctx, struct SRow *, 2);
-		r->out.ppRows[0] = NULL;
-		r->out.result = MAPI_E_INVALID_BOOKMARK;
-		return r->out.result;
-	}
-
 	/* Step 2. Fetch properties */
 	r->out.ppRows = talloc_array(mem_ctx, struct SRow *, 2);
 	r->out.ppRows[0] = talloc_zero(r->out.ppRows, struct SRow);
 	r->out.ppRows[0]->ulAdrEntryPad = 0;
-	r->out.ppRows[0]->cValues = r->in.pPropTags->cValues;
-	r->out.ppRows[0]->lpProps = talloc_array(r->out.ppRows[0], struct SPropValue, r->in.pPropTags->cValues);
 
-	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.pPropTags);
+	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.dwFlags, r->in.pPropTags);
 	if (retval != MAPI_E_SUCCESS) {
-		talloc_free(r->out.ppRows);
-		r->out.result = MAPI_W_ERRORS_RETURNED;
-		goto failure;
+		/* Is MId is not found, proceed as if no attributes were found */
+		if (retval == MAPI_E_INVALID_BOOKMARK) {
+			uint32_t	ulPropTag;
+			struct SRow	*aRow;
+			
+			aRow = r->out.ppRows[0];
+			aRow->ulAdrEntryPad = 0x0;
+			aRow->cValues = r->in.pPropTags->cValues;
+			aRow->lpProps = talloc_array(mem_ctx, struct SPropValue, aRow->cValues);
+			for (i = 0; i < aRow->cValues; i++) {
+				ulPropTag = r->in.pPropTags->aulPropTag[i];
+				ulPropTag = (ulPropTag & 0xFFFF0000) | PT_ERROR;
+
+				aRow->lpProps[i].ulPropTag = ulPropTag;
+				aRow->lpProps[i].dwAlignPad = 0x0;
+				set_SPropValue(&(aRow->lpProps[i]), NULL);
+			}
+			retval = MAPI_W_ERRORS_RETURNED;
+		} else {
+			talloc_free(r->out.ppRows);
+			r->out.ppRows = NULL;
+		}
+		r->out.result = retval;
+		return r->out.result;
 	}
 
-	r->out.result = MAPI_E_SUCCESS;
+	/* Step 3. Properties are fetched. Provide proper return
+	 value.  ErrorsReturned should be returned when at least one
+	 property is not found */
+	for (i = 0; i < r->out.ppRows[0]->cValues; i++) {
+		if ((r->out.ppRows[0]->lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) {
+			retval = MAPI_W_ERRORS_RETURNED;
+			break;
+		}
+	}
 
-	return MAPI_E_SUCCESS;
+	r->out.result = retval;
+	return retval;
 }
 
 
@@ -778,8 +827,102 @@
 						TALLOC_CTX *mem_ctx,
 						struct NspiResolveNamesW *r)
 {
-	DEBUG(3, ("exchange_nsp: NspiResolveNamesW (0x14) not implemented\n"));
-	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+	enum MAPISTATUS		retval = MAPI_E_SUCCESS;
+	struct dcesrv_handle	*h;
+	struct emsabp_context	*emsabp_ctx;
+	struct ldb_message	*ldb_msg_ab;
+	struct SPropTagArray	*pPropTags;
+	const char		*purportedSearch;
+	struct SPropTagArray	*pMIds = NULL;
+	struct SRowSet		*pRows = NULL;
+	struct WStringsArray_r	*paWStr;
+	uint32_t		i;
+	int			ret;
+	const char * const	recipient_attrs[] = { "*", NULL };
+	const char * const	search_attr[] = { "mailNickName", "mail", "name", 
+						  "displayName", "givenName", "sAMAccountName" };
+
+	DEBUG(3, ("exchange_nsp: NspiResolveNamesW (0x14)\n"));
+
+	/* Step 0. Ensure incoming user is authenticated */
+	if (!NTLM_AUTH_IS_OK(dce_call)) {
+		DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
+		return MAPI_E_LOGON_FAILED;
+	}
+
+	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	OPENCHANGE_RETVAL_IF(!h, MAPI_E_LOGON_FAILED, NULL);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+
+	/* Step 1. Prepare in/out data */
+	retval = emsabp_ab_container_by_id(mem_ctx, emsabp_ctx, r->in.pStat->ContainerID, &ldb_msg_ab);
+	OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(retval), MAPI_E_INVALID_BOOKMARK, NULL);
+
+	purportedSearch = ldb_msg_find_attr_as_string(ldb_msg_ab, "purportedSearch", NULL);
+	OPENCHANGE_RETVAL_IF(!purportedSearch, MAPI_E_INVALID_BOOKMARK, NULL);
+
+	/* Set default list of property tags if none were provided in input */
+	if (!r->in.pPropTags) {
+		pPropTags = set_SPropTagArray(mem_ctx, 0x7,
+					      PR_EMS_AB_CONTAINERID,
+					      PR_OBJECT_TYPE,
+					      PR_DISPLAY_TYPE,
+					      PR_DISPLAY_NAME,
+					      PR_OFFICE_TELEPHONE_NUMBER,
+					      PR_COMPANY_NAME,
+					      PR_OFFICE_LOCATION);
+	} else {
+		pPropTags = r->in.pPropTags;
+	}
+
+	/* Allocate output MIds */
+	paWStr = r->in.paWStr;
+	pMIds = talloc(mem_ctx, struct SPropTagArray);
+	pMIds->cValues = paWStr->Count;
+	pMIds->aulPropTag = (enum MAPITAGS *) talloc_array(mem_ctx, uint32_t, pMIds->cValues);
+	pRows = talloc(mem_ctx, struct SRowSet);
+	pRows->cRows = 0;
+	pRows->aRow = talloc_array(mem_ctx, struct SRow, pMIds->cValues);
+
+	/* Step 2. Fetch AB container records */
+	for (i = 0; i < paWStr->Count; i++) {
+		struct ldb_result	*ldb_res;
+		char			*filter = talloc_strdup(mem_ctx, "");
+		int			j;
+
+		/* Build search filter */
+		for (j = 0; j < ARRAY_SIZE(search_attr); j++) {
+			char	*attr_filter = talloc_asprintf(mem_ctx, "(%s=%s)", search_attr[j], paWStr->Strings[i]);
+			filter = talloc_strdup_append(filter, attr_filter);
+			talloc_free(attr_filter);
+		}
+
+		/* Search AD */
+		filter = talloc_asprintf(mem_ctx, "(&%s(|%s))", purportedSearch, filter);
+		ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &ldb_res,
+				 ldb_get_default_basedn(emsabp_ctx->samdb_ctx),
+				 LDB_SCOPE_SUBTREE, recipient_attrs, "%s", filter);
+
+		/* Determine name resolutation status and fetch object upon success */
+		if (ret != LDB_SUCCESS || ldb_res->count == 0) {
+			pMIds->aulPropTag[i] = MAPI_UNRESOLVED;
+		} else if (ldb_res->count > 1) {
+			pMIds->aulPropTag[i] = MAPI_AMBIGUOUS;
+		} else {
+			pMIds->aulPropTag[i] = MAPI_RESOLVED;
+			emsabp_fetch_attrs_from_msg(mem_ctx, emsabp_ctx, &pRows->aRow[pRows->cRows],
+						    ldb_res->msgs[0], 0, 0, pPropTags);
+			pRows->cRows++;
+		}
+	}
+
+	*r->out.ppMIds = pMIds;
+	if (pRows->cRows) {
+		*r->out.ppRows = pRows;
+	}
+
+	r->out.result = retval;
+	return retval;
 }
 
 

Modified: trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -41,9 +41,9 @@
 #endif
 
 struct emsabp_context {
+	const char		*account_name;
 	struct loadparm_context	*lp_ctx;
-	void			*conf_ctx;
-	void			*users_ctx;
+	struct ldb_context	*samdb_ctx;
 	void			*ldb_ctx;
 	TDB_CONTEXT		*tdb_ctx;
 	TDB_CONTEXT		*ttdb_ctx;
@@ -109,28 +109,34 @@
 __BEGIN_DECLS
 
 NTSTATUS	samba_init_module(void);
+struct ldb_context *samdb_connect(TALLOC_CTX *, struct tevent_context *, struct loadparm_context *, struct auth_session_info *);
+const struct GUID *samdb_ntds_objectGUID(struct ldb_context *);
 
 /* definitions from emsabp.c */
 struct emsabp_context	*emsabp_init(struct loadparm_context *, TDB_CONTEXT *);
 bool			emsabp_destructor(void *);
+enum MAPISTATUS		emsabp_get_account_info(TALLOC_CTX *, struct emsabp_context *, const char *, struct ldb_message **);
 bool			emsabp_verify_user(struct dcesrv_call_state *, struct emsabp_context *);
 bool			emsabp_verify_codepage(struct emsabp_context *, uint32_t);
 bool			emsabp_verify_lcid(struct emsabp_context *, uint32_t);
-struct GUID		*emsabp_get_server_GUID(struct emsabp_context *);
 enum MAPISTATUS		emsabp_set_EphemeralEntryID(struct emsabp_context *, uint32_t, uint32_t, struct EphemeralEntryID *);
 enum MAPISTATUS		emsabp_set_PermanentEntryID(struct emsabp_context *, uint32_t, struct ldb_message *, struct PermanentEntryID *);
 enum MAPISTATUS		emsabp_EphemeralEntryID_to_Binary_r(TALLOC_CTX *, struct EphemeralEntryID *, struct Binary_r *);
 enum MAPISTATUS		emsabp_PermanentEntryID_to_Binary_r(TALLOC_CTX *, struct PermanentEntryID *, struct Binary_r *);
 enum MAPISTATUS		emsabp_get_HierarchyTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct SRowSet **);
 enum MAPISTATUS		emsabp_get_CreationTemplatesTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct SRowSet **);
-void			*emsabp_query(TALLOC_CTX *, struct emsabp_context *, struct ldb_message *, uint32_t, uint32_t);
-enum MAPISTATUS		emsabp_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t, struct SPropTagArray *);
+void			*emsabp_query(TALLOC_CTX *, struct emsabp_context *, struct ldb_message *, uint32_t, uint32_t, uint32_t);
+enum MAPISTATUS		emsabp_fetch_attrs_from_msg(TALLOC_CTX *, struct emsabp_context *, struct SRow *, struct ldb_message *, uint32_t, uint32_t, struct SPropTagArray *);
+enum MAPISTATUS		emsabp_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t, uint32_t, struct SPropTagArray *);
 enum MAPISTATUS		emsabp_table_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t, struct PermanentEntryID *, 
 						 struct PermanentEntryID *, struct ldb_message *, bool);
 enum MAPISTATUS		emsabp_search(TALLOC_CTX *, struct emsabp_context *, struct SPropTagArray *, struct Restriction_r *, struct STAT *, uint32_t);
 enum MAPISTATUS		emsabp_search_dn(struct emsabp_context *, const char *, struct ldb_message **);
-enum MAPISTATUS		emsabp_search_legacyExchangeDN(struct emsabp_context *, const char *, struct ldb_message **);
+enum MAPISTATUS		emsabp_search_legacyExchangeDN(struct emsabp_context *, const char *, struct ldb_message **, bool *);
+enum MAPISTATUS		emsabp_ab_container_by_id(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct ldb_message **);
+enum MAPISTATUS		emsabp_ab_container_enum(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct ldb_result **);
 
+
 /* definitions from emsabp_tdb.c */
 TDB_CONTEXT		*emsabp_tdb_init(TALLOC_CTX *, struct loadparm_context *);
 enum MAPISTATUS		emsabp_tdb_close(TDB_CONTEXT *);

Modified: trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -44,9 +44,6 @@
 	TALLOC_CTX		*mem_ctx;
 	struct emsabp_context	*emsabp_ctx;
 	struct tevent_context	*ev;
-	char			*configuration = NULL;
-	char			*users = NULL;
-	int			ret;
 
 	/* Sanity checks */
 	if (!lp_ctx) return NULL;
@@ -70,40 +67,14 @@
 	/* Save a pointer to the loadparm context */
 	emsabp_ctx->lp_ctx = lp_ctx;
 
-	/* Return an opaque context pointer on the configuration database */
-	configuration = private_path(mem_ctx, lp_ctx, "configuration.ldb");
-	emsabp_ctx->conf_ctx = ldb_init(mem_ctx, ev);
-	if (!emsabp_ctx->conf_ctx) {
-		talloc_free(configuration);
+	/* Return an opaque context pointer on samDB database */
+	emsabp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx));
+	if (!emsabp_ctx->samdb_ctx) {
 		talloc_free(mem_ctx);
+		DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__));
 		return NULL;
 	}
 
-	ret = ldb_connect(emsabp_ctx->conf_ctx, configuration, LDB_FLG_RDONLY, NULL);
-	talloc_free(configuration);
-	if (ret != LDB_SUCCESS) {
-		DEBUG(0, ("[%s:%d]: Connection to \"configuration.ldb\" failed\n", __FUNCTION__, __LINE__));
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
-	/* Return an opaque context pointer to the users database */
-	users = private_path(mem_ctx, lp_ctx, "users.ldb");
-	emsabp_ctx->users_ctx = ldb_init(mem_ctx, ev);
-	if (!emsabp_ctx->users_ctx) {
-		talloc_free(users);
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
-	ret = ldb_connect(emsabp_ctx->users_ctx, users, LDB_FLG_RDONLY, NULL);
-	talloc_free(users);
-	if (ret != LDB_SUCCESS) {
-		DEBUG(0, ("[%s:%d]: Connection to \"users.ldb\" failed\n", __FUNCTION__, __LINE__));
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
 	/* Reference the global TDB context to the current emsabp context */
 	emsabp_ctx->tdb_ctx = tdb_ctx;
 
@@ -134,7 +105,55 @@
 	return false;
 }
 
+/**
+   \details Get AD record for Mail-enabled account
 
+   \param dce_call pointer to the session context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param username User common name
+   \param ldb_msg Pointer on pointer to ldb_message to return result to
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_NOT_ENOUGH_RESOURCES, MAPI_E_NOT_FOUND or
+   MAPI_E_CORRUPT_STORE
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_get_account_info(TALLOC_CTX *mem_ctx,
+						 struct emsabp_context *emsabp_ctx,
+						 const char *username,
+						 struct ldb_message **ldb_msg)
+{
+	int			ret;
+	int			msExchUserAccountControl;
+	struct ldb_result	*res = NULL;
+	const char * const	recipient_attrs[] = { "*", NULL };
+
+	ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &res,
+			 ldb_get_default_basedn(emsabp_ctx->samdb_ctx),
+			 LDB_SCOPE_SUBTREE, recipient_attrs, "CN=%s",
+			 username);
+	OPENCHANGE_RETVAL_IF((ret != LDB_SUCCESS || !res->count), MAPI_E_NOT_FOUND, NULL);
+
+	/* Check if more than one record was found */
+	OPENCHANGE_RETVAL_IF(res->count != 1, MAPI_E_CORRUPT_STORE, NULL);
+
+	msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", -1);
+	switch (msExchUserAccountControl) {
+	case -1: /* msExchUserAccountControl attribute is not found */
+		return MAPI_E_NOT_FOUND;
+	case 0:
+		*ldb_msg = res->msgs[0];
+		return MAPI_E_SUCCESS;
+	case 2: /* Account is disabled */
+		*ldb_msg = res->msgs[0];
+		return MAPI_E_ACCOUNT_DISABLED;
+	default: /* Unknown value for msExchUserAccountControl attribute */
+		return MAPI_E_CORRUPT_STORE;
+	}
+	
+	/* We should never get here anyway */
+	return MAPI_E_CORRUPT_STORE;
+}
+
 /**
    \details Check if the authenticated user belongs to the Exchange
    organization
@@ -148,35 +167,23 @@
 				 struct emsabp_context *emsabp_ctx)
 {
 	int			ret;
+	TALLOC_CTX		*mem_ctx;
 	const char		*username = NULL;
-	int			msExchUserAccountControl;
-	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
-	struct ldb_result	*res = NULL;
-	const char * const	recipient_attrs[] = { "msExchUserAccountControl", NULL };
+	struct ldb_message	*ldb_msg = NULL;
 
 	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
 
-	ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res, 
-			 ldb_get_default_basedn(emsabp_ctx->users_ctx),
-			 scope, recipient_attrs, "CN=%s", username);
+	mem_ctx = talloc_named(emsabp_ctx->mem_ctx, 0, __FUNCTION__);
 
-	/* If the search failed */
-	if (ret != LDB_SUCCESS || !res->count) {
-		return false;
+	ret = emsabp_get_account_info(mem_ctx, emsabp_ctx, username, &ldb_msg);
+	
+	/* cache account_name upon success */
+	if (MAPI_STATUS_IS_OK(ret)) {
+		emsabp_ctx->account_name = talloc_strdup(emsabp_ctx->mem_ctx, username);
 	}
 
-	/* If msExchUserAccountControl attribute is not found */
-	if (!res->msgs[0]->num_elements) {
-		return false;
-	}
-
-	/* If the attribute exists check its value */
-	msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2);
-	if (msExchUserAccountControl == 2) {
-		return false;
-	}
-
-	return true;
+	talloc_free(mem_ctx);
+	return MAPI_STATUS_IS_OK(ret);
 }
 
 
@@ -195,78 +202,11 @@
 _PUBLIC_ bool emsabp_verify_codepage(struct emsabp_context *emsabp_ctx,
 				     uint32_t CodePage)
 {
-	return valid_codepage(CodePage);
+	return mapi_verify_cpid(CodePage);
 }
 
 
 /**
-   \details Retrieve the NSPI server GUID from the server object in
-   the configuration LDB database
-
-   \param emsabp_ctx pointer to the EMSABP context
-
-   \return An allocated GUID structure on success, otherwise NULL
- */
-_PUBLIC_ struct GUID *emsabp_get_server_GUID(struct emsabp_context *emsabp_ctx)
-{
-	int			ret;
-	struct loadparm_context	*lp_ctx;
-	struct GUID		*guid = (struct GUID *) NULL;
-	const char		*netbiosname = NULL;
-	const char		*guid_str = NULL;
-	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
-	struct ldb_result	*res = NULL;
-	char			*dn = NULL;
-	struct ldb_dn		*ldb_dn = NULL;
-	const char * const	recipient_attrs[] = { "*", NULL };
-	const char		*firstorgdn = NULL;
-
-	lp_ctx = emsabp_ctx->lp_ctx;
-
-	netbiosname = lp_netbios_name(lp_ctx);
-	if (!netbiosname) return NULL;
-
-	/* Step 1. Find the Exchange Organization */
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
-			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
-			 scope, recipient_attrs, "(objectClass=msExchOrganizationContainer)");
-
-	if (ret != LDB_SUCCESS || !res->count) {
-		return NULL;
-	}
-
-	firstorgdn = ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL);
-	if (!firstorgdn) {
-		return NULL;
-	}
-
-	/* Step 2. Find the OpenChange Server object */
-	dn = talloc_asprintf(emsabp_ctx->mem_ctx, "CN=Servers,CN=First Administrative Group,CN=Administrative Groups,%s",
-			     firstorgdn);
-	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, dn);
-	talloc_free(dn);
-	if (!ldb_dn_validate(ldb_dn)) {
-		return NULL;
-	}
-
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, 
-			 scope, recipient_attrs, "(cn=%s)", netbiosname);
-	if (ret != LDB_SUCCESS || !res->count) {
-		return NULL;
-	}
-
-	/* Step 3. Retrieve the objectGUID GUID */
-	guid_str = ldb_msg_find_attr_as_string(res->msgs[0], "objectGUID", NULL);
-	if (!guid_str) return NULL;
-
-	guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID);
-	GUID_from_string(guid_str, guid);
-	
-	return guid;
-}
-
-
-/**
    \details Build an EphemeralEntryID structure
 
    \param emsabp_ctx pointer to the EMSABP context
@@ -287,7 +227,7 @@
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
 
-	guid = emsabp_get_server_GUID(emsabp_ctx);
+	guid = (struct GUID *) samdb_ntds_objectGUID(emsabp_ctx->samdb_ctx);
 	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, NULL);
 
 	ephEntryID->ID_type = 0x87;
@@ -367,6 +307,10 @@
    \param permEntryID pointer to the PermanentEntryID returned by the
    function
 
+   \note This function only covers DT_CONTAINER AddressBook
+   objects. It should be extended in the future to support more
+   containers.
+
    \return MAPI_E_SUCCESS on success, otherwise
    MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE
  */
@@ -374,8 +318,9 @@
 						     uint32_t DisplayType, struct ldb_message *msg, 
 						     struct PermanentEntryID *permEntryID)
 {
-	struct GUID	*guid = (struct GUID *) NULL;
-	const char	*guid_str;
+	struct GUID		*guid = (struct GUID *) NULL;
+	const struct ldb_val	*ldb_value = NULL;
+	const char		*dn_str;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
@@ -391,11 +336,12 @@
 
 	if (!msg) {
 		permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, "/");
-	} else {
-		guid_str = ldb_msg_find_attr_as_string(msg, "objectGUID", NULL);
-		OPENCHANGE_RETVAL_IF(!guid_str, MAPI_E_CORRUPT_STORE, NULL);
+	} else if (DisplayType == DT_CONTAINER) {
+		ldb_value = ldb_msg_find_ldb_val(msg, "objectGUID");
+		OPENCHANGE_RETVAL_IF(!ldb_value, MAPI_E_CORRUPT_STORE, NULL);
+
 		guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID);
-		GUID_from_string(guid_str, guid);
+		GUID_from_data_blob(ldb_value, guid);
 		permEntryID->dn = talloc_asprintf(emsabp_ctx->mem_ctx, EMSABP_DN, 
 						  guid->time_low, guid->time_mid,
 						  guid->time_hi_and_version,
@@ -405,6 +351,11 @@
 						  guid->node[2], guid->node[3],
 						  guid->node[4], guid->node[5]);
 		talloc_free(guid);
+
+	}  else {
+		dn_str = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL);
+		OPENCHANGE_RETVAL_IF(!dn_str, MAPI_E_CORRUPT_STORE, NULL);
+		permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, dn_str);
 	}
 
 	return MAPI_E_SUCCESS;
@@ -463,7 +414,11 @@
    \param msg pointer to the LDB message
    \param ulPropTag the property tag to lookup
    \param MId Minimal Entry ID associated to the current message
+   \param dwFlags bit flags specifying whether or not the server must
+   return the values of the property PidTagEntryId in the Ephemeral
+   or Permanent Entry ID format
 
+
    \note This implementation is at the moment limited to MAILUSER,
    which means we arbitrary set PR_OBJECT_TYPE and PR_DISPLAY_TYPE
    while we should have a generic method to fill these properties.
@@ -471,16 +426,19 @@
    \return Valid generic pointer on success, otherwise NULL
  */
 _PUBLIC_ void *emsabp_query(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
-			    struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId)
+			    struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId,
+			    uint32_t dwFlags)
 {
 	enum MAPISTATUS			retval;
 	void				*data = (void *) NULL;
 	const char			*attribute;
 	const char			*ref_attribute;
 	const char			*ldb_string = NULL;
+	char				*tmp_str;
 	struct Binary_r			*bin;
 	struct StringArray_r		*mvszA;
 	struct EphemeralEntryID		ephEntryID;
+	struct PermanentEntryID         permEntryID;
 	struct ldb_message		*msg2 = NULL;
 	struct ldb_message_element	*ldb_element;
 	int				ret;
@@ -490,6 +448,7 @@
 	/* Step 1. Fill attributes not in AD but created using EMSABP databases */
 	switch (ulPropTag) {
 	case PR_ADDRTYPE:
+	case PR_ADDRTYPE_UNICODE:
 		data = (void *) talloc_strdup(mem_ctx, EMSABP_ADDRTYPE);
 		return data;
 	case PR_OBJECT_TYPE:
@@ -502,9 +461,26 @@
 		return data;
 	case PR_ENTRYID:
 		bin = talloc(mem_ctx, struct Binary_r);
-		retval = emsabp_set_EphemeralEntryID(emsabp_ctx, DT_MAILUSER, MId, &ephEntryID);
-		retval = emsabp_EphemeralEntryID_to_Binary_r(mem_ctx, &ephEntryID, bin);
+		if (dwFlags & fEphID) {
+			retval = emsabp_set_EphemeralEntryID(emsabp_ctx, DT_MAILUSER, MId, &ephEntryID);
+			retval = emsabp_EphemeralEntryID_to_Binary_r(mem_ctx, &ephEntryID, bin);
+		} else {
+			retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_MAILUSER, msg, &permEntryID);
+			retval = emsabp_PermanentEntryID_to_Binary_r(mem_ctx, &permEntryID, bin);
+		}
 		return bin;
+	case PR_SEARCH_KEY:
+		/* retrieve email address attribute, i.e. legacyExchangeDN */
+		ldb_string = ldb_msg_find_attr_as_string(msg, emsabp_property_get_attribute(PR_EMAIL_ADDRESS), NULL);
+		if (!ldb_string) return NULL;
+		tmp_str = talloc_strdup_upper(mem_ctx, ldb_string);
+		if (!tmp_str) return NULL;
+		/* make binary for PR_SEARCH_KEY */
+		bin = talloc(mem_ctx, struct Binary_r);
+		bin->lpb = (uint8_t *)talloc_asprintf(mem_ctx, "EX:%s", tmp_str);
+		bin->cb = strlen((const char *)bin->lpb) + 1;
+		talloc_free(tmp_str);
+		return bin;
 	case PR_INSTANCE_KEY:
 		bin = talloc_zero(mem_ctx, struct Binary_r);
 		bin->cb = 4;
@@ -547,6 +523,7 @@
 		data = talloc_strdup(mem_ctx, ldb_string);
 		break;
 	case PT_MV_STRING8:
+	case PT_MV_UNICODE:
 		ldb_element = ldb_msg_find_element(msg2, attribute);
 		if (!ldb_element) return NULL;
 
@@ -569,6 +546,66 @@
 
 
 /**
+   \details Build the SRow array entry for the specified ldb_message.
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param aRow pointer to the SRow structure where results will be stored
+   \param ldb_msg ldb_message record to fetch results from
+   \param MId MId of the entry to fetch (may be 0)
+   \param dwFlags input call flags (default to 0)
+   \param pPropTags pointer to the property tags array
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs_from_msg(TALLOC_CTX *mem_ctx,
+						     struct emsabp_context *emsabp_ctx,
+						     struct SRow *aRow,
+						     struct ldb_message *ldb_msg,
+						     uint32_t MId, uint32_t dwFlags,
+						     struct SPropTagArray *pPropTags)
+{
+	enum MAPISTATUS	retval;
+	const char	*dn;
+	void		*data;
+	uint32_t	ulPropTag;
+	int		i;
+
+	/* Step 0. Create MId if necessary */
+	if (MId == 0) {
+		dn = ldb_msg_find_attr_as_string(ldb_msg, "distinguishedName", NULL);
+		OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_DATA, NULL);
+		retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &MId);
+		if (retval) {
+			retval = emsabp_tdb_insert(emsabp_ctx->ttdb_ctx, dn);
+			OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+
+			retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &MId);
+			OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+		}
+	}
+
+	/* Step 1. Retrieve property values and build aRow */
+	aRow->ulAdrEntryPad = 0x0;
+	aRow->cValues = pPropTags->cValues;
+	aRow->lpProps = talloc_array(mem_ctx, struct SPropValue, aRow->cValues);
+
+	for (i = 0; i < aRow->cValues; i++) {
+		ulPropTag = pPropTags->aulPropTag[i];
+		data = emsabp_query(mem_ctx, emsabp_ctx, ldb_msg, ulPropTag, MId, dwFlags);
+		if (!data) {
+			ulPropTag = (ulPropTag & 0xFFFF0000) | PT_ERROR;
+		}
+		
+		aRow->lpProps[i].ulPropTag = ulPropTag;
+		aRow->lpProps[i].dwAlignPad = 0x0;
+		set_SPropValue(&(aRow->lpProps[i]), data);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
    \details Builds the SRow array entry for the specified MId.
 
    The function retrieves the DN associated to the specified MId
@@ -581,6 +618,9 @@
    \param aRow pointer to the SRow structure where results will be
    stored
    \param MId MId to fetch properties for
+   \param dwFlags bit flags specifying whether or not the server must
+   return the values of the property PidTagEntryId in the Ephemeral
+   or Permanent Entry ID format
    \param pPropTags pointer to the property tags array
 
    \note We currently assume records are users.ldb
@@ -588,11 +628,10 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
-					    struct SRow *aRow, uint32_t MId, 
+					    struct SRow *aRow, uint32_t MId, uint32_t dwFlags,
 					    struct SPropTagArray *pPropTags)
 {
 	enum MAPISTATUS		retval;
-	void			*ldb_ctx;
 	char			*dn;
 	const char * const	recipient_attrs[] = { "*", NULL };
 	struct ldb_result	*res = NULL;
@@ -603,20 +642,18 @@
 	int			i;
 
 	/* Step 0. Try to Retrieve the dn associated to the MId first from temp TDB (users) */
-	ldb_ctx = emsabp_ctx->users_ctx;
 	retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->ttdb_ctx, MId, &dn);
-	if (retval) {
+	if (!MAPI_STATUS_IS_OK(retval)) {
 		/* If it fails try to retrieve it from the on-disk TDB database (conf) */
 		retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, MId, &dn);
-		ldb_ctx = emsabp_ctx->conf_ctx;
 	}
-	OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+	OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL);
 
 	/* Step 1. Fetch the LDB record */
-	ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
+	ldb_dn = ldb_dn_new(mem_ctx, emsabp_ctx->samdb_ctx, dn);
 	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, NULL);
 
-	ret = ldb_search(ldb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE,
+	ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE,
 			 recipient_attrs, NULL);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL);
 
@@ -627,7 +664,7 @@
 
 	for (i = 0; i < aRow->cValues; i++) {
 		ulPropTag = pPropTags->aulPropTag[i];
-		data = emsabp_query(mem_ctx, emsabp_ctx, res->msgs[0], ulPropTag, MId);
+		data = emsabp_query(mem_ctx, emsabp_ctx, res->msgs[0], ulPropTag, MId, dwFlags);
 		if (!data) {
 			ulPropTag &= 0xFFFF0000;
 			ulPropTag += PT_ERROR;
@@ -856,20 +893,20 @@
 	aRow_idx++;
 
 	/* Step 2. Retrieve the object pointed by addressBookRoots attribute: 'All Address Lists' */
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
-			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
+	ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res,
+			 ldb_get_config_basedn(emsabp_ctx->samdb_ctx),
 			 scope, recipient_attrs, "(addressBookRoots=*)");
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_CORRUPT_STORE, aRow);
 
 	addressBookRoots = ldb_msg_find_attr_as_string(res->msgs[0], "addressBookRoots", NULL);
 	OPENCHANGE_RETVAL_IF(!addressBookRoots, MAPI_E_CORRUPT_STORE, aRow);
 
-	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, addressBookRoots);
+	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->samdb_ctx, addressBookRoots);
 	talloc_free(res);
 	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, aRow);
 
 	scope = LDB_SCOPE_BASE;
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, 
+	ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, 
 			 scope, recipient_attrs, NULL);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, aRow);
 
@@ -883,8 +920,8 @@
 	res = talloc_zero(mem_ctx, struct ldb_result);
 	OPENCHANGE_RETVAL_IF(!res, MAPI_E_NOT_ENOUGH_RESOURCES, aRow);
 
-	controls = ldb_parse_control_strings(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, control_strings);
-	ret = ldb_build_search_req(&req, emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx,
+	controls = ldb_parse_control_strings(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, control_strings);
+	ret = ldb_build_search_req(&req, emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx,
 				   ldb_dn, LDB_SCOPE_SUBTREE, "(purportedSearch=*)",
 				   recipient_attrs, controls, res, ldb_search_default_callback, NULL);
 
@@ -893,7 +930,7 @@
 		OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, aRow);
 	}
 
-	ret = ldb_request(emsabp_ctx->conf_ctx, req);
+	ret = ldb_request(emsabp_ctx->samdb_ctx, req);
 	if (ret == LDB_SUCCESS) {
 		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
 	}
@@ -1005,8 +1042,8 @@
 			res_prop->lpProp->value.lpszA :
 			res_prop->lpProp->value.lpszW;
 
-		ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res,
-				 ldb_get_default_basedn(emsabp_ctx->users_ctx),
+		ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res,
+				 ldb_get_default_basedn(emsabp_ctx->samdb_ctx),
 				 LDB_SCOPE_SUBTREE, recipient_attrs,
 				 "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))",
 				 recipient);
@@ -1016,23 +1053,24 @@
 		}
 	} else {
 		/* FIXME Check restriction == NULL */
+		return MAPI_E_INVALID_OBJECT;
 	}
 
 	if (limit && res->count > limit) {
 		return MAPI_E_TABLE_TOO_BIG;
 	}
 
-	MIds->aulPropTag = talloc_array(emsabp_ctx->mem_ctx, uint32_t, res->count);
+	MIds->aulPropTag = (enum MAPITAGS *) talloc_array(emsabp_ctx->mem_ctx, uint32_t, res->count);
 	MIds->cValues = res->count;
 
 	/* Step 2. Create session MId for all fetched records */
 	for (i = 0; i < res->count; i++) {
 		dn = ldb_msg_find_attr_as_string(res->msgs[i], "distinguishedName", NULL);
-		retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &MIds->aulPropTag[i]);
+		retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, (uint32_t *)&(MIds->aulPropTag[i]));
 		if (retval) {
 			retval = emsabp_tdb_insert(emsabp_ctx->ttdb_ctx, dn);
 			OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
-			retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, &(MIds->aulPropTag[i]));
+			retval = emsabp_tdb_fetch_MId(emsabp_ctx->ttdb_ctx, dn, (uint32_t *) &(MIds->aulPropTag[i]));
 			OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
 		}
 	}
@@ -1064,10 +1102,10 @@
 	OPENCHANGE_RETVAL_IF(!dn, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL);
 
-	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, dn);
+	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->samdb_ctx, dn);
 	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, NULL);
 
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn,
+	ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn,
 			 LDB_SCOPE_BASE, recipient_attrs, NULL);
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL);
 
@@ -1085,11 +1123,14 @@
    \param legacyDN pointer to the legacyDN attribute value to lookup
    \param ldb_res pointer on pointer to the LDB message returned by 
    the function
+   \param pbUseConfPartition pointer on boolean specifying whether the
+   legacyExchangeDN was retrieved from the Configuration parition or
+   not
 
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN(struct emsabp_context *emsabp_ctx, const char *legacyDN,
-							struct ldb_message **ldb_res)
+							struct ldb_message **ldb_res, bool *pbUseConfPartition)
 {
 	const char * const	recipient_attrs[] = { "*", NULL };
 	int			ret;
@@ -1098,15 +1139,112 @@
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!pbUseConfPartition, MAPI_E_INVALID_PARAMETER, NULL);
 
-	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
-			 ldb_get_default_basedn(emsabp_ctx->conf_ctx), 
+	*pbUseConfPartition = true;
+	ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res,
+			 ldb_get_config_basedn(emsabp_ctx->samdb_ctx), 
 			 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
 			 legacyDN);
 
+	if (ret != LDB_SUCCESS || res->count == 0) {
+		*pbUseConfPartition = false;
+		ret = ldb_search(emsabp_ctx->samdb_ctx, emsabp_ctx->mem_ctx, &res,
+				 ldb_get_default_basedn(emsabp_ctx->samdb_ctx),
+				 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
+				 legacyDN);
+	}
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, NULL);
 
 	*ldb_res = res->msgs[0];
 
 	return MAPI_E_SUCCESS;
 }
+
+
+/**
+   \details Fetch Address Book container record for given ContainerID
+
+   \param mem_ctx memory context for allocation
+   \param emsabp_ctx pointer to the EMSABP context
+   \param ContainerID id of the container to fetch
+   \param ldb_msg pointer on pointer to the LDB message returned by
+   the function
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_ERROR
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_ab_container_by_id(TALLOC_CTX *mem_ctx,
+						   struct emsabp_context *emsabp_ctx,
+						   uint32_t ContainerID,
+						   struct ldb_message **ldb_msg)
+{
+	int			ret;
+	char			*dn;
+	const char * const	recipient_attrs[] = { "globalAddressList", NULL };
+	struct ldb_result	*res = NULL;
+
+	if (!ContainerID) {
+		/* if GAL is requested */
+		ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, &res,
+				 ldb_get_config_basedn(emsabp_ctx->samdb_ctx),
+				 LDB_SCOPE_SUBTREE, recipient_attrs, "(globalAddressList=*)");
+		OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_CORRUPT_STORE, NULL);
+
+		/* TODO: If more than one GAL, determine the most appropriate */
+
+		dn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], "globalAddressList", NULL);
+		OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_STORE, NULL);
+	} else {
+		/* fetch a container we have already recorded */
+		ret = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, ContainerID, &dn);
+		OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(ret), MAPI_E_INVALID_BOOKMARK, NULL);
+	}
+
+	ret = emsabp_search_dn(emsabp_ctx, dn, ldb_msg);
+	OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(ret), MAPI_E_CORRUPT_STORE, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Enumerate AB container entries
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param ContainerID id of the container to fetch
+   \param ldb_res pointer on pointer to the LDB result returned by the
+   function
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_ab_container_enum(TALLOC_CTX *mem_ctx,
+						  struct emsabp_context *emsabp_ctx,
+						  uint32_t ContainerID,
+						  struct ldb_result **ldb_res)
+{
+	enum MAPISTATUS		retval;
+	int			ldb_ret;
+	struct ldb_message	*ldb_msg_ab;
+	const char		*purportedSearch;
+	const char * const	recipient_attrs[] = { "*", NULL };
+
+	/* Fetch AB container record */
+	retval = emsabp_ab_container_by_id(mem_ctx, emsabp_ctx, ContainerID, &ldb_msg_ab);
+	OPENCHANGE_RETVAL_IF(!MAPI_STATUS_IS_OK(retval), MAPI_E_INVALID_BOOKMARK, NULL);
+
+	purportedSearch = ldb_msg_find_attr_as_string(ldb_msg_ab, "purportedSearch", NULL);
+	if (!purportedSearch) {
+		*ldb_res = talloc_zero(mem_ctx, struct ldb_result);
+		return MAPI_E_SUCCESS;
+	}
+	OPENCHANGE_RETVAL_IF(!purportedSearch, MAPI_E_INVALID_BOOKMARK, NULL);
+
+	/* Search AD with purportedSearch filter */
+	ldb_ret = ldb_search(emsabp_ctx->samdb_ctx, mem_ctx, ldb_res,
+			     ldb_get_default_basedn(emsabp_ctx->samdb_ctx),
+			     LDB_SCOPE_SUBTREE, recipient_attrs, 
+			     "%s", purportedSearch);
+
+	return (ldb_ret != LDB_SUCCESS) ? MAPI_E_NOT_FOUND : MAPI_E_SUCCESS;
+}

Modified: trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -41,6 +41,7 @@
 	{ PR_EMAIL_ADDRESS,			"legacyExchangeDN",	false,	NULL			},
 	{ PR_EMS_AB_HOME_MDB,			"homeMDB",		true,	"legacyExchangeDN"	},
 	{ PR_EMS_AB_PROXY_ADDRESSES,		"proxyAddresses",	false,	NULL			},
+	{ PR_EMS_AB_PROXY_ADDRESSES_UNICODE,	"proxyAddresses",	false,	NULL			},
 	{ PR_EMS_AB_NETWORK_ADDRESS,		"networkAddress",	false,	NULL			},
 	{ PR_TITLE,				"personalTitle",	false,	NULL			},
 	{ 0,					NULL,			false,	NULL			}

Modified: trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -30,6 +30,14 @@
 #include <util/debug.h>
 
 /**
+   \details Structure to be used for MId traversal within TDB
+ */
+struct traverse_MId {
+	uint32_t	MId;
+	bool		found;
+};
+
+/**
    \details Open EMSABP TDB database
 
    \param mem_ctx pointer to the memory context
@@ -217,17 +225,21 @@
 				   TDB_DATA key, TDB_DATA dbuf, 
 				   void *state)
 {
-	TALLOC_CTX	*mem_ctx;
-	uint32_t	value;
-	char		*value_str = NULL;
-	uint32_t	*MId = (uint32_t *)state;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		value;
+	char			*value_str = NULL;
+	struct traverse_MId	*mid_trav = (struct traverse_MId *) state;
 
 	mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_traverse_MId");
 	value_str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize);
 	value = strtol((const char *)value_str, NULL, 16);
 	talloc_free(mem_ctx);
-	if (value == *MId) return 1;
 
+	if (value == mid_trav->MId) {
+		mid_trav->found = true;
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -244,11 +256,12 @@
 _PUBLIC_ bool emsabp_tdb_lookup_MId(TDB_CONTEXT *tdb_ctx,
 				    uint32_t MId)
 {
-	int	ret;
+	int			ret;
+	struct traverse_MId	mid_trav = { MId, false };
 
-	ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId, (void *)&MId);
+	ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId, (void *)&mid_trav);
 
-	return (ret == 1) ? true : false;
+	return (ret > 0) && mid_trav.found;
 }
 
 

Modified: trunk/openchange/ndr_mapi.c
===================================================================
--- trunk/openchange/ndr_mapi.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/ndr_mapi.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -392,7 +392,7 @@
   MAPI length field includes length bytes. 
   But these bytes do not belong to the mapi content in the user
   context. We have to add them when pushing mapi content length
-  (uint16_t) and next substract when pushing the content blob
+  (uint16_t) and next subtract when pushing the content blob
 */
 
 enum ndr_err_code ndr_push_mapi_request(struct ndr_push *ndr, int ndr_flags, const struct mapi_request *r)
@@ -962,7 +962,7 @@
 
 void ndr_print_mapi_SPropValue_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SPropValue_wrap *r)
 {
-	return ndr_print_mapi_SPropValue(ndr, name, (const struct mapi_SPropValue *)r);
+	ndr_print_mapi_SPropValue(ndr, name, (const struct mapi_SPropValue *)r);
 }
 
 
@@ -983,7 +983,7 @@
 
 void ndr_print_mapi_SPropValue_array_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SPropValue_array_wrap *r)
 {
-	return ndr_print_mapi_SPropValue_array(ndr, name, (const struct mapi_SPropValue_array *)r);
+	ndr_print_mapi_SPropValue_array(ndr, name, (const struct mapi_SPropValue_array *)r);
 }
 
 enum ndr_err_code ndr_push_RestrictionVariable(struct ndr_push *ndr, int ndr_flags, const union RestrictionVariable *r)

Modified: trunk/openchange/property.idl
===================================================================
--- trunk/openchange/property.idl	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/property.idl	2010-02-11 11:16:26 UTC (rev 3288)
@@ -99,6 +99,19 @@
 		FirstDOW_Saturday	= 0x6
 	} FirstDOW;
 
+	typedef [v1_enum] enum {
+		ARO_SUBJECT		= 0x0001,
+		ARO_MEETINGTYPE		= 0x0002,
+		ARO_REMINDERDELTA	= 0x0004,
+		ARO_REMINDER		= 0x0008,
+		ARO_LOCATION		= 0x0010,
+		ARO_BUSYSTATUS		= 0x0020,
+		ARO_ATTACHMENT		= 0x0040,
+		ARO_SUBTYPE		= 0x0080,
+		ARO_APPTCOLOR		= 0x0100,
+		ARO_EXCEPTIONAL_BODY	= 0x0200
+	} OverrideFlags;
+
 	typedef [public,flag(NDR_NOALIGN)] struct {
 		uint16						ReaderVersion;
 		uint16						WriterVersion;
@@ -119,7 +132,91 @@
 		uint32						StartDate;
 		uint32						EndDate;
 	} RecurrencePattern;
+	
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint32						ChangeHighlightSize;
+		uint32						ChangeHighlightValue;
+		uint32						Reserved;
+	} ChangeHighlight;
 
+	typedef [public,flag(NDR_NOALIGN)] struct {	
+		ChangeHighlight		ChangeHighlight;
+		uint32			ReservedBlockEE1Size;
+		uint32			ReservedBlockEE1;
+		uint32			StartDateTime;			
+		uint32			EndDateTime;
+		uint32			OriginalStartDate;
+		uint16			WidCharSubjectLength;
+		uint16			WideCharSubject;
+		uint16			WideCharLocationLength;
+		uint16			WideCharLocation;
+		uint32			ReservedBlockEE2Size;
+		uint32			ReservedBlockEE2;
+	} ExtendedException;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0000)]			;	
+		[case(0x0001)] 	uint16		sLength;
+		[case(0x0002)]	uint32		mType;
+		[case(0x0004)]	uint32		rDelta;
+		[case(0x0008)]	uint32		rSet;
+		[case(0x0010)]	uint16		lLength;
+		[case(0x0020)]	uint32		bStatus;
+		[case(0x0040)]	uint32		attachment;
+		[case(0x0080)]	uint32		sType;
+		[case(0x0100)]	uint32		aColor;
+		[default];
+	} Exception_Value;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[default];
+		[case(0x0001)] 	uint16		subject;
+		[case(0x0010)]	uint32		location;
+
+	} Exception_Msg;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+			uint32									StartDateTime;
+			uint32									EndDateTime;
+			uint32									OriginalStartDate;
+			OverrideFlags								OverrideFlags;
+			[switch_is(OverrideFlags & 0x0001)]	Exception_Value			SubjectLength;
+			[switch_is(OverrideFlags & 0x0001)]	Exception_Value			SubjectLength2;
+			[switch_is(OverrideFlags & 0x0001)]	Exception_Msg			Subject;
+			[switch_is(OverrideFlags & 0x0002)]	Exception_Value			MeetingType;
+			[switch_is(OverrideFlags & 0x0004)]	Exception_Value			ReminderDelta;
+			[switch_is(OverrideFlags & 0x0008)]	Exception_Value			ReminderSet;
+			[switch_is(OverrideFlags & 0x0010)]	Exception_Value			LocationLength;
+			[switch_is(OverrideFlags & 0x0010)]	Exception_Value			LocationLength2;
+			[switch_is(OverrideFlags & 0x0010)]	Exception_Msg			Location;
+			[switch_is(OverrideFlags & 0x0020)]	Exception_Value			BusyStatus;
+			[switch_is(OverrideFlags & 0x0040)]	Exception_Value			Attachment;
+			[switch_is(OverrideFlags & 0x0080)]	Exception_Value			SubType;
+			[switch_is(OverrideFlags & 0x0100)]	Exception_Value			AppointmentColor;
+	} ExceptionInfo;
+
+
+
+
+	
+	
+	typedef [public,flag(NDR_NOALIGN)] struct {
+
+		RecurrencePattern				RecurrencePattern;
+		uint32						ReaderVersion2;
+		uint32						WriterVersion2;
+		uint32						StartTimeOffset;
+		uint32						EndTimeOffset;
+		uint16						ExceptionCount;
+		ExceptionInfo					ExceptionInfo[ExceptionCount];
+ 		uint32						ReservedBlock1Size;
+		uint32						ReservedBlock1;
+		[flag(NDR_REMAINING)] DATA_BLOB data;
+//  		ExtendedException				ExtendedException[ExceptionCount];
+//  		uint32						ReservedBlock2Size;
+//  		uint32						ReservedBlock2;
+	} AppointmentRecurrencePattern;
+	
 	/* [MS-DIF].pdf Section 2.3.6 */
 	typedef [public,flag(NDR_NOALIGN)] struct {
 		uint16	wYear;

Modified: trunk/openchange/python/openchange/__init__.py
===================================================================
--- trunk/openchange/python/openchange/__init__.py	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/python/openchange/__init__.py	2010-02-11 11:16:26 UTC (rev 3288)
@@ -32,11 +32,13 @@
         return None # No extra path necessary
     except ImportError:
         SAMBA_PREFIXES = ["/usr/local/samba", "/opt/samba"]
-        PYTHON_NAMES = ["python2.3", "python2.4", "python2.5"]
+        LIB_DIRS = ["lib", "lib64"]
+        PYTHON_NAMES = ["python2.3", "python2.4", "python2.5", "python2.6"]
         for samba_prefix in SAMBA_PREFIXES:
-            for python_name in PYTHON_NAMES:
-                path = os.path.join(samba_prefix, "lib", python_name, 
-                                    "site-packages")
-                if os.path.isdir(os.path.join(path, "samba")):
-                    return path
+            for lib_dir in LIB_DIRS:
+                for python_name in PYTHON_NAMES:
+                    path = os.path.join(samba_prefix, lib_dir, python_name, 
+                                        "site-packages")
+                    if os.path.isdir(os.path.join(path, "samba")):
+                        return path
         raise ImportError("Unable to find the Samba python path")

Modified: trunk/openchange/python/openchange/provision.py
===================================================================
--- trunk/openchange/python/openchange/provision.py	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/python/openchange/provision.py	2010-02-11 11:16:26 UTC (rev 3288)
@@ -168,32 +168,14 @@
 
     db.transaction_commit()
 
-    # Step 3. Add ADSC classes to the schema
-    db = SamDB(url=lp.get("sam database"), session_info=session_info,
+    # Step 3. Extend existing classes and attributes
+    db = SamDB(url=lp.get("sam database"), session_info=session_info, 
                   credentials=creds, lp=lp)
 
     db.transaction_start()
 
     try:
-        print "[+] Step 3: Add missing ADSC classes to Samba schema"
-        setup_add_ldif(db, setup_path("AD/oc_provision_schema_ADSC.ldif"), {
-                "SCHEMADN": names.schemadn
-                })
-    except:
-        db.transaction_cancel()
-        raise
-
-    db.transaction_commit()
-
-
-    # Step 4. Extend existing classes and attributes
-    db = SamDB(url=lp.get("sam database"), session_info=session_info,
-                  credentials=creds, lp=lp)
-
-    db.transaction_start()
-
-    try:
-        print "[+] Step 4: Extend existing Samba classes and attributes"
+        print "[+] Step 3: Extend existing Samba classes and attributes"
         setup_modify_ldif(db, setup_path("AD/oc_provision_schema_modify.ldif"), {
                 "SCHEMADN": names.schemadn
                 })
@@ -205,13 +187,13 @@
 
 
     # Step 4. Add configuration objects
-    db = SamDB(url=lp.get("sam database"), session_info=system_session(),
+    db = SamDB(url=lp.get("sam database"), session_info=session_info, 
                   credentials=creds, lp=lp)
 
     db.transaction_start()
 
     try:
-        print "[+] Step 5: Exchange Samba with Exchange configuration objects"
+        print "[+] Step 4: Exchange Samba with Exchange configuration objects"
         setup_add_ldif(db, setup_path("AD/oc_provision_configuration.ldif"), {
                 "FIRSTORG": names.firstorg,
                 "FIRSTORGDN": names.firstorgdn,
@@ -364,7 +346,7 @@
 
     names = guess_names_from_smbconf(lp, None, None)
 
-    db = Ldb(url=os.path.join(lp.get("private dir"), "users.ldb"), 
+    db = Ldb(url=os.path.join(lp.get("private dir"), lp.get("sam database")), 
              session_info=system_session(), credentials=creds, lp=lp)
 
     user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)
@@ -373,20 +355,20 @@
 dn: %s
 changetype: modify
 add: displayName
-add: auxiliaryClass
-add: mailNickName
-add: homeMDB
-add: legacyExchangeDN
-add: proxyAddresses
-replace: msExchUserAccountControl
 displayName: %s
+add: auxiliaryClass
 auxiliaryClass: msExchBaseClass
+add: mailNickName
 mailNickname: %s
+add: homeMDB
 homeMDB: CN=Mailbox Store (%s),CN=First Storage Group,CN=InformationStore,CN=%s,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=%s,CN=Microsoft Exchange,CN=Services,CN=Configuration,%s
+add: legacyExchangeDN
 legacyExchangeDN: /o=%s/ou=First Administrative Group/cn=Recipients/cn=%s
+add: proxyAddresses
 proxyAddresses: smtp:postmaster@%s
 proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=%s
 proxyAddresses: SMTP:%s@%s
+replace: msExchUserAccountControl
 msExchUserAccountControl: 0
 """ % (user_dn, username, username, names.netbiosname, names.netbiosname, names.firstorg, names.domaindn, names.firstorg, username, names.dnsdomain, username, username, names.dnsdomain)
     db.modify_ldif(extended_user)
@@ -405,8 +387,8 @@
 
     names = guess_names_from_smbconf(lp, None, None)
 
-    db = Ldb(url=os.path.join(lp.get("private dir"), "users.ldb"), session_info=system_session(),
-                  credentials=creds, lp=lp)
+    db = Ldb(url=os.path.join(lp.get("private dir"), lp.get("sam database")), 
+             session_info=system_session(), credentials=creds, lp=lp)
 
     user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)
     extended_user = """

Added: trunk/openchange/qt/demo/demoapp.cpp
===================================================================
--- trunk/openchange/qt/demo/demoapp.cpp	                        (rev 0)
+++ trunk/openchange/qt/demo/demoapp.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,146 @@
+#include <Qt/QtGui>
+
+#include "demoapp.h"
+
+#include "../lib/foldermodel.h"
+#include "../lib/messagesmodel.h"
+
+#include <libmapi++/libmapi++.h>
+
+using namespace libmapipp;
+
+DemoApp::DemoApp()
+{
+    m_textEdit = new QTextEdit;
+    setCentralWidget( m_textEdit );
+
+    createActions();
+    createMenus();
+
+    login();
+    
+    addFolderDockWidget();
+    addMessagesDockWidget();
+    openMessage( 0 );
+      
+    resize( 1100, 900 );
+}
+
+void DemoApp::about()
+{
+    QMessageBox::about( this, tr( "OpenChange GUI Test Harness" ),
+			tr( "<qt>This test harness is for demonstrating and testing "
+			    "some of the OpenChange functionality. It is not "
+			    "intended for use in production.<br/><br/> <b>We mean it.</b></qt>" ) );
+}
+
+void DemoApp::createActions()
+{
+    m_aboutAction = new QAction( tr( "About" ), this );
+    connect( m_aboutAction, SIGNAL( triggered() ), this, SLOT( about() ) );
+    
+    m_quitAction = new QAction( tr( "&Quit" ), this );
+    // Use this if we ever require Qt 4.6
+    // m_quitAction->setShortcuts( QKeySequence::Quit );
+    m_quitAction->setShortcut( QKeySequence( Qt::Key_Q, Qt::CTRL ) );
+    m_quitAction->setStatusTip( tr( "Quit the application" ) );
+    connect( m_quitAction, SIGNAL( triggered() ), this, SLOT( close() ) );
+}
+
+void DemoApp::createMenus()
+{
+    m_fileMenu = menuBar()->addMenu( tr( "&File" ) );
+    m_fileMenu->addAction( m_quitAction );
+    
+    m_helpMenu = menuBar()->addMenu( tr( "&Help" ) );
+    m_helpMenu->addAction( m_aboutAction );
+}
+
+void DemoApp::login()
+{
+    // Initialize MAPI Session
+    m_mapi_session = new libmapipp::session();
+
+    m_mapi_session->login();
+}
+
+void DemoApp::addFolderDockWidget()
+{
+    m_folderDock = new QDockWidget( tr( "Folders" ), this );
+    
+    FolderModel *folder = new FolderModel( m_mapi_session );
+    m_folderModel = folder->buildModel();
+    
+    QTreeView *folderDockView = new QTreeView( m_folderDock );
+    folderDockView->setModel( m_folderModel );
+    folderDockView->expandToDepth( 2 );
+    connect( folderDockView, SIGNAL( clicked(QModelIndex) ), this, SLOT( folderChanged(QModelIndex) ) );
+    m_folderDock->setWidget( folderDockView );
+    
+    addDockWidget(Qt::LeftDockWidgetArea, m_folderDock);
+}
+
+void DemoApp::addMessagesDockWidget()
+{
+    QDockWidget *messagesDock = new QDockWidget( tr( "Messages" ), this );
+    
+    // Get Default Inbox folder ID.
+    mapi_id_t inbox_id = m_mapi_session->get_message_store().get_default_folder(olFolderInbox);
+    // std::cout << "inbox_id: " << inbox_id << std::endl;
+
+    // Open Inbox Folder
+    m_folder = new folder(m_mapi_session->get_message_store(), inbox_id);
+    MessagesModel *messages = new MessagesModel( m_folder );
+    
+    m_messagesDockView = new QTableView( messagesDock );
+    m_messagesModel = messages->buildModel();
+    m_messagesDockView->setModel( m_messagesModel );
+    m_messagesDockView->setShowGrid( false );
+    m_messagesDockView->resizeColumnsToContents();
+    m_messagesDockView->resizeRowsToContents();
+    connect( m_messagesDockView, SIGNAL( clicked(QModelIndex) ), this, SLOT( messageChanged(QModelIndex) ) );
+    messagesDock->setWidget( m_messagesDockView );
+    
+    splitDockWidget( m_folderDock, messagesDock, Qt::Horizontal );
+}
+
+void DemoApp::folderChanged(const QModelIndex &index)
+{
+    QStandardItem *item = m_folderModel->itemFromIndex( index );
+    if (item) {
+	qlonglong folderId = item->data().toLongLong();
+	m_folder = new folder(m_mapi_session->get_message_store(), folderId);
+	MessagesModel *messages = new MessagesModel( m_folder );
+	m_messagesModel = messages->buildModel();
+	m_messagesDockView->setModel( m_messagesModel );
+    }
+}
+
+void DemoApp::messageChanged( const QModelIndex &index )
+{
+    QStandardItem *item = m_messagesModel->itemFromIndex( index );
+    if ( item ) {
+	quint32 messageNumber = item->data().toUInt();
+	openMessage( messageNumber );
+    }
+}
+
+void DemoApp::openMessage( quint32 messageNumber )
+{
+    libmapipp::folder::message_container_type messages = m_folder->fetch_messages();
+    // std::cout << "Folder contains " << messages.size() << " messages" << std::endl;
+
+    // Get the properties we are interested in
+    libmapipp::property_container msg_props = messages[messageNumber]->get_property_container();
+    msg_props << PR_BODY_HTML;
+    msg_props.fetch();
+
+    if ( msg_props[PR_BODY_HTML] ) {
+	QString body = QString( (const char*)msg_props[PR_BODY_HTML] );
+	m_textEdit->setHtml( body );
+    } else {
+	m_textEdit->setHtml( QString() );
+    }
+}
+
+#include "demoapp.moc"

Added: trunk/openchange/qt/demo/demoapp.h
===================================================================
--- trunk/openchange/qt/demo/demoapp.h	                        (rev 0)
+++ trunk/openchange/qt/demo/demoapp.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,61 @@
+#ifndef DEMOAPP_H
+#define DEMOAPP_H
+
+#include <QtGui/QMainWindow>
+#include <QtGui/QStandardItemModel>
+
+class QAction;
+class QMenu;
+class QTextEdit;
+class QStandardItem;
+class QTableView;
+
+namespace libmapipp
+{
+  class session;
+  class folder;
+};
+
+class DemoApp : public QMainWindow
+{
+    Q_OBJECT
+
+  public:
+    DemoApp();
+
+  private slots:
+    void about();
+    void folderChanged( const QModelIndex &index );
+    void messageChanged( const QModelIndex &index );
+    
+  private:
+    void createActions();
+    void createMenus();
+
+    void login();
+    
+    void addFolderDockWidget();
+    void addMessagesDockWidget();
+    
+    void openMessage( quint32 messageNumber );
+
+    QMenu *m_fileMenu;
+    QMenu *m_helpMenu;
+
+    QAction *m_quitAction;
+    QAction *m_aboutAction;
+    
+    QDockWidget *m_folderDock;
+    QStandardItemModel *m_folderModel;
+    
+    QTableView *m_messagesDockView;
+    QStandardItemModel *m_messagesModel;
+    
+    libmapipp::folder *m_folder;
+    QTextEdit *m_textEdit;
+    
+    libmapipp::session *m_mapi_session;
+};
+
+#endif
+

Added: trunk/openchange/qt/demo/main.cpp
===================================================================
--- trunk/openchange/qt/demo/main.cpp	                        (rev 0)
+++ trunk/openchange/qt/demo/main.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,13 @@
+#include "demoapp.h"
+
+#include <QtGui/QApplication>
+
+int main(int argc, char *argv[])
+{
+    QApplication app(argc, argv);
+
+    DemoApp *demo = new DemoApp();
+    demo->show();
+
+    return app.exec();
+}

Added: trunk/openchange/qt/lib/foldermodel.cpp
===================================================================
--- trunk/openchange/qt/lib/foldermodel.cpp	                        (rev 0)
+++ trunk/openchange/qt/lib/foldermodel.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,76 @@
+#include <Qt/QtGui>
+#include <exception>
+#include <vector>
+#include <string>
+
+#include <QtCore/QStringList>
+#include <QtCore/QDebug>
+
+#include "foldermodel.h"
+
+#include <libmapi++/libmapi++.h>
+
+using namespace libmapipp;
+
+FolderModel::FolderModel( libmapipp::session *mapi_session ) :
+  m_mapi_session( mapi_session )
+{
+      m_folderModel = new QStandardItemModel();
+      QStringList folderModelHeaders;
+      folderModelHeaders << QString( "Folder Name" ) << QString( "FolderId" ) << QString( "Container Class" );
+      m_folderModel->setHorizontalHeaderLabels( folderModelHeaders );
+}
+
+void FolderModel::add_folder_to_tree(libmapipp::folder& up_folder, QStandardItem *parentItem)
+{
+      property_container up_folder_property_container = up_folder.get_property_container();
+      up_folder_property_container << PR_DISPLAY_NAME << PR_CONTAINER_CLASS;
+      up_folder_property_container.fetch();
+
+      std::string display_name = static_cast<const char*>(up_folder_property_container[PR_DISPLAY_NAME]);
+      std::string container_class;
+      if (up_folder_property_container[PR_CONTAINER_CLASS])
+	      container_class = static_cast<const char*>(up_folder_property_container[PR_CONTAINER_CLASS]);
+
+      QList< QStandardItem * > row;
+      QStandardItem *name = new QStandardItem( QString::fromStdString( display_name ) );
+      name->setData( (qlonglong)up_folder.get_id() );
+      QStandardItem *folderId = new QStandardItem( QString::number( up_folder.get_id(), 16 ) );
+      QStandardItem *containerClass = new QStandardItem( QString::fromStdString( container_class ) );
+      row << name << folderId << containerClass;
+
+      parentItem->appendRow( row );
+
+      // Fetch Top Information Folder Hierarchy (child folders)
+      folder::hierarchy_container_type hierarchy = up_folder.fetch_hierarchy();
+      for (unsigned int i = 0; i < hierarchy.size(); ++i) {
+	      add_folder_to_tree(*hierarchy[i], name);
+      }
+}
+
+QStandardItemModel* FolderModel::buildModel()
+{
+      try {
+	    // Get Default Top Information Store folder ID
+	    mapi_id_t top_folder_id = m_mapi_session->get_message_store().get_default_folder(olFolderTopInformationStore);
+
+	    // Open Top Information Folder
+	    folder top_folder( m_mapi_session->get_message_store(), top_folder_id );
+
+	    QStandardItem *parentItem = m_folderModel->invisibleRootItem();
+
+	    add_folder_to_tree(top_folder, parentItem);
+      }
+      catch (mapi_exception e) // Catch any mapi exceptions
+      {
+              std::cout << "MAPI Exception @ main: " <<  e.what() << std::endl;
+      }
+      catch (std::runtime_error e) // Catch runtime exceptions
+      {
+              std::cout << "std::runtime_error exception @ main: " << e.what() << std::endl;
+      }
+      return m_folderModel;
+}
+
+
+#include "foldermodel.moc"

Added: trunk/openchange/qt/lib/foldermodel.h
===================================================================
--- trunk/openchange/qt/lib/foldermodel.h	                        (rev 0)
+++ trunk/openchange/qt/lib/foldermodel.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,30 @@
+#ifndef FOLDERMODEL_H
+#define FOLDERMODEL_H
+
+class QStandardItem;
+class QStandardItemModel;
+
+namespace libmapipp
+{
+class folder;
+class session;
+}
+
+class FolderModel : public QStandardItemModel
+{
+    Q_OBJECT
+
+  public:
+    FolderModel( libmapipp::session *mapi_session );
+
+    QStandardItemModel* buildModel();
+
+  private:
+    libmapipp::session *m_mapi_session;
+    QStandardItemModel *m_folderModel;
+    
+    void add_folder_to_tree(libmapipp::folder& up_folder, QStandardItem *parentItem);
+};
+
+
+#endif

Added: trunk/openchange/qt/lib/messagesmodel.cpp
===================================================================
--- trunk/openchange/qt/lib/messagesmodel.cpp	                        (rev 0)
+++ trunk/openchange/qt/lib/messagesmodel.cpp	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,55 @@
+#include "messagesmodel.h"
+
+#include <libmapi++/libmapi++.h>
+
+using namespace libmapipp;
+
+MessagesModel::MessagesModel( libmapipp::folder *folder ):
+  m_mapi_folder( folder )
+{
+}
+    
+QStandardItemModel* MessagesModel::buildModel()
+{
+    // Fetch messages in Inbox Folder
+    folder::message_container_type messages = m_mapi_folder->fetch_messages();
+
+    QStandardItemModel *messagesModel = new QStandardItemModel();
+    QStringList messagesModelHeaders;
+    messagesModelHeaders << QString( "Topic" ) << QString( "To" ) << QString( "From" );
+    messagesModel->setHorizontalHeaderLabels( messagesModelHeaders );
+
+    for ( unsigned int i = 0; i < messages.size(); ++i ) {
+	property_container message_property_container = messages[i]->get_property_container();
+
+	// Add Property Tags to be fetched and then fetch the properties.
+	message_property_container << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC << PR_SENDER_NAME;
+	message_property_container.fetch_all();
+
+	std::string to;
+	std::string subject;
+	std::string from;
+
+	for (property_container::iterator Iter = message_property_container.begin(); Iter != message_property_container.end(); Iter++)
+	{
+		if (Iter.get_tag() == PR_DISPLAY_TO)
+			to = (const char*) *Iter;
+		else if (Iter.get_tag() == PR_CONVERSATION_TOPIC)
+			subject = (const char*) *Iter;
+		else if (Iter.get_tag() == PR_SENDER_NAME)
+			from = (const char*) *Iter;
+	}
+	QList< QStandardItem * > row;
+	row << new QStandardItem( QString::fromStdString( subject ) );
+	row[0]->setData( (quint32) i );
+	row << new QStandardItem( QString::fromStdString( to ) );
+	row << new QStandardItem( QString::fromStdString( from ) );
+	messagesModel->appendRow( row );
+    }
+    
+    return messagesModel;
+}
+
+
+
+#include "messagesmodel.moc"

Added: trunk/openchange/qt/lib/messagesmodel.h
===================================================================
--- trunk/openchange/qt/lib/messagesmodel.h	                        (rev 0)
+++ trunk/openchange/qt/lib/messagesmodel.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,27 @@
+#ifndef MESSAGESMODEL_H
+#define MESSAGESMODEL_H
+
+class QStandardItem;
+#include <QStandardItemModel>
+
+namespace libmapipp
+{
+class folder;
+class session;
+}
+
+
+class MessagesModel : public QStandardItemModel
+{
+    Q_OBJECT
+    
+  public:
+    MessagesModel( libmapipp::folder *folder );
+    
+    QStandardItemModel *buildModel();
+    
+  private:
+    libmapipp::folder *m_mapi_folder;
+};
+
+#endif

Modified: trunk/openchange/script/mkrelease.sh
===================================================================
--- trunk/openchange/script/mkrelease.sh	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/script/mkrelease.sh	2010-02-11 11:16:26 UTC (rev 3288)
@@ -5,7 +5,7 @@
 # ./script/mkrelease.sh 0.7 PHASER Phaser 308
 #
 
-TMPDIR=`mktemp libmapi-XXXXX`
+TMPDIR=`mktemp openchange-XXXXX`
 rm $TMPDIR || exit 1
 svn export . $TMPDIR || exit 1
 svn log -r$4:HEAD > $TMPDIR/CHANGELOG || exit 1
@@ -26,10 +26,10 @@
 ) || exit 1
 
 VERSION=$1-$2
-mv $TMPDIR libmapi-$VERSION || exit 1
-tar -cf libmapi-$VERSION.tar libmapi-$VERSION || exit 1
+mv $TMPDIR openchange-$VERSION || exit 1
+tar -cf openchange-$VERSION.tar openchange-$VERSION || exit 1
 echo "Now run: "
-echo "gpg --detach-sign --armor libmapi-$VERSION.tar"
-echo "gzip libmapi-$VERSION.tar" 
+echo "gpg --detach-sign --armor openchange-$VERSION.tar"
+echo "gzip openchange-$VERSION.tar" 
 echo "And then upload "
-echo "libmapi-$VERSION.tar.gz libmapi-$VERSION.tar.asc" 
+echo "openchange-$VERSION.tar.gz openchange-$VERSION.tar.asc" 

Modified: trunk/openchange/script/samba4_ver.sh
===================================================================
--- trunk/openchange/script/samba4_ver.sh	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/script/samba4_ver.sh	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,4 +1,4 @@
-SAMBA4_GIT_REV=4ceae35
-SAMBA4_GIT_VER=4.0.0alpha8
-SAMBA4_RELEASE=4.0.0alpha8
+SAMBA4_GIT_REV=100e249
+SAMBA4_GIT_VER=4.0.0alpha10
+SAMBA4_RELEASE=4.0.0alpha10
 

Added: trunk/openchange/script/smoketest.sh
===================================================================
--- trunk/openchange/script/smoketest.sh	                        (rev 0)
+++ trunk/openchange/script/smoketest.sh	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,199 @@
+#!/bin/sh
+
+ADMIN_USERNAME=Administrator
+ADMIN_PASSWORD=YeahWhatever
+
+TEST1_USERNAME=testuser1
+TEST1_USERPASS=testuser1
+TEST1_PROFILENAME=testuser1
+
+TEST2_USERNAME=
+TEST2_USERPASS=
+TEST2_PROFILENAME=
+
+SERVER1_NAME=
+SERVER2_NAME=
+SERVER1_IP=192.168.244.20
+
+SERVER1_DOMAIN=OPENCHANGETEST
+
+########################################################################
+# Support functions
+#
+# You shouldn't need to modify anything after this
+########################################################################
+
+declare -i TESTCOUNT=0
+declare -i TESTPOINTCOUNT=0
+TEST() {
+    TESTPOINTCOUNT=0
+    TESTCOUNT=$TESTCOUNT+1
+    echo "##############################################################"
+    echo "Test $TESTCOUNT: $1"
+    echo "##############################################################"
+}
+
+TESTPOINT() {
+    TESTPOINTCOUNT=$TESTPOINTCOUNT+1
+    echo "# Testpoint $TESTCOUNT.$TESTPOINTCOUNT: $1"
+    res=eval $1
+    echo $res
+    echo ""
+}
+
+TESTPOINT_VERSION() {
+    TOOL=$1
+    TESTPOINT "$TOOL --version"
+    TESTPOINT "$TOOL -V"
+}
+
+TESTPOINT_USAGE() {
+    TOOL=$1
+    TESTPOINT "$TOOL --help"
+    TESTPOINT "$TOOL -?"
+    TESTPOINT "$TOOL --usage"
+}
+
+########################################################################
+TEST "Verify mapiprofile"
+########################################################################
+
+TESTPOINT_VERSION "./bin/mapiprofile"
+
+TESTPOINT_USAGE "./bin/mapiprofile"
+
+## Create a test profile database
+PROFILEDB=`mktemp -u profiles.XXXXXXXXXXXXXXXXXXXXX`
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --newdb"
+
+## Check we are OK if there is no entries in the database
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --list"
+
+## Check that the languages list stuff works
+TESTPOINT "./bin/mapiprofile --listlangs"
+
+## Test point - Create an admin account profile
+
+## Test point - Set the admin account as the default
+
+## List the accounts
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --list"
+
+## Get the default account
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --getdefault"
+
+## Create a (test) user account using NTLM
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --username=$TEST1_USERNAME --password=$TEST1_USERPASS --profile=$TEST1_PROFILENAME --address=$SERVER1_IP --domain=$SERVER1_DOMAIN --create"
+
+## Test point - Create another (test) user account using Kerberos
+
+## Set the user account as the default
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --profile=$TEST1_PROFILENAME --default"
+
+## Dump a profile's contents
+TESTPOINT "./bin/mapiprofile --database=$PROFILEDB --profile=$TEST1_PROFILENAME --dump"
+
+## Test point - Delete a profile
+
+########################################################################
+TEST "Verify openchangeclient basic functions"
+########################################################################
+
+TESTPOINT_VERSION "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME"
+
+TESTPOINT_USAGE "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME"
+
+########################################################################
+TEST "Verify openchangeclient admin functions"
+########################################################################
+
+########################################################################
+TEST "Verify openchangeclient user functions"
+########################################################################
+
+## Verify that we can get a basic mailbox list
+TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --mailbox"
+
+## Verify that we can list the users
+TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --userlist"
+
+## Verify that we can download mail
+TESTPOINT "./bin/openchangeclient --database=$PROFILEDB --profile=$TEST1_PROFILENAME --fetchmail"
+
+## Test point - verify we can send plain text mail
+
+## Test point - verify we can send HTML mail
+
+## Test point - verify we can add an attachment to a mail
+
+########################################################################
+TEST "Verify openchangeclient OCPF functions"
+########################################################################
+
+########################################################################
+TEST "Run the mapitest suite"
+########################################################################
+
+TESTPOINT_VERSION "./bin/mapitest"
+
+TESTPOINT_USAGE "./bin/mapitest"
+
+TESTPOINT ./bin/mapitest --database=$PROFILEDB --no-server
+
+## Test point - Run just one step from mapitest
+
+
+## Run mapitest as a specified user
+TESTPOINT "./bin/mapitest --database=$PROFILEDB --profile=$TEST1_PROFILENAME"
+
+########################################################################
+TEST "Verify exchange2mbox"
+########################################################################
+
+TESTPOINT_VERSION "./bin/exchange2mbox"
+
+TESTPOINT_USAGE "./bin/exchange2mbox"
+
+########################################################################
+TEST "Verify exchange2ical"
+########################################################################
+
+TESTPOINT_VERSION "./bin/exchange2ical"
+
+TESTPOINT_USAGE "./bin/exchange2ical"
+
+## Verify basic dump of calendar
+TESTPOINT "./bin/exchange2ical --database=$PROFILEDB --profile=$TEST1_PROFILENAME"
+
+########################################################################
+TEST "Verify locale_codepage"
+########################################################################
+
+TESTPOINT_VERSION "./bin/locale_codepage"
+
+TESTPOINT_USAGE "./bin/locale_codepage"
+
+## Check a locale ID
+TESTPOINT "./bin/locale_codepage --locale_id=0x0c09"
+
+## Verify the group listing works
+TESTPOINT "./bin/locale_codepage --list-groups"
+
+## Check a codepage
+TESTPOINT "./bin/locale_codepage --codepage=0x4B0"
+
+########################################################################
+TEST "Verify openchangepfadmin"
+########################################################################
+
+TESTPOINT_VERSION "./bin/openchangepfadmin"
+
+TESTPOINT_USAGE "./bin/openchangepfadmin"
+
+## Get the list of public folders
+TESTPOINT "./bin/openchangepfadmin --database=$PROFILEDB --profile=$TEST1_PROFILENAME --list"
+
+#############
+# Cleanup stuff
+#############
+rm $PROFILEDB


Property changes on: trunk/openchange/script/smoketest.sh
___________________________________________________________________
Added: svn:executable
   + *

Modified: trunk/openchange/setup/AD/oc_provision_configuration.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_configuration.ldif	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/setup/AD/oc_provision_configuration.ldif	2010-02-11 11:16:26 UTC (rev 3288)
@@ -15,7 +15,6 @@
 distinguishedName: CN=Microsoft Exchange,CN=Services,${CONFIGDN}
 showInAdvancedViewOnly: TRUE
 adminDisplayName: Microsoft Exchange
-heuristics: 6
 name: Microsoft Exchange
 objectCategory: CN=ms-Exch-Configuration-Container,${SCHEMADN}
 addressBookRoots: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
@@ -39,13 +38,8 @@
 name: ${FIRSTORG}
 legacyExchangeDN: /o=${FIRSTORG}
 objectCategory: CN=ms-Exch-Organization-Container,${SCHEMADN}
-msExchRoutingEnabled: FALSE
-msExchMixedMode: TRUE
-msExchAdminGroupsEnabled: FALSE
-msExchAdmins: S-1-5-21-1226241484-1028146065-4277480997-500,10
 
 
-
 #
 # Administrative Groups
 #
@@ -108,7 +102,6 @@
 distinguishedName: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
 showInAdvancedViewOnly: TRUE
 adminDisplayName: ${NETBIOSNAME}
-heuristics: 1576964
 messageTrackingEnabled: FALSE
 networkAddress: ncacn_vns_spp:${NETBIOSNAME}
 networkAddress: netbios:${NETBIOSNAME}
@@ -226,7 +219,7 @@
 
 
 #
-# All Address Lists Containers
+# Address Lists Containers
 # description: Address book root container
 #
 dn: CN=Address Lists Container,${FIRSTORGDN}
@@ -235,6 +228,7 @@
 objectClass: msExchContainer
 cn: Address Lists Container
 distinguishedName: CN=Address Lists Container,${FIRSTORGDN}
+instanceType: 4
 displayName: Address Lists Container
 showInAdvancedViewOnly: TRUE
 name: Address Lists Container

Modified: trunk/openchange/setup/AD/oc_provision_schema.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema.ldif	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/setup/AD/oc_provision_schema.ldif	2010-02-11 11:16:26 UTC (rev 3288)
@@ -2,10 +2,6 @@
 # Classes added
 ##############################################################################
 
-
-
-
-
 #
 # ms-Exch-Active-Directory-Connector
 # Represents the service that synchronizes information between the
@@ -1526,7 +1522,7 @@
 mayContain: msExchInstallPath
 mayContain: heuristics
 mayContain: msExchComputerLink
-mayContain: msExchAddressListServiceBL
+#mayContain: msExchAddressListServiceBL
 rDNAttID: cn
 showInAdvancedViewOnly: TRUE
 adminDisplayName: ms-Exch-Exchange-Server
@@ -1545,40 +1541,6 @@
 
 
 #
-# ms-Exch-Configuration-Container
-# description: This container stores configuration information for the Exchange server.
-#
-dn: CN=ms-Exch-Configuration-Container,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: ms-Exch-Configuration-Container
-distinguishedName: CN=ms-Exch-Configuration-Container,${SCHEMADN}
-subClassOf: container
-governsID: 1.2.840.113556.1.5.176
-mayContain: msExchPolicyRoots
-mayContain: msExchMasterService
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: ms-Exch-Configuration-Container
-adminDescription: ms-Exch-Configuration-Container
-auxiliaryClass: msExchBaseClass
-objectClassCategory: 1
-lDAPDisplayName: msExchConfigurationContainer
-name: ms-Exch-Configuration-Container
-schemaIDGUID: d03d6858-06f4-11d2-aa53-00c04fd7d83a
-systemOnly: FALSE
-systemMayContain: templateRoots
-systemMayContain: addressBookRoots
-systemMayContain: globalAddressList
-defaultSecurityDescriptor: D:S:
-systemFlags: 16
-defaultHidingValue: TRUE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=ms-Exch-Configuration-Container,${SCHEMADN}
-
-
-
-#
 # ms-Exch-Exchange-Server-Policy
 # The Exchange server policy.
 #
@@ -3310,8 +3272,136 @@
 defaultObjectCategory: CN=ms-Exch-Protocol-Cfg,${SCHEMADN}
 
 
+#
+# ms-Exch-Protocol-Cfg-Protocol-Container
+#
+dn: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-Protocol-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN}
+instanceType: 4
+possSuperiors: protocolCfgSharedServer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.2000
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-Protocol-Container
+adminDescription: ms-Exch-Protocol-Cfg-Protocol-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgProtocolContainer
+name: ms-Exch-Protocol-Cfg-Protocol-Container
+schemaIDGUID: 90f2b634-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Protocol-Container,${SCHEMADN}
 
+
+
 #
+# ms-Exch-Protocol-Cfg-Shared
+#
+dn: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-Shared
+distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN}
+instanceType: 4
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.65
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: useSiteValues
+mayContain: oWAServer
+mayContain: formData
+mayContain: folderPathname
+mayContain: connectionListFilterType
+mayContain: connectionListFilter
+mayContain: characterSetList
+mayContain: availableAuthorizationPackages
+mayContain: helpData32
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-Shared
+adminDescription: ms-Exch-Protocol-Cfg-Shared
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgShared
+name: ms-Exch-Protocol-Cfg-Shared
+schemaIDGUID: a8df74d0-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-Shared-Site
+#
+dn: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-Shared-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN}
+instanceType: 4
+possSuperiors: container
+subClassOf: protocolCfgShared
+governsID: 1.2.840.113556.1.3.66
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Site
+adminDescription: ms-Exch-Protocol-Cfg-Shared-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSharedSite
+name: ms-Exch-Protocol-Cfg-Shared-Site
+schemaIDGUID: a8df74d2-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Site,${SCHEMADN}
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.5.7000.62.5001
+mayContain: msExchLogonACL
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyList
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP
+adminDescription: ms-Exch-Protocol-Cfg-SMTP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTP
+name: ms-Exch-Protocol-Cfg-SMTP
+schemaIDGUID: 33f98980-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP,${SCHEMADN}
+
+
+#
 # ms-Exch-Protocol-Cfg-HTTP
 #
 dn: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN}
@@ -3343,8 +3433,37 @@
 objectCategory: CN=Class-Schema,${SCHEMADN}
 defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN}
 
+#
+# ms-Exch-Protocol-Cfg-Shared-Server
+#
+dn: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-Shared-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN}
+instanceType: 4
+possSuperiors: msExchExchangeServer
+possSuperiors: container
+possSuperiors: computer
+subClassOf: protocolCfgShared
+governsID: 1.2.840.113556.1.3.67
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Server
+adminDescription: ms-Exch-Protocol-Cfg-Shared-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSharedServer
+name: ms-Exch-Protocol-Cfg-Shared-Server
+schemaIDGUID: a8df74d1-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Server,${SCHEMADN}
 
 
+
 #
 # ms-Exch-Protocol-Cfg-HTTP-Container  
 #
@@ -4081,6 +4200,34 @@
 
 
 #
+# ms-Exch-Protocol-Cfg-Shared-Container
+#
+dn: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-Shared-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN}
+possSuperiors: protocolCfgSharedServer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.2001
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-Shared-Container
+adminDescription: ms-Exch-Protocol-Cfg-Shared-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgSharedContainer
+name: ms-Exch-Protocol-Cfg-Shared-Container
+schemaIDGUID: 939ef91a-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-Shared-Container,${SCHEMADN}
+
+
+#
 # ms-Exch-Protocol-Cfg-SMTP-Container	
 #
 dn: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN}
@@ -6195,27 +6342,27 @@
 # The link from the Exchange server to the address list service
 # running on it.
 #
-dn: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: ms-Exch-Address-List-Service-BL
-distinguishedName: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN}
-attributeID: 1.2.840.113556.1.4.7000.102.74
-attributeSyntax: 2.5.5.1
-isSingleValued: TRUE
-linkID: 1017
-showInAdvancedViewOnly: TRUE
-adminDisplayName: ms-Exch-Address-List-Service-BL
-oMObjectClass:: KwwCh3McAIVK
-adminDescription: ms-Exch-Address-List-Service-BL
-oMSyntax: 127
-searchFlags: 0
-lDAPDisplayName: msExchAddressListServiceBL
-name: ms-Exch-Address-List-Service-BL
-schemaIDGUID: 8a407b6e-b09e-11d2-aa06-00c04f8eedd8
-systemFlags: 1
-isMemberOfPartialAttributeSet: FALSE
-objectCategory: CN=Attribute-Schema,${SCHEMADN}
+#dn: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN}
+#objectClass: top
+#objectClass: attributeSchema
+#cn: ms-Exch-Address-List-Service-BL
+#distinguishedName: CN=ms-Exch-Address-List-Service-BL,${SCHEMADN}
+#attributeID: 1.2.840.113556.1.4.7000.102.74
+#attributeSyntax: 2.5.5.1
+#isSingleValued: TRUE
+#linkID: 1017
+#showInAdvancedViewOnly: TRUE
+#adminDisplayName: ms-Exch-Address-List-Service-BL
+#oMObjectClass:: KwwCh3McAIVK
+#adminDescription: ms-Exch-Address-List-Service-BL
+#oMSyntax: 127
+#searchFlags: 0
+#lDAPDisplayName: msExchAddressListServiceBL
+#name: ms-Exch-Address-List-Service-BL
+#schemaIDGUID: 8a407b6e-b09e-11d2-aa06-00c04f8eedd8
+#systemFlags: 1
+#isMemberOfPartialAttributeSet: FALSE
+#objectCategory: CN=Attribute-Schema,${SCHEMADN}
 
 
 
@@ -29711,94 +29858,3 @@
 schemaIDGUID: 1482fed4-b098-11d2-aa06-00c04f8eedd8
 isMemberOfPartialAttributeSet: FALSE
 objectCategory: CN=Attribute-Schema,${SCHEMADN}
-
-
-
-
-
-
-
-
-
-##############################################################################
-##############################################################################
-
-
-
-#
-# Specifies the trees of address book containers to appear in MAPI
-# address book
-#
-dn: CN=Address-Book-Roots,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: Address-Book-Roots
-distinguishedName: CN=Address-Book-Roots,${SCHEMADN}
-attributeID: 1.2.840.113556.1.4.1244
-attributeSyntax: 2.5.5.1
-isSingleValued: FALSE
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Address-Book-Roots
-oMObjectClass:: KwwCh3McAIVK
-adminDescription: Address-Book-Roots
-oMSyntax: 127
-searchFlags: 0
-lDAPDisplayName: addressBookRoots
-name: Address-Book-Roots
-schemaIDGUID: f70b6e48-06f4-11d2-aa53-00c04fd7d83a
-systemOnly: FALSE
-systemFlags: 16
-objectCategory: CN=Attribute-Schema,${SCHEMADN}
-
-
-
-#
-# Store the distinguished name of a newly created global address list
-# (GAL)
-#
-dn: CN=Global-Address-List,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: Global-Address-List
-distinguishedName: CN=Global-Address-List,${SCHEMADN}
-attributeID: 1.2.840.113556.1.4.1245
-attributeSyntax: 2.5.5.1
-isSingleValued: FALSE
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Global-Address-List
-oMObjectClass:: KwwCh3McAIVK
-adminDescription: Global-Address-List
-oMSyntax: 127
-searchFlags: 0
-lDAPDisplayName: globalAddressList
-name: Global-Address-List
-schemaIDGUID:f754c748-06f4-11d2-aa53-00c04fd7d83a
-systemOnly: FALSE
-systemFlags: 16
-objectCategory: CN=Attribute-Schema,${SCHEMADN}
-
-
-#
-# Specifies an attribute used on the Exchange Server configuration
-# container to indicate where the template containers are stored
-#
-dn: CN=Template-Roots,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: Template-Roots
-distinguishedName: CN=Template-Roots,${SCHEMADN}
-attributeID: 1.2.840.113556.1.4.1346
-attributeSyntax: 2.5.5.1
-isSingleValued: FALSE
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Template-Roots
-oMObjectClass:: KwwCh3McAIVK
-adminDescription: Template-Roots
-oMSyntax: 127
-searchFlags: 0
-lDAPDisplayName: templateRoots
-name: Template-Roots
-schemaIDGUID: ed9de9a0-7041-11d2-9905-0000f87a57d4
-systemOnly: FALSE
-systemFlags: 16
-objectCategory: CN=Attribute-Schema,${SCHEMADN}

Deleted: trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,249 +0,0 @@
-#
-# Address-Book-Container
-# description: holding members of an address book view
-#
-dn: CN=Address-Book-Container,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: Address-Book-Container
-distinguishedName: CN=Address-Book-Container,${SCHEMADN}
-possSuperiors: msExchConfigurationContainer
-possSuperiors: container
-subClassOf: top
-governsID: 1.2.840.113556.1.5.125
-mayContain: msExchMinAdminVersion
-mayContain: msExchAddressListOU
-mayContain: msExchSearchScope
-mayContain: msExchSearchBase
-mayContain: msExchEnableInternalEvaluator
-mayContain: msExchPurportedSearchUI
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Address-Book-Container
-adminDescription: Address-Book-Container
-objectClassCategory: 1
-lDAPDisplayName: addressBookContainer
-name: Address-Book-Container
-schemaIDGUID: 3e74f60f-3e73-11d1-a9c0-0000f80367c1
-systemOnly: FALSE
-systemPossSuperiors: addressBookContainer
-systemPossSuperiors: configuration
-systemMayContain: purportedSearch
-systemMustContain: displayName
-defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
-systemFlags: 16
-defaultHidingValue: TRUE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=Address-Book-Container,${SCHEMADN}
-
-
-
-#
-# Contact
-# description: contains information about a person or company that
-# users may often contact
-#
-dn: CN=Contact,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: Contact
-distinguishedName: CN=Contact,${SCHEMADN}
-subClassOf: organizationalPerson
-governsID: 1.2.840.113556.1.5.15
-mayContain: msExchOriginatingForest
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Contact
-adminDescription: Contact
-auxiliaryClass: msExchMultiMediaUser
-auxiliaryClass: msExchCertificateInformation
-auxiliaryClass: msExchBaseClass
-auxiliaryClass: msExchCustomAttributes
-objectClassCategory: 1
-lDAPDisplayName: contact
-name: Contact
-schemaIDGUID: 5cb41ed0-0e4c-11d0-a286-00aa003049e2
-systemOnly: FALSE
-systemPossSuperiors: organizationalUnit
-systemPossSuperiors: domainDNS
-systemMayContain: notes
-systemMustContain: cn
-systemAuxiliaryClass: mailRecipient
-defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
-systemFlags: 16
-defaultHidingValue: FALSE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=Person,${SCHEMADN}
-
-
-
-#
-# DisplayTemplate
-# description: specifies information for an address template.
-#
-dn: CN=Display-Template,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: Display-Template
-distinguishedName: CN=Display-Template,${SCHEMADN}
-subClassOf: top
-governsID: 1.2.840.113556.1.3.59
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Display-Template
-adminDescription: Display-Template
-auxiliaryClass: msExchBaseClass
-objectClassCategory: 1
-lDAPDisplayName: displayTemplate
-name: Display-Template
-schemaIDGUID: 5fd4250c-1262-11d0-a060-00aa006c33ed
-systemOnly: FALSE
-systemPossSuperiors: container
-systemMayContain: originalDisplayTableMSDOS
-systemMayContain: originalDisplayTable
-systemMayContain: helpFileName
-systemMayContain: helpData32
-systemMayContain: helpData16
-systemMayContain: addressEntryDisplayTableMSDOS
-systemMayContain: addressEntryDisplayTable
-systemMustContain: cn
-defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
-defaultHidingValue: TRUE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=Display-Template,${SCHEMADN}
-
-
-
-#
-# DSA 
-# description: Directory service only uses the subclass MSFT-DSA
-#
-dn: CN=DSA,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: DSA
-distinguishedName: CN=DSA,${SCHEMADN}
-subClassOf: applicationEntity
-governsID: 2.5.6.13
-mayContain: fileVersion
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: DSA
-adminDescription: DSA
-objectClassCategory: 1
-lDAPDisplayName: dSA
-name: DSA
-schemaIDGUID: 3fdfee52-47f4-11d1-a9c3-0000f80367c1
-systemOnly: FALSE
-systemPossSuperiors: server
-systemPossSuperiors: computer
-systemMayContain: knowledgeInformation
-defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
-systemFlags: 16
-defaultHidingValue: TRUE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=DSA,${SCHEMADN}
-
-
-
-#
-# Group-Of-Names
-# description: Used to define entries representing an unordered set of
-# names that represent individual objects or other groups of names.
-#
-dn: CN=Group-Of-Names,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: Group-Of-Names
-distinguishedName: CN=Group-Of-Names,${SCHEMADN}
-subClassOf: top
-governsID: 2.5.6.9
-mayContain: reportToOwner
-mayContain: reportToOriginator
-mayContain: oOFReplyToOriginator
-mayContain: hideDLMembership
-mayContain: dLMemberRule
-rDNAttID: cn
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Group-Of-Names
-adminDescription: Group-Of-Names
-objectClassCategory: 0
-lDAPDisplayName: groupOfNames
-name: Group-Of-Names
-schemaIDGUID: bf967a9d-0de6-11d0-a285-00aa003049e2
-systemOnly: FALSE
-systemPossSuperiors: organizationalUnit
-systemPossSuperiors: locality
-systemPossSuperiors: organization
-systemPossSuperiors: container
-systemMayContain: seeAlso
-systemMayContain: owner
-systemMayContain: ou
-systemMayContain: o
-systemMayContain: businessCategory
-systemMustContain: member
-systemMustContain: cn
-defaultSecurityDescriptor: D:(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;DA)(A;;RPWPCRCCD
-systemFlags: 16
-defaultHidingValue: TRUE
-objectCategory: CN=Class-Schema,${SCHEMADN}
-defaultObjectCategory: CN=Group-Of-Names,${SCHEMADN}
-
-
-
-#
-# PurportedSearch
-# description: This attribute specifies the search argument for an
-# address book view.
-#
-dn: CN=Purported-Search,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: Purported-Search
-distinguishedName: CN=Purported-Search,${SCHEMADN}
-attributeID: 1.2.840.113556.1.4.886
-attributeSyntax: 2.5.5.12
-isSingleValued: TRUE
-rangeLower: 0
-rangeUpper: 2048
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Purported-Search
-adminDescription: Purported-Search
-oMSyntax: 64
-searchFlags: 8
-lDAPDisplayName: purportedSearch
-name: Purported-Search
-schemaIDGUID: b4b54e50-943a-11d1-aebd-0000f80367c1
-systemOnly: FALSE
-systemFlags: 16
-objectCategory: CN=Attribute-Schema,${SCHEMADN}
-
-
-
-#
-# Owner
-# description: The distinguished name of an object that has ownership
-# of an object.
-#
-dn: CN=Owner,${SCHEMADN}
-objectClass: top
-objectClass: attributeSchema
-cn: Owner
-distinguishedName: CN=Owner,${SCHEMADN}
-attributeID: 2.5.4.32
-attributeSyntax: 2.5.5.1
-isSingleValued: TRUE
-linkID: 44
-showInAdvancedViewOnly: TRUE
-adminDisplayName: Owner
-oMObjectClass:: KwwCh3McAIVK
-adminDescription: Owner
-oMSyntax: 127
-searchFlags: 0
-lDAPDisplayName: owner
-name: Owner
-schemaIDGUID: bf9679f3-0de6-11d0-a285-00aa003049e2
-systemOnly: FALSE
-systemFlags: 16
-isMemberOfPartialAttributeSet: TRUE
-objectCategory: CN=Attribute-Schema,${SCHEMADN}

Modified: trunk/openchange/setup/AD/oc_provision_schema_modify.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema_modify.ldif	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/setup/AD/oc_provision_schema_modify.ldif	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1,16 +1,19 @@
-# Some of the classes Exchange needs to extend do not exist in
-# Samba4. These classes are added in oc_provision_schema_ADSC.ldif
 #
-#	Classes Added:
-#  	  	* Address-Book-Container
-#		* Contact
-#		* Display-Template
-#		* DSA
-#		* Group-Of-Names
+# ms-Exch-Configuration-Container class: see oc_provision_schema.ldif
 #
-# ms-Exch-Configuraion-Container class: see oc_provision_schema.ldif
-#
 
+dn: CN=Address-Book-Container,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: msExchMinAdminVersion
+mayContain: msExchAddressListOU
+mayContain: msExchSearchScope
+mayContain: msExchSearchBase
+mayContain: msExchEnableInternalEvaluator
+mayContain: msExchPurportedSearchUI
+add: possSuperiors
+possSuperiors: msExchConfigurationContainer
+possSuperiors: container
 
 #
 # Computer class
@@ -46,10 +49,10 @@
 dn: CN=Container,${SCHEMADN}
 changetype: modify
 add: auxiliaryClass
+auxiliaryClass: msExchBaseClass
 add: possSuperiors
+possSuperiors: protocolCfgSharedServer
 add: mayContain
-auxiliaryClass: msExchBaseClass
-possSuperiors: protocolCfgSharedServer
 mayContain: containerInfo
 mayContain: msExchPolicyList
 mayContain: msExchTemplateRDNs
@@ -77,10 +80,10 @@
 dn: CN=Group,${SCHEMADN}
 changetype: modify
 add: auxiliaryClass
-add: mayContain
 auxiliaryClass: msExchCustomAttributes
 auxiliaryClass: msExchBaseClass
 auxiliaryClass: msExchIMRecipient
+add: mayContain
 mayContain: hideDLMembership
 mayContain: oOFReplyToOriginator
 mayContain: reportToOriginator
@@ -193,8 +196,8 @@
 dn: CN=Organizational-Unit,${SCHEMADN}
 changetype: modify
 add: auxiliaryClass
+auxiliaryClass: msExchBaseClass
 add: mayContain
-auxiliaryClass: msExchBaseClass
 mayContain: msExchPolicyList
 
 
@@ -243,8 +246,6 @@
 dn: CN=User,${SCHEMADN}
 changetype: modify
 add: auxiliaryClass
-add: possSuperiors
-add: mayContain
 auxiliaryClass: msExchCustomAttributes
 auxiliaryClass: msExchMailStorage
 auxiliaryClass: msExchBaseClass
@@ -252,7 +253,9 @@
 auxiliaryClass: msExchCertificateInformation
 auxiliaryClass: msExchIMRecipient
 auxiliaryClass: msExchOmaUser
+add: possSuperiors
 possSuperiors: msExchSystemObjectsContainer
+add: mayContain
 mayContain: msExchQueryBaseDN
 mayContain: msExchControllingZone
 mayContain: msExchResourceGUID
@@ -377,8 +380,8 @@
 dn: CN=Garbage-Coll-Period,${SCHEMADN}
 changetype: modify
 add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
 replace: searchFlags
-isMemberOfPartialAttributeSet: TRUE
 searchFlags: 16
 
 
@@ -573,8 +576,8 @@
 dn: CN=Proxy-Addresses,${SCHEMADN}
 changetype: modify
 add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
 replace: searchFlags
-isMemberOfPartialAttributeSet: TRUE
 searchFlags: 13
 
 
@@ -617,10 +620,10 @@
 dn: CN=Text-Encoded-Or-Address,${SCHEMADN}
 changetype: modify
 add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
 replace: searchFlags
+searchFlags: 1
 replace: attributeSecurityGuid
-isMemberOfPartialAttributeSet: TRUE
-searchFlags: 1
 attributeSecurityGuid: e48d0154-bcf8-11d1-8702-00c04fb96050
 
 
@@ -635,8 +638,8 @@
 dn: CN=Title,${SCHEMADN}
 changetype: modify
 add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
 replace: searchFlags
-isMemberOfPartialAttributeSet: TRUE
 searchFlags: 16
 
 

Modified: trunk/openchange/torture/exchange_createuser.c
===================================================================
--- trunk/openchange/torture/exchange_createuser.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/torture/exchange_createuser.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -105,7 +105,7 @@
 	/* open LDAP connection */
 	remote_ldb_url = talloc_asprintf(mem_ctx, "ldap://%s", profile->server);
 	remote_ldb = ldb_wrap_connect(mem_ctx, ev, global_mapi_ctx->lp_ctx, remote_ldb_url, 
-								  NULL, cmdline_credentials, 0, NULL);
+								  NULL, cmdline_credentials, 0);
 	if (!remote_ldb) return NT_STATUS_UNSUCCESSFUL;
 
 	/* search the user's record using the user dom_sid */

Modified: trunk/openchange/torture/mapi_fetchmail.c
===================================================================
--- trunk/openchange/torture/mapi_fetchmail.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/torture/mapi_fetchmail.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -117,7 +117,7 @@
 
 			if (GetLastError() != MAPI_E_NOT_FOUND) {
 			  retval = GetPropsAll(&obj_message, &properties_array);
-			  mapidump_message(&properties_array, NULL);
+			  mapidump_message(&properties_array, NULL, &obj_message);
 			  mapi_object_release(&obj_message);
 			}
 		}

Modified: trunk/openchange/torture/mapi_newmail.c
===================================================================
--- trunk/openchange/torture/mapi_newmail.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/torture/mapi_newmail.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -109,7 +109,7 @@
 	if (retval != MAPI_E_SUCCESS) return false;
 
  	/* wait for notifications */
-	MonitorNotification(mapi_object_get_session(&obj_inbox),(void *)&obj_store);
+	MonitorNotification(mapi_object_get_session(&obj_inbox),(void *)&obj_store, NULL);
 
 	mapi_object_release(&obj_inbox);
 	mapi_object_release(&obj_store);

Modified: trunk/openchange/torture/nspi_profile.c
===================================================================
--- trunk/openchange/torture/nspi_profile.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/torture/nspi_profile.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -148,9 +148,12 @@
 	
 	nspi->mem_ctx = mem_ctx;
 
-	retval = nspi_GetSpecialTable(nspi, 0, &rowset);
+	retval = nspi_GetSpecialTable(nspi, mem_ctx, 0, &rowset);
 	mapi_errstr("NspiGetSpecialTable", GetLastError());
-	if (retval != MAPI_E_SUCCESS) return false;
+	if (retval != MAPI_E_SUCCESS) {
+		talloc_free(mem_ctx);
+		return false;
+	}
 
 	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0xc,
 					  PR_DISPLAY_NAME,
@@ -184,7 +187,7 @@
 
 	rowset = talloc_zero(nspi->mem_ctx, struct SRowSet);
 	MIds = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi, SPropTagArray, &Filter, &rowset, &MIds);
+	retval = nspi_GetMatches(nspi, nspi->mem_ctx, SPropTagArray, &Filter, &rowset, &MIds);
 	MAPIFreeBuffer(lpProp);
 	mapi_errstr("NspiGetMatches", GetLastError());
 	if (retval != MAPI_E_SUCCESS) return false;
@@ -224,9 +227,9 @@
 
 	instance_key = MIds->aulPropTag[0];
 	MIds2.cValues = 0x1;
-	MIds2.aulPropTag = &instance_key;
+	MIds2.aulPropTag = (enum MAPITAGS *) &instance_key;
 
-	retval = nspi_QueryRows(nspi, SPropTagArray, &MIds2, 1, &rowset);
+	retval = nspi_QueryRows(nspi, nspi->mem_ctx, SPropTagArray, &MIds2, 1, &rowset);
 	mapi_errstr("NspiQueryRows", GetLastError());
 	if (retval != MAPI_E_SUCCESS) return false;
 
@@ -250,7 +253,7 @@
 	pNames.Strings[0] = (const char *) talloc_asprintf(nspi->mem_ctx, SERVER_DN, 
 							   nspi->org, nspi->org_unit, 
 							   nspi->servername);
-	retval = nspi_DNToMId(nspi, &pNames, &MId_server);
+	retval = nspi_DNToMId(nspi, nspi->mem_ctx, &pNames, &MId_server);
 	mapi_errstr("NspiDNToMId", GetLastError());
 	MAPIFreeBuffer((char *)pNames.Strings[0]);
 	MAPIFreeBuffer((char **)pNames.Strings);
@@ -258,7 +261,7 @@
 
 	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x2,
 					  PR_EMS_AB_NETWORK_ADDRESS);
-	retval = nspi_GetProps(nspi, SPropTagArray, MId_server, &rowset);
+	retval = nspi_GetProps(nspi, nspi->mem_ctx, SPropTagArray, MId_server, &rowset);
 	mapi_errstr("NspiGetProps", GetLastError());
 	if (retval != MAPI_E_SUCCESS) return false;
 

Added: trunk/openchange/utils/exchange2ical_tool.c
===================================================================
--- trunk/openchange/utils/exchange2ical_tool.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical_tool.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,247 @@
+/*
+   Convert Exchange appointments and meetings to ICAL files
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libexchange2ical/libexchange2ical.h>
+
+static void getRange(const char *range, struct tm *start, struct tm *end)
+{
+	char *startString;
+	char *endString;
+
+	startString = strtok((char *) range, "-");
+	endString = strtok(NULL, "-");
+
+	end->tm_mon	= atoi(strtok(endString, "/"))-1;
+	end->tm_mday	= atoi(strtok(NULL, "/"));
+	end->tm_year	= atoi(strtok(NULL, "/"))-1900;
+	end->tm_min	= 0;
+	end->tm_hour	= 0;
+	end->tm_sec	= 0;
+
+	
+	start->tm_mon	= atoi(strtok(startString, "/"))-1;
+	start->tm_mday	= atoi(strtok(NULL, "/"));
+	start->tm_year	= atoi(strtok(NULL, "/"))-1900;
+	start->tm_min	= 0;
+	start->tm_hour	= 0;
+	start->tm_sec	= 0;
+	
+	return;
+}
+
+static char* read_stream(char *s, size_t size, void *d) 
+{ 
+  char *c = fgets(s, size, (FILE*)d);
+
+  return c;
+}
+
+int main(int argc, const char *argv[])
+{
+	enum MAPISTATUS			retval;
+	poptContext			pc;
+	int				opt;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_folder;
+	const char			*opt_profdb = NULL;
+	const char			*opt_profname = NULL;
+	const char			*opt_password = NULL;
+	const char			*opt_debug = NULL;
+	const char			*opt_filename = NULL;
+	const char			*opt_icalsync = NULL;
+	const char			*opt_range = NULL;
+	bool				opt_dumpdata = false;
+	FILE 	 			*fp = NULL;
+	mapi_id_t			fid;
+	struct mapi_session		*session = NULL;
+	icalcomponent *vcal;
+	struct tm start;
+	struct tm end;
+	icalparser *parser;
+	icalcomponent *ical;
+	icalcomponent *vevent;
+	TALLOC_CTX			*mem_ctx;
+
+	
+
+	enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_DEBUG, OPT_DUMPDATA, OPT_FILENAME, OPT_RANGE, OPT_ICALSYNC };
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{ "database",	'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB,	"set the profile database path",		NULL },
+		{ "profile",	'p', POPT_ARG_STRING, NULL, OPT_PROFILE,	"set the profile name",				NULL },
+		{ "password",	'P', POPT_ARG_STRING, NULL, OPT_PASSWORD,	"set the profile password",			NULL },
+		{ "icalsync", 	'i', POPT_ARG_STRING, NULL, OPT_ICALSYNC,	"set the icalendar to convert to exchange",	NULL },
+		{ "filename",	'o', POPT_ARG_STRING, NULL, OPT_FILENAME,	"set the output iCalendar filename",		NULL },
+		{ "range",	'R', POPT_ARG_STRING, NULL, OPT_RANGE,		"set the range of accepted start dates", 	NULL },
+		{ "debuglevel",	'd', POPT_ARG_STRING, NULL, OPT_DEBUG,		"set the debug level",				NULL },
+		{ "dump-data",	  0, POPT_ARG_NONE,   NULL, OPT_DUMPDATA,	"dump the hex data",				NULL },
+		POPT_OPENCHANGE_VERSION
+		{ NULL,		  0, 0,		      NULL, 0,			NULL,					NULL }
+	};
+
+	
+	pc = poptGetContext("exchange2ical", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_FILENAME:
+			opt_filename = poptGetOptArg(pc);
+			break;
+		case OPT_ICALSYNC:
+			opt_icalsync = poptGetOptArg(pc);
+			break;
+		case OPT_RANGE:
+			opt_range = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			opt_profname = poptGetOptArg(pc);
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		}
+	}
+	
+	mem_ctx = talloc_named(NULL, 0, "exchange2ical_tool");
+
+	/* Sanity Checks */
+	if (!opt_profdb) {
+		opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+	}
+
+	/* Initialize MAPI subsystem */
+	retval = MAPIInitialize(opt_profdb);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		return 1;
+	}
+	
+	/* debug options */
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+	SetMAPIDumpData(opt_dumpdata);
+	
+	session = octool_init_mapi(opt_profname, opt_password, 0);
+	if(!session){
+		mapi_errstr("Session", GetLastError());
+		return 1;
+	}
+
+
+		
+	/* Open Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenMsgStore", GetLastError());
+		return 1;
+	}
+
+	/* Get default calendar folder */
+	retval = GetDefaultFolder(&obj_store, &fid, olFolderCalendar);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("GetDefaultFolder", GetLastError());
+		return 1;
+	}
+	
+	/* Open default calendar folder */
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenFolder", GetLastError());
+		return 1;
+	}
+	
+
+	/*Ical2exchange*/
+	if(opt_icalsync){
+		if ((fp = fopen(opt_icalsync, "r")) == NULL) {
+			perror("Can not open Icalendar file");
+		} else {
+			parser = icalparser_new();
+			icalparser_set_gen_data(parser,fp);
+			ical = icalparser_parse(parser, read_stream);
+			printf("\n\nICAL file:\n%s\n", icalcomponent_as_ical_string(ical));
+
+			icalcomponent_strip_errors(ical);
+		
+			vevent = icalcomponent_get_first_component(ical, ICAL_VEVENT_COMPONENT);
+			while(vevent){
+				_IcalEvent2Exchange(&obj_folder, vevent);
+				vevent = icalcomponent_get_next_component(ical, ICAL_VEVENT_COMPONENT);
+			}	
+			icalcomponent_free(ical);
+			icalparser_free(parser);
+			fclose(fp);
+			fp = NULL;
+		}
+	}
+	
+	if(opt_range){
+		getRange(opt_range, &start, &end);
+		vcal = Exchange2IcalRange(&obj_folder, &start, &end);
+	} else {
+		vcal = Exchange2Ical(&obj_folder);
+	}
+
+
+	if(vcal){				
+		/* Icalendar save or print to console */
+		char *cal = icalcomponent_as_ical_string(vcal);
+		if (!opt_filename) {
+			printf("\n\nICAL file:\n%s\n", cal);
+		} else {
+			size_t bytesWritten;
+			
+			if ((fp = fopen(opt_filename, "w")) == NULL) {
+				perror("fopen");
+				exit (1);
+			}
+			bytesWritten = fwrite(cal, strlen(cal), 1, fp);
+			if (bytesWritten < 1) {
+				printf("BOGUS write length: %zi", bytesWritten);
+			}
+			fclose(fp);
+		}
+		free(cal);
+		icalcomponent_free(vcal);
+	}
+	poptFreeContext(pc);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+	MAPIUninitialize();
+	talloc_free(mem_ctx);	
+
+	return 0;
+}
+
+

Modified: trunk/openchange/utils/exchange2mbox.c
===================================================================
--- trunk/openchange/utils/exchange2mbox.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/exchange2mbox.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -123,7 +123,9 @@
 	struct mapi_profile	profile;
 	size_t			read_size;
 	char			*line = NULL;
+#if !defined(__FreeBSD__)
 	ssize_t			size;
+#endif
 	const char		*msgid;
 	char     		*id;
 	char			**mbox_msgids;

Modified: trunk/openchange/utils/mapiprofile.c
===================================================================
--- trunk/openchange/utils/mapiprofile.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapiprofile.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -31,7 +31,6 @@
 
 #define	DEFAULT_DIR	"%s/.openchange"
 #define	DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
-#define	DEFAULT_LCID	"0x409" /* language code ID: en-US */
 
 static bool mapiprofile_createdb(const char *profdb, const char *ldif_path)
 {
@@ -103,15 +102,20 @@
 static bool mapiprofile_create(const char *profdb, const char *profname,
 			       const char *pattern, const char *username, 
 			       const char *password, const char *address, 
-			       const char *lcid, const char *workstation,
+			       const char *language, const char *workstation,
 			       const char *domain, const char *realm,
-			       uint32_t flags,
+			       uint32_t flags, bool seal,
 			       bool opt_dumpdata, const char *opt_debuglevel)
 {
 	enum MAPISTATUS		retval;
 	struct mapi_session	*session = NULL;
 	TALLOC_CTX		*mem_ctx;
 	struct mapi_profile	profile;
+	const char		*locale;
+	uint32_t		cpid;
+	uint32_t		lcid;
+	char			*cpid_str;
+	char			*lcid_str;
 
 	mem_ctx = talloc_named(NULL, 0, "mapiprofile_create");
 
@@ -120,6 +124,8 @@
 
 #if defined (__FreeBSD__)
 	(void) signal(SIGINT, (sig_t) signal_delete_profile);
+#elif defined (__SunOS)
+        (void) signal(SIGINT, signal_delete_profile);
 #else
 	(void) signal(SIGINT, (sighandler_t) signal_delete_profile);
 #endif
@@ -157,28 +163,39 @@
 	mapi_profile_add_string_attr(profname, "binding", address);
 	mapi_profile_add_string_attr(profname, "workstation", workstation);
 	mapi_profile_add_string_attr(profname, "domain", domain);
+	mapi_profile_add_string_attr(profname, "seal", (seal == true) ? "true" : "false");
 
 	if (realm) {
 		mapi_profile_add_string_attr(profname, "realm", realm);
 	}
 
-	if (strncmp(lcid, "0x", 2) != 0) {
-		/* it doesn't look like a hex id, so try to convert it from
-		   a string name (like "English_Australian" to a language code
-		   ID string (like "0x0c09")
-		*/
-		lcid = talloc_asprintf(mem_ctx, "0x%04x", lcid_lang2lcid(lcid));
+	locale = (const char *) (language) ? mapi_get_locale_from_language(language) : mapi_get_system_locale();
+
+	if (locale) {
+		cpid = mapi_get_cpid_from_locale(locale);
+		lcid = mapi_get_lcid_from_locale(locale);
 	}
-	if (!lcid_valid_locale(strtoul(lcid, 0, 16))) {
-		lcid = DEFAULT_LCID;
-		printf("Language code not recognised, using default (%s) instead\n", lcid);
+
+	if (!locale || !cpid || !lcid) {
+		printf("Invalid Language supplied or unknown system language '%s\n'", language);
+		printf("Deleting profile\n");
+		if ((retval = DeleteProfile(profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("DeleteProfile", GetLastError());
+		}
+		talloc_free(mem_ctx);
+		return false;
 	}
 
-	/* This is only convenient here and should be replaced at some point */
-	mapi_profile_add_string_attr(profname, "codepage", "0x4e4");
-	mapi_profile_add_string_attr(profname, "language", lcid );
-	mapi_profile_add_string_attr(profname, "method", "0x409");
+	cpid_str = talloc_asprintf(mem_ctx, "%d", cpid);
+	lcid_str = talloc_asprintf(mem_ctx, "0x%.4x", lcid);
 
+	mapi_profile_add_string_attr(profname, "codepage", cpid_str);
+	mapi_profile_add_string_attr(profname, "language", lcid_str);
+	mapi_profile_add_string_attr(profname, "method", lcid_str);
+
+	talloc_free(cpid_str);
+	talloc_free(lcid_str);
+
 	retval = MapiLogonProvider(&session, profname, password, PROVIDER_ID_NSPI);
 	if (retval != MAPI_E_SUCCESS) {
 		mapi_errstr("MapiLogonProvider", GetLastError());
@@ -516,6 +533,7 @@
 	bool		getdflt = false;
 	bool		getfqdn = false;
 	bool		opt_dumpdata = false;
+	bool		opt_seal = false;
 	const char	*opt_debuglevel = NULL;
 	const char	*ldif = NULL;
 	const char	*address = NULL;
@@ -523,7 +541,7 @@
 	const char	*domain = NULL;
 	const char	*realm = NULL;
 	const char	*username = NULL;
-	const char      *lcid = NULL;
+	const char      *language = NULL;
 	const char	*pattern = NULL;
 	const char	*password = NULL;
 	const char	*profdb = NULL;
@@ -536,11 +554,12 @@
 	int		retcode = EXIT_SUCCESS;
 
 	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_ADDRESS, OPT_WORKSTATION,
-	      OPT_DOMAIN, OPT_REALM, OPT_USERNAME, OPT_LCID, OPT_PASSWORD, 
+	      OPT_DOMAIN, OPT_REALM, OPT_USERNAME, OPT_LANGUAGE, OPT_PASSWORD, 
 	      OPT_CREATE_PROFILE, OPT_DELETE_PROFILE, OPT_LIST_PROFILE, OPT_DUMP_PROFILE, 
 	      OPT_DUMP_ATTR, OPT_PROFILE_NEWDB, OPT_PROFILE_LDIF, OPT_LIST_LANGS,
 	      OPT_PROFILE_SET_DFLT, OPT_PROFILE_GET_DFLT, OPT_PATTERN, OPT_GETFQDN,
-	      OPT_NOPASS, OPT_RENAME_PROFILE, OPT_DUMPDATA, OPT_DEBUGLEVEL};
+	      OPT_NOPASS, OPT_RENAME_PROFILE, OPT_DUMPDATA, OPT_DEBUGLEVEL,
+	      OPT_ENCRYPT_CONN};
 
 	struct poptOption long_options[] = {
 		POPT_AUTOHELP
@@ -554,8 +573,9 @@
 		{"workstation", 'M', POPT_ARG_STRING, NULL, OPT_WORKSTATION, "set the workstation", "WORKSTATION_NAME"},
 		{"domain", 'D', POPT_ARG_STRING, NULL, OPT_DOMAIN, "set the domain/workgroup", "DOMAIN"},
 		{"realm", 'R', POPT_ARG_STRING, NULL, OPT_REALM, "set the realm", "REALM"},
+		{"encrypt", 'E', POPT_ARG_NONE, NULL, OPT_ENCRYPT_CONN, "enable encryption with Exchange server", NULL },
 		{"username", 'u', POPT_ARG_STRING, NULL, OPT_USERNAME, "set the profile username", "USERNAME"},
-		{"langcode", 'C', POPT_ARG_STRING, NULL, OPT_LCID, "set the language code ID", "LANGCODE"},
+		{"language", 'C', POPT_ARG_STRING, NULL, OPT_LANGUAGE, "set the user's language (if different from system one)", "LANGUAGE"},
 		{"pattern", 's', POPT_ARG_STRING, NULL, OPT_PATTERN, "username to search for", "USERNAME"},
 		{"password", 'p', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"},
 		{"nopass", 0, POPT_ARG_NONE, NULL, OPT_NOPASS, "do not save password in the profile", NULL},
@@ -624,12 +644,15 @@
 		case OPT_REALM:
 			realm = poptGetOptArg(pc);
 			break;
+		case OPT_ENCRYPT_CONN:
+			opt_seal = true;
+			break;
 		case OPT_USERNAME:
 			username = poptGetOptArg(pc);
 			break;
-		case OPT_LCID:
+		case OPT_LANGUAGE:
 			opt_tmp = poptGetOptArg(pc);
-			lcid = talloc_strdup(mem_ctx, opt_tmp);
+			language = talloc_strdup(mem_ctx, opt_tmp);
 			free((void*)opt_tmp);
 			opt_tmp = NULL;
 			break;
@@ -717,12 +740,9 @@
 		if (!address) show_help(pc, "address");
 		if (!domain) show_help(pc, "domain");
 
-		if (!lcid) {
-		  lcid = talloc_strdup(mem_ctx, DEFAULT_LCID);
-		}
 		if (! mapiprofile_create(profdb, profname, pattern, username, password, address,
-					 lcid, workstation, domain, realm, nopass, opt_dumpdata,
-					 opt_debuglevel) ) {
+					 language, workstation, domain, realm, nopass, opt_seal, 
+					 opt_dumpdata, opt_debuglevel) ) {
 			retcode = EXIT_FAILURE;
 			goto cleanup;
 		}
@@ -737,7 +757,7 @@
 	}
 
 	if (listlangs == true) {
-		lcid_print_languages();
+		mapidump_languages_list();
 	}
 
 	if (setdflt == true) {

Modified: trunk/openchange/utils/mapitest/mapitest.h
===================================================================
--- trunk/openchange/utils/mapitest/mapitest.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/mapitest.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -31,14 +31,30 @@
 struct mapitest;
 struct mapitest_suite;
 
-#include "utils/mapitest/proto.h"
 
 /**
 	\file mapitest.h
- 	Data structures for %mapitest
+	Data structures for %mapitest
  */
 
 /**
+  Flags for changing test applicability
+  
+  If you add values here, you also need to add a matching description to
+  applicabilityFlagsDescription and suitable logic to
+  mapitest_suite_test_is_applicable().
+*/
+enum TestApplicabilityFlags {
+	ApplicableToAllVersions = 0,	/*!< This test is always applicable */
+	NotInExchange2010 = 0x1,	/*!< This test is not applicable to Exchange 2010 */
+	LastTestApplicabilityFlag = 0xFFFF
+};
+
+
+
+#include "utils/mapitest/proto.h"
+
+/**
 	A list of %mapitest tests
 
 	%mapitest tests are grouped into test suites. This linked
@@ -49,11 +65,12 @@
 	fn element (i.e. fn is a function pointer).
 */
 struct mapitest_test {
-	struct mapitest_test	*prev;		/*!< The previous test in the list */
-	struct mapitest_test	*next;		/*!< The next test in the list */
-	char			*name;		/*!< The name of this test */
-	char			*description;	/*!< The description of this test */
-	void			*fn;		/*!< pointer to the test function */
+	struct mapitest_test		*prev;		/*!< The previous test in the list */
+	struct mapitest_test		*next;		/*!< The next test in the list */
+	char				*name;		/*!< The name of this test */
+	char				*description;	/*!< The description of this test */
+	void				*fn;		/*!< pointer to the test function */
+	enum TestApplicabilityFlags	flags;		/*!< any applicability for this test */
 };
 
 /**
@@ -66,6 +83,7 @@
 	struct mapitest_unit	*prev;		/*!< The previous test in the list */
 	struct mapitest_unit	*next;		/*!< The next test in the list */
 	char			*name;		/*!< The name of the test */
+	char			*reason;	/*!< Why this test was skipped (if applicable) */
 };
 
 /**
@@ -80,7 +98,9 @@
 struct mapitest_stat {
 	uint32_t		success;       /*!< Number of tests in this suite that passed */
 	uint32_t		failure;       /*!< Number of tests in this suite that failed */
+	uint32_t		skipped;       /*!< Number of tests in this suite that were skipped */
 	struct mapitest_unit	*failure_info; /*!< List of names of the tests that failed */
+	struct mapitest_unit	*skip_info;    /*!< List of names of the tests that were skipped, and why */
 	bool			enabled;       /*!< Whether this statistics structure is valid */
 };
 
@@ -160,7 +180,7 @@
 #define	MT_HDR_FMT_DATE		"[*] %-25s: %-20s"
 #define	MT_HDR_FMT_SECTION	"[*] %-25s:\n"
 #define	MT_HDR_FMT_SUBSECTION	"%-21s: %-10s\n"
-#define	MT_HDR_FMT_STORE_VER	"%-21s: %d.%d.%d\n"
+#define	MT_HDR_FMT_VER_NORM	"%-21s: %02d.%02d.%04d.%04d\n"
 
 #define	MT_DIRNAME_TOP		"[MT] Top of Mailbox"
 #define	MT_DIRNAME_APPOINTMENT	"[MT] Calendar"
@@ -192,8 +212,10 @@
 
 #define	MT_ERROR       	"[ERROR]: %s\n"
 
-#define	MT_STAT_TITLE	"[STAT] FAILURE REPORT\n"
+#define	MT_STAT_FAILED_TITLE	"[STAT] FAILED TEST CASES\n"
 #define	MT_STAT_FAILURE	"* %-35s: %s\n"
+#define	MT_STAT_SKIPPED_TITLE	"[STAT] SKIPPED TEST CASES\n"
+#define	MT_STAT_SKIPPED	"* %-35s: %s (%s)\n"
 
 #define MT_SUMMARY_TITLE "[STAT] TEST SUMMARY\n"
 
@@ -201,4 +223,6 @@
 #define MT_RED             "\033[1;31m"
 #define MT_GREEN           "\033[1;32m"
 
+#define Exchange2010Version	0x0E00
+
 #endif /* !__MAPITEST_H__ */

Modified: trunk/openchange/utils/mapitest/mapitest_common.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_common.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/mapitest_common.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -119,13 +119,13 @@
 					  PR_SUBJECT);
 	retval = SetColumns(&obj_ctable, SPropTagArray);
 	MAPIFreeBuffer(SPropTagArray);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	if (retval != MAPI_E_SUCCESS) {
 		mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetColumns", GetLastError());
 		mapi_object_release(&obj_ctable);
 		return false;
 	}
 
-	while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) {
+	while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && !retval && SRowSet.cRows) {
 		for (i = 0; i < SRowSet.cRows; i++) {
 			if (retval == MAPI_E_SUCCESS) {
 				msgids[0] = SRowSet.aRow[i].lpProps[0].value.d;
@@ -158,8 +158,7 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		rowset;
 	mapi_object_t		obj_htable;
-	const char		*tmp;
-	char			*newname;
+	const char		*newname;
 	const uint64_t		*fid;
 	uint32_t		count;
 	uint32_t		index;
@@ -184,16 +183,13 @@
 	while (((retval = QueryRows(&obj_htable, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) {
 		for (index = 0; index < rowset.cRows; index++) {
 			fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID);
-			tmp = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
+			newname = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
 
-			newname = windows_to_utf8(mt->mem_ctx, tmp);
 			if (newname && fid && !strcmp(newname, name)) {
 				retval = OpenFolder(obj_parent, *fid, obj_child);
 				mapi_object_release(&obj_htable);
-				MAPIFreeBuffer(newname);
 				return true;
 			}
-			MAPIFreeBuffer(newname);
 		}
 	}
 
@@ -212,7 +208,7 @@
 {
 	enum MAPISTATUS		retval;
 
-	/* Create the mesage */
+	/* Create the message */
 	retval = CreateMessage(obj_folder, obj_message);
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateMessage", GetLastError());
@@ -245,13 +241,17 @@
 	if (subject == NULL) return false;
 
 	/* Resolve recipients */
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_OBJECT_TYPE,
 					  PR_DISPLAY_TYPE,
-					  PR_7BIT_DISPLAY_NAME,
-					  PR_DISPLAY_NAME,
-					  PR_SMTP_ADDRESS,
-					  PR_GIVEN_NAME);
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_SEND_RICH_INFO,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
 
 	username[0] = (const char *)mt->info.szDisplayName;
 	username[1] = NULL;
@@ -260,7 +260,7 @@
 	flaglist = talloc_zero(mt->mem_ctx, struct SPropTagArray);
 
 	retval = ResolveNames(mapi_object_get_session(obj_message), username, SPropTagArray, 
-			      &SRowSet, &flaglist, 0);
+			      &SRowSet, &flaglist, MAPI_UNICODE);
 	MAPIFreeBuffer(SPropTagArray);
 	if (retval != MAPI_E_SUCCESS) {
 		mapitest_print(mt, "* %-35s: 0x%.8x\n", "ResolveNames", GetLastError());
@@ -454,11 +454,11 @@
    Convenience function to login to the server
 
    This functions logs into the server, gets the top level store, and
-   gets the hierachy table for the top level store (which is returned as
+   gets the hierarchy table for the top level store (which is returned as
    obj_htable). It also creates a test folder with 10 test messages.
 
    \param mt pointer to the top-level mapitest structure
-   \param obj_htable the hierachy table for the top level store
+   \param obj_htable the hierarchy table for the top level store
    \param count the number of rows in the top level hierarchy table
 
    \return true on success, otherwise false
@@ -486,7 +486,7 @@
 		return false;
 	}
 
-	/* We do this before getting the hierachy table, because otherwise the new
+	/* We do this before getting the hierarchy table, because otherwise the new
 	   test folder will be omitted, and the count will be wrong */
 	ret = mapitest_common_create_filled_test_folder(mt);
 	if (ret == false) {
@@ -513,6 +513,7 @@
 _PUBLIC_ void mapitest_common_cleanup(struct mapitest *mt)
 {
 	struct mt_common_tf_ctx	*context;
+	enum MAPISTATUS		retval;
 	int			i;
 
 	context = mt->priv;
@@ -521,14 +522,14 @@
 		mapi_object_release(&(context->obj_test_msg[i]));
 	}
 
-	EmptyFolder(&(context->obj_test_folder));
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	retval = EmptyFolder(&(context->obj_test_folder));
+	if (retval != MAPI_E_SUCCESS) {
 		mapitest_print(mt, "* %-35s: 0x%.8x\n", "Empty test folder", GetLastError());
 	}
 
-	DeleteFolder(&(context->obj_top_folder), mapi_object_get_id(&(context->obj_test_folder)),
-		     DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
-	if (GetLastError() != MAPI_E_SUCCESS) {
+	retval = DeleteFolder(&(context->obj_top_folder), mapi_object_get_id(&(context->obj_test_folder)),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	if (retval != MAPI_E_SUCCESS) {
 		mapitest_print(mt, "* %-35s: 0x%.8x\n", "Delete test folder", GetLastError());
 	}
 

Modified: trunk/openchange/utils/mapitest/mapitest_print.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_print.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/mapitest_print.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -273,7 +273,40 @@
 	mapitest_deindent();
 }
 
+/**
+  \details Print out a normalized version number for a client or server.
+  
+  \param mt pointer to the top level mapitest structure
+  \param label label for the version (e.g. "Store Version" or "Client Version")
+  \param word0 highest order word for the version
+  \param word1 middle word for the version
+  \param word2 low word for the version
+*/
+static void mapitest_print_version_normalised(struct mapitest *mt, const char* label,
+					      const uint16_t word0, const uint16_t word1, const uint16_t word2)
+{
+	/* See MS-OXRPC Section 3.1.9 to understand this */
+	uint16_t normalisedword0;
+	uint16_t normalisedword1;
+	uint16_t normalisedword2;
+	uint16_t normalisedword3;
 
+	if (word1 & 0x8000) {
+		/* new format */
+		normalisedword0 = (word0 & 0xFF00) >> 8;
+		normalisedword1 = (word0 & 0x00FF);
+		normalisedword2 = (word1 & 0x7FFF);
+		normalisedword3 = word2;
+	} else {
+		normalisedword0 = word0;
+		normalisedword1 = 0;
+		normalisedword2 = word1;
+		normalisedword3 = word2;
+	}
+	mapitest_print(mt, MT_HDR_FMT_VER_NORM, label, normalisedword0,
+		       normalisedword1, normalisedword2, normalisedword3);
+}
+
 /**
    \details Print a report of the Exchange server and account information
 
@@ -288,10 +321,10 @@
 	mapitest_print_newline(mt, 1);
 	mapitest_print(mt, MT_HDR_FMT_SECTION, "Exchange Server");
 	mapitest_indent();
-	mapitest_print(mt, MT_HDR_FMT_STORE_VER, "Store version",
-		       mt->info.rgwServerVersion[0],
-		       mt->info.rgwServerVersion[1],
-		       mt->info.rgwServerVersion[2]);
+	mapitest_print_version_normalised(mt, "Store Version",
+					  mt->info.rgwServerVersion[0],
+					  mt->info.rgwServerVersion[1],
+					  mt->info.rgwServerVersion[2]);
 	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Username",
 		       (mt->confidential == true) ? MT_CONFIDENTIAL : mt->info.szDisplayName);
 	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Organization",

Modified: trunk/openchange/utils/mapitest/mapitest_stat.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_stat.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/mapitest_stat.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -31,6 +31,18 @@
 */
 
 /**
+  Descriptions of TestApplicabilityFlags
+*/
+struct TestApplicabilityDescription {
+	enum TestApplicabilityFlags	flags;		/*!< The flag value */
+	char*				description;	/*!< A user-visible string equivalent */
+} applicabilityFlagsDescription[] = {
+	{ ApplicableToAllVersions, 	"Applicable to all server versions" },
+	{ NotInExchange2010, 		"Not applicable to Exchange 2010" },
+	{ LastTestApplicabilityFlag,	"Sentinel Value" }
+};
+
+/**
    \details Initialize the mapitest statistic structure
    
    \param mem_ctx memory allocation context
@@ -47,7 +59,9 @@
 	stat = talloc_zero(mem_ctx, struct mapitest_stat);
 	stat->success = 0;
 	stat->failure = 0;
+	stat->skipped = 0;
 	stat->failure_info = NULL;
+	stat->skip_info = NULL;
 	stat->enabled = false;
 
 	return stat;
@@ -78,6 +92,7 @@
 		suite->stat->failure++;
 		el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit);
 		el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name);
+		el->reason = 0;
 		DLIST_ADD_END(suite->stat->failure_info, el, struct mapitest_unit *);
 	}
 
@@ -86,8 +101,53 @@
 	return MAPITEST_SUCCESS;
 }
 
+static void mapitest_stat_add_skipped_test_reason(struct mapitest_unit *stat_unit, enum TestApplicabilityFlags flags)
+{
+	int i;
+	for (i = 0; applicabilityFlagsDescription[i].flags != LastTestApplicabilityFlag; ++i) {
+		if (flags & applicabilityFlagsDescription[i].flags) {
+			if (!stat_unit->reason) {
+				stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, applicabilityFlagsDescription[i].description);
+			} else {
+				stat_unit->reason = talloc_asprintf_append(stat_unit->reason, ", %s", applicabilityFlagsDescription[i].description);
+			}
+		}
+	}
+	if (!stat_unit->reason) {
+		stat_unit->reason = talloc_strdup((TALLOC_CTX *)stat_unit, "Unknown reason");
+	}
+}
 
 /**
+   \details Add a skipped test to the suite statistic parameters
+
+   \param suite the suite container
+   \param name the test name
+   \param flags flags to indicate the reason why the test was skipped
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t mapitest_stat_add_skipped_test(struct mapitest_suite *suite,
+						 const char *name,
+						 enum TestApplicabilityFlags flags)
+{
+	struct mapitest_unit	*el = NULL;
+
+	/* Sanity check */
+	if (!suite || !suite->stat || !name) return MAPITEST_ERROR;
+
+	suite->stat->skipped++;
+	el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit);
+	el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name);
+	mapitest_stat_add_skipped_test_reason(el, flags);
+	DLIST_ADD_END(suite->stat->skip_info, el, struct mapitest_unit *);
+
+	suite->stat->enabled = true;
+
+	return MAPITEST_SUCCESS;
+}
+
+/**
    \details Dump mapitest statistics about test failures
 
    \param mt the global mapitest structure
@@ -100,9 +160,24 @@
 	struct mapitest_unit	*el;
 	int32_t 		num_passed_tests = 0;
 	int32_t 		num_failed_tests = 0;
+	int32_t 		num_skipped_tests = 0;
 
-	mapitest_print_title(mt, MT_STAT_TITLE, MODULE_TITLE_DELIM);
+	mapitest_print_title(mt, MT_STAT_SKIPPED_TITLE, MODULE_TITLE_DELIM);
+	for (suite = mt->mapi_suite; suite; suite = suite->next) {
+		if (suite->stat->enabled == true) {
+			num_skipped_tests += suite->stat->skipped;
+			if (suite->stat->skipped) {
+				for (el = suite->stat->skip_info; el; el = el->next) {
+					mapitest_print(mt, MT_STAT_SKIPPED, suite->name, el->name, el->reason);
+				}
+			}
+		}
+	}
 
+	mapitest_print_test_title_end(mt);
+
+	mapitest_print_title(mt, MT_STAT_FAILED_TITLE, MODULE_TITLE_DELIM);
+
 	for (suite = mt->mapi_suite; suite; suite = suite->next) {
 		if (suite->stat->enabled == true) {
 			num_passed_tests += suite->stat->success;
@@ -120,6 +195,7 @@
 	mapitest_print_title(mt, MT_SUMMARY_TITLE, MODULE_TITLE_DELIM);
 	mapitest_print(mt, "Number of passing tests: %i\n", num_passed_tests);
 	mapitest_print(mt, "Number of failing tests: %i\n", num_failed_tests);
+	mapitest_print(mt, "Number of skipped tests: %i\n", num_skipped_tests);
 	mapitest_print_test_title_end(mt);
 
 	return num_failed_tests;

Modified: trunk/openchange/utils/mapitest/mapitest_suite.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_suite.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/mapitest_suite.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -98,7 +98,6 @@
 	return MAPITEST_SUCCESS;
 }
 
-
 /**
    \details add a test to the mapitest suite with description
 
@@ -110,11 +109,37 @@
    \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
    
    \sa mapitest_suite_init, mapitest_suite_register
+   \sa mapitest_suite_add_test_flagged for an alternative function allowing the
+   test to only be run under some conditions.
 */
 _PUBLIC_ uint32_t mapitest_suite_add_test(struct mapitest_suite *suite,
 					  const char *name, const char *description,
 					  bool (*run) (struct mapitest *test))
 {
+	return mapitest_suite_add_test_flagged(suite, name, description, run, ApplicableToAllVersions);
+}
+
+/**
+   \details add a test to the mapitest suite with description and flags
+
+   This is very similar to mapitest_suite_add_test(), except it allows a test to have
+   special applicability (e.g. to only run when a particular server configuration is available).
+   
+   \param suite pointer to the parent test suite
+   \param name the test name
+   \param description the test description
+   \param run the test function
+   \param applicability a set of applicability flags
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+   
+   \sa mapitest_suite_init, mapitest_suite_register, mapitest_suite_add_test
+*/
+_PUBLIC_ uint32_t mapitest_suite_add_test_flagged(struct mapitest_suite *suite,
+						  const char *name, const char *description,
+						  bool (*run) (struct mapitest *test),
+						  enum TestApplicabilityFlags applicability)
+{
 	struct mapitest_test	*el = NULL;
 
 	/* Sanity check */
@@ -131,6 +156,7 @@
 	el->name = talloc_asprintf((TALLOC_CTX *)suite, "%s-%s", suite->name, name);
 	el->description = talloc_strdup((TALLOC_CTX *)suite, description);
 	el->fn = run;
+	el->flags = applicability;
 
 	DLIST_ADD_END(suite->tests, el, struct mapitest_test *);
 
@@ -162,7 +188,24 @@
 	return NULL;
 }
 
+/**
+   \details test whether a particular test is applicable
 
+   \param mt pointer to the top-level mapitest structure
+   \param el the test to check
+   
+   \return true if the test should be run, otherwise false
+*/
+static bool mapitest_suite_test_is_applicable(struct mapitest *mt, struct mapitest_test *test)
+{
+	uint16_t actualServerVer = mt->info.rgwServerVersion[0];
+
+	if ((test->flags & NotInExchange2010) && (actualServerVer >= Exchange2010Version)) {
+		return false;
+	}
+	return true;
+}
+
 /**
    \details run a test from a suite given its name
    
@@ -183,6 +226,10 @@
 	if (!suite || !name) return false;
 
 	for (el = suite->tests; el; el = el->next) {
+		if (!mapitest_suite_test_is_applicable(mt, el)) {
+			mapitest_stat_add_skipped_test(suite, el->name, el->flags);
+			return true;
+		}
 		if (!strcmp(el->name, name)) {
 			errno = 0;
 			mapitest_print_test_title_start(mt, el->name);
@@ -235,8 +282,13 @@
 
 		if (suite) {
 			for (el = suite->tests; el; el = el->next) {
-				mapitest_suite_run_test(mt, suite, el->name);
-				ret = true;
+				if (mapitest_suite_test_is_applicable(mt, el)) {
+					mapitest_suite_run_test(mt, suite, el->name);
+					ret = true;
+				} else {
+					printf("test is not applicable: %s\n", el->name);
+					return true;
+				}
 			}
 		}
 	}
@@ -309,15 +361,19 @@
 			mapitest_print_module_title_start(mt, suite->name);
 
 			for (el = suite->tests; el; el = el->next) {
-				errno = 0;
-				mapitest_print_test_title_start(mt, el->name);
-				
-				fn = el->fn;
-				ret = fn(mt);
-				
-				mapitest_stat_add_result(suite, el->name, ret);
-				mapitest_print_test_title_end(mt);
-				mapitest_print_test_result(mt, el->name, ret);
+				if (!mapitest_suite_test_is_applicable(mt, el)) {
+					mapitest_stat_add_skipped_test(suite, el->name, el->flags);
+				} else {
+					errno = 0;
+					mapitest_print_test_title_start(mt, el->name);
+					
+					fn = el->fn;
+					ret = fn(mt);
+					
+					mapitest_stat_add_result(suite, el->name, ret);
+					mapitest_print_test_title_end(mt);
+					mapitest_print_test_result(mt, el->name, ret);
+				}
 			}
 
 			mapitest_print_module_title_end(mt);

Modified: trunk/openchange/utils/mapitest/module.c
===================================================================
--- trunk/openchange/utils/mapitest/module.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/module.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -40,6 +40,7 @@
 	ret += module_noserver_init(mt);
 	ret += module_errorchecks_init(mt);
 	ret += module_lcid_init(mt);
+	ret += module_mapidump_init(mt);
 
 	return ret;
 }
@@ -65,7 +66,8 @@
 	mapitest_suite_add_test(suite, "PUBLICFOLDER-ISGHOSTED", "Determine if a public folder is ghosted", mapitest_oxcstor_PublicFolderIsGhosted);
 	mapitest_suite_add_test(suite, "GETOWNINGSERVERS", "Get the list of servers that host replicas of a given public folder", mapitest_oxcstor_GetOwningServers);
 	mapitest_suite_add_test(suite, "LONGTERMID", "Map to / from a Long Term ID", mapitest_oxcstor_LongTermId);
-	mapitest_suite_add_test(suite, "GETSTORESTATE", "Retrieve the store state", mapitest_oxcstor_GetStoreState);
+	mapitest_suite_add_test_flagged(suite, "GETSTORESTATE", "Retrieve the store state", mapitest_oxcstor_GetStoreState, NotInExchange2010);
+	mapitest_suite_add_test(suite, "ISMAILBOXFOLDER", "Get the standard folder for a given folder ID", mapitest_oxcstor_IsMailboxFolder);
 
 	mapitest_suite_register(mt, suite);
 	
@@ -218,7 +220,7 @@
 	mapitest_suite_add_test(suite, "STREAM", "Test stream operations", mapitest_oxcprpt_Stream);
 	mapitest_suite_add_test(suite, "COPYTO", "Copy or move properties", mapitest_oxcprpt_CopyTo);
 	mapitest_suite_add_test(suite, "WRITE-COMMIT-STREAM", "Test atomic Write / Commit operation", mapitest_oxcprpt_WriteAndCommitStream);
-	mapitest_suite_add_test(suite, "COPYTO-STREAM", "Copy stream from source to desination stream", mapitest_oxcprpt_CopyToStream);
+	mapitest_suite_add_test(suite, "COPYTO-STREAM", "Copy stream from source to destination stream", mapitest_oxcprpt_CopyToStream);
 	mapitest_suite_add_test(suite, "NAME-ID", "Convert between Names and IDs", mapitest_oxcprpt_NameId);
 
 	mapitest_suite_register(mt, suite);
@@ -320,6 +322,7 @@
 	mapitest_suite_add_test(suite, "GETNAMESFROMIDS", "Returns a list of property names for a set of proptags", mapitest_nspi_GetNamesFromIDs);
 	mapitest_suite_add_test(suite, "GETIDSFROMNAMES", "Returns the property IDs associated with property names", mapitest_nspi_GetIDsFromNames);
 	mapitest_suite_add_test(suite, "RESOLVENAMES", "Resolve usernames", mapitest_nspi_ResolveNames);
+	mapitest_suite_add_test(suite, "GETGALTABLE", "Fetches the Global Address List", mapitest_nspi_GetGALTable);
 
 	mapitest_suite_register(mt, suite);
 
@@ -344,6 +347,7 @@
 	mapitest_suite_add_test(suite, "SROWSET", "Test SRowSet parsing", mapitest_noserver_srowset);
 	mapitest_suite_add_test(suite, "GETSETPROPS", "Test Property handling", mapitest_noserver_properties);
 	mapitest_suite_add_test(suite, "MAPIPROPS", "Test MAPI Property handling", mapitest_noserver_mapi_properties);
+	mapitest_suite_add_test(suite, "PROPTAGVALUE", "Test MAPI PropTag value handling", mapitest_noserver_proptagvalue);
 
 	mapitest_suite_register(mt, suite);
 
@@ -389,3 +393,42 @@
 
 	return MAPITEST_SUCCESS;
 }
+
+/**
+   \details Initialise the mapidump test suite
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_mapidump_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "MAPIDUMP", "mapidump test suite", false);
+
+	mapitest_suite_add_test(suite, "SPROPVALUE", "Test dump of SPropValue", mapitest_mapidump_spropvalue);
+	mapitest_suite_add_test(suite, "SPROPTAGARRAY", "Test dump of SPropTagArray", mapitest_mapidump_sproptagarray);
+	mapitest_suite_add_test(suite, "SROWSET", "Test dump of SRowSet", mapitest_mapidump_srowset);
+	mapitest_suite_add_test(suite, "PABENTRY", "Test dump of PAB Entry", mapitest_mapidump_pabentry);
+	mapitest_suite_add_test(suite, "NOTE", "Test dump of a note message", mapitest_mapidump_note);
+	mapitest_suite_add_test(suite, "TASK", "Test dump of a task message", mapitest_mapidump_task);
+	mapitest_suite_add_test(suite, "CONTACT", "Test dump of a contact message", mapitest_mapidump_contact);
+	mapitest_suite_add_test(suite, "APPOINTMENT", "Test dump of an appointment message", mapitest_mapidump_appointment);
+	mapitest_suite_add_test(suite, "MESSAGE", "Test dump of an email message", mapitest_mapidump_message);
+	mapitest_suite_add_test(suite, "NEWMAIL", "Test dump of a new mail notification", mapitest_mapidump_newmail);
+	mapitest_suite_add_test(suite, "FREEBUSY", "Test dump of a free/busy event", mapitest_mapidump_freebusy);
+	mapitest_suite_add_test(suite, "RECIPIENTS", "Test dump of a free/busy event", mapitest_mapidump_recipients);
+	mapitest_suite_add_test(suite, "FOLDERCREATEDNOTIF", "Test dump of a folder created notification", mapitest_mapidump_foldercreated);
+	mapitest_suite_add_test(suite, "FOLDERDELETEDNOTIF", "Test dump of a folder deleted notification", mapitest_mapidump_folderdeleted);
+	mapitest_suite_add_test(suite, "FOLDERMOVEDNOTIF", "Test dump of a folder move notification", mapitest_mapidump_foldermoved);
+	mapitest_suite_add_test(suite, "FOLDERCOPYNOTIF", "Test dump of a folder copy notification", mapitest_mapidump_foldercopied);
+	mapitest_suite_add_test(suite, "MESSAGECREATEDNOTIF", "Test dump of a message created notification", mapitest_mapidump_messagecreated);
+	mapitest_suite_add_test(suite, "MESSAGEDELETEDNOTIF", "Test dump of a message deleted notification", mapitest_mapidump_messagedeleted);
+	mapitest_suite_add_test(suite, "MESSAGEMOVEDNOTIF", "Test dump of a message move notification", mapitest_mapidump_messagemoved);
+	mapitest_suite_add_test(suite, "MESSAGECOPYNOTIF", "Test dump of a message copy notification", mapitest_mapidump_messagecopied);
+	mapitest_suite_add_test(suite, "MESSAGEMODIFIEDNOTIF", "Test dump of a message modification notification", mapitest_mapidump_messagemodified);
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_lcid.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_lcid.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_lcid.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -44,35 +44,35 @@
 */ 
 _PUBLIC_ bool mapitest_lcid_langcode2langtag(struct mapitest *mt)
 {
-	const char	*tag;
+	const char	*locale;
 
-	tag = lcid_langcode2langtag( 0x0409 );
-	if (strcmp(tag, "en-US") != 0) {
-		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 1 - mismatch", tag);
+	locale = mapi_get_locale_from_lcid(0x0409);
+	if (strcmp(locale, "en_US") != 0) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 1 - mismatch", locale);
 		return false;
 	} else {
 		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 1");
 	}
 
-	tag = lcid_langcode2langtag( 0x0439 );
-	if (strcmp(tag, "hi-IN") != 0) {
-		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 2 - mismatch", tag);
+	locale = mapi_get_locale_from_lcid(0x0439);
+	if (strcmp(locale, "hi_IN") != 0) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 2 - mismatch", locale);
 		return false;
 	} else {
 		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 2");
 	}
 
-	tag = lcid_langcode2langtag( 0x1401 );
-	if (strcmp(tag, "ar-DZ") != 0) {
-		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 3 - mismatch", tag);
+	locale = mapi_get_locale_from_lcid(0x1401);
+	if (strcmp(locale, "ar_DZ") != 0) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 3 - mismatch", locale);
 		return false;
 	} else {
 		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 3");
 	}
 
-	tag = lcid_langcode2langtag( 0x0 );
-	if (tag != 0) {
-		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 4 - expected NULL", tag);
+	locale = mapi_get_locale_from_lcid(0x0);
+	if (locale != NULL) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 4 - expected NULL", locale);
 		return false;
 	} else {
 		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 4");

Added: trunk/openchange/utils/mapitest/modules/module_mapidump.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_mapidump.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_mapidump.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -0,0 +1,1075 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - mapidump function tests
+
+   Copyright (C) Brad Hards 2009
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_mapidump.c
+
+   \brief mapidump function tests
+
+   \note These tests do not show how to use libmapi properly, and should
+  not be used as a programming reference.
+*/
+
+/**
+   \details Test dump using mapidump_SPropValue
+
+   This function:
+   -# Tests the mapidump_SPropValue() function 
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_spropvalue(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	struct FILETIME ft;
+	struct Binary_r bin;
+	struct StringArray_r mvstr;
+	int i;
+
+	propvalue.ulPropTag = PR_GENDER; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.i = 3; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_SENSITIVITY; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.l = 68000; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_REPLY_REQUESTED; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.b = 1; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_FILE_SIZE_EXTENDED; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.d = 0x3DEADBEEFCAFE124LL; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_SENDER_NAME; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.lpszA = "Mr. The Sender"; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_REPORT_TAG; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	bin.cb = 12;
+	bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb);
+	for (i = 0; i < bin.cb; ++i) {
+		bin.lpb[i] = 0xF0 + i;
+	}
+	propvalue.value.bin = bin; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_DELIVER_TIME ; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	ft.dwLowDateTime = 0x12345678;
+	ft.dwHighDateTime = 0x01CA6AE4;
+	propvalue.value.ft = ft; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_REPLY_TIME_ERROR; /* enum MAPITAGS */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.err = MAPI_E_UNKNOWN_CPID; /* union SPropValue_CTR */
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	propvalue.ulPropTag = PR_CONTACT_ADDRTYPES;
+	propvalue.dwAlignPad = 0;
+	mvstr.cValues = 3;
+	mvstr.lppszA = talloc_array(mt->mem_ctx, const char *, mvstr.cValues);
+	mvstr.lppszA[0] = talloc_strdup(mt->mem_ctx, "Foo");
+	mvstr.lppszA[1] = talloc_strdup(mt->mem_ctx, "A longer string");
+	mvstr.lppszA[2] = talloc_strdup(mt->mem_ctx, "All strung out on bugs");
+
+	propvalue.value.MVszA = mvstr;
+	mapidump_SPropValue(propvalue, "[sep]");
+
+#if 0
+	/* Types TODO */
+	// int64_t dbl;/* [case(0x0005)] */
+	// const char *lpszW;/* [unique,charset(UTF16),case(0x001f)] */
+	// struct FlatUID_r *lpguid;/* [unique,case(0x0048)] */
+	// struct ShortArray_r MVi;/* [case(0x1002)] */
+	// struct LongArray_r MVl;/* [case(0x1003)] */
+	// struct BinaryArray_r MVbin;/* [case(0x1102)] */
+	// struct FlatUIDArray_r MVguid;/* [case(0x1048)] */
+	// struct WStringArray_r MVszW;/* [case(0x101f)] */
+	// struct DateTimeArray_r MVft;/* [case(0x1040)] */
+	// uint32_t object;/* [case(0x000d)] */
+#endif
+
+	propvalue.ulPropTag = 0xDDDD << 16 | PT_LONG; /* This isn't a real tag, just a test case */
+	propvalue.dwAlignPad = 0;
+	propvalue.value.l = 68020;
+	mapidump_SPropValue(propvalue, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_SPropTagArray
+
+   This function:
+   -# Tests the mapidump_SPropTagArray() function 
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_sproptagarray(struct mapitest *mt)
+{
+	struct SPropTagArray *tagarray;
+
+	tagarray = set_SPropTagArray(mt->mem_ctx, 5, PR_SENDER_NAME,
+						     PR_BODY,
+						     PR_PERSONAL_HOME_PAGE,
+						     PR_OTHER_ADDRESS_CITY,
+						     (0xDDDD << 16 | PT_LONG));
+
+	mapidump_SPropTagArray(tagarray);
+
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_SRowSet
+
+   This function:
+   -# Tests the mapidump_SRowSet() function 
+   -# Indirectly tests the mapidump_SRow() function
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_srowset(struct mapitest *mt)
+{
+	struct SRowSet 		srowset;
+
+	struct SPropValue       SPropValue;
+
+	srowset.cRows = 2;
+	srowset.aRow = talloc_array(mt->mem_ctx, struct SRow, srowset.cRows);
+
+	srowset.aRow[0].cValues = 0;
+	srowset.aRow[0].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue);
+
+	SPropValue.ulPropTag = PR_OBJECT_TYPE;
+	SPropValue.value.l = MAPI_MAILUSER;
+	SRow_addprop(&(srowset.aRow[0]), SPropValue);
+
+	SPropValue.ulPropTag = PR_DISPLAY_TYPE;
+	SPropValue.value.l = 0;
+	SRow_addprop(&(srowset.aRow[0]), SPropValue);
+
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = "gname";
+	SRow_addprop(&(srowset.aRow[0]), SPropValue);
+
+	srowset.aRow[1].cValues = 0;
+	srowset.aRow[1].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue);
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = "kname";
+	SRow_addprop(&(srowset.aRow[1]), SPropValue);
+
+	SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME;
+	SPropValue.value.lpszA = "lname";
+	SRow_addprop(&(srowset.aRow[1]), SPropValue);
+
+	mapidump_SRowSet(&srowset, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_pabentry
+
+   This function:
+   -# Tests the mapidump_PAB_entry() function 
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_pabentry(struct mapitest *mt)
+{
+	struct SRow		pabentry;
+	struct SPropValue       SPropValue;
+
+	pabentry.cValues = 0;
+	pabentry.lpProps = talloc_zero(mt->mem_ctx, struct SPropValue);
+
+	SPropValue.ulPropTag = PR_ADDRTYPE_UNICODE;
+	SPropValue.value.lpszA = "dummy addrtype";
+	SRow_addprop(&(pabentry), SPropValue);
+
+	SPropValue.ulPropTag = PR_DISPLAY_NAME_UNICODE;
+	SPropValue.value.lpszA = "dummy display name";
+	SRow_addprop(&(pabentry), SPropValue);
+
+	SPropValue.ulPropTag = PR_EMAIL_ADDRESS_UNICODE;
+	SPropValue.value.lpszA = "dummy at example.com";
+	SRow_addprop(&(pabentry), SPropValue);
+
+	SPropValue.ulPropTag = PR_ACCOUNT_UNICODE;
+	SPropValue.value.lpszA = "dummy account";
+	SRow_addprop(&(pabentry), SPropValue);
+
+	mapidump_PAB_entry(&pabentry);
+
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_note
+
+   This function:
+   -# Tests the mapidump_note() function on a plain text message
+   -# Tests the mapidump_note() function on a HTML message
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_note(struct mapitest *mt)
+{
+	struct mapi_SPropValue_array	props;
+
+	props.cValues = 3;
+	props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues);
+
+	props.lpProps[0].ulPropTag = PR_CONVERSATION_TOPIC;
+	props.lpProps[0].value.lpszA = "Topic of the Note";
+
+	props.lpProps[1].ulPropTag = PR_BODY;
+	props.lpProps[1].value.lpszA = "This is the body of the note. It has two sentences.";
+
+	props.lpProps[2].ulPropTag = PR_CLIENT_SUBMIT_TIME;
+	props.lpProps[2].value.ft.dwLowDateTime = 0x12345678;
+	props.lpProps[2].value.ft.dwHighDateTime = 0x01CA6BE4;
+
+	mapidump_note(&props, "[dummy ID]");
+
+	props.lpProps[1].ulPropTag = PR_BODY_HTML;
+	props.lpProps[1].value.lpszA = "<h1>Heading for the Note</h1>\n<p>This is the body of the note. It has two sentences.</p>";
+
+	mapidump_note(&props, "[dummy ID]");
+
+	
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_task
+
+   This function:
+   -# Tests the mapidump_task() function
+   -# modifies the task to be completed
+   -# Tests the associated get_importance() function
+   -# Tests the associated get_task_status() function
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_task(struct mapitest *mt)
+{
+	struct mapi_SPropValue_array	props;
+
+	props.cValues = 9;
+	props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues);
+
+	props.lpProps[0].ulPropTag = PR_CONVERSATION_TOPIC;
+	props.lpProps[0].value.lpszA = "Topic of the Task";
+
+	props.lpProps[1].ulPropTag = PR_BODY;
+	props.lpProps[1].value.lpszA = "This is the body of the task. It has two sentences.";
+
+	props.lpProps[2].ulPropTag = PidLidTaskDueDate;
+	props.lpProps[2].value.ft.dwLowDateTime = 0x12345678;
+	props.lpProps[2].value.ft.dwHighDateTime = 0x01CA6CE4;
+
+	props.lpProps[3].ulPropTag = PidLidPrivate;
+	props.lpProps[3].value.b = 0;
+
+	props.lpProps[4].ulPropTag = PR_IMPORTANCE;
+	props.lpProps[4].value.l = IMPORTANCE_HIGH;
+
+	props.lpProps[5].ulPropTag = PidLidPercentComplete;
+	props.lpProps[5].value.dbl = 0.78;
+
+	props.lpProps[6].ulPropTag = PidLidTaskStartDate;
+	props.lpProps[6].value.ft.dwLowDateTime = 0x09876543;
+	props.lpProps[6].value.ft.dwHighDateTime = 0x01CA6AE4;
+
+	props.lpProps[7].ulPropTag = PidLidTaskStatus;
+	props.lpProps[7].value.l = olTaskWaiting;
+
+	props.lpProps[8].ulPropTag = PidLidContacts;
+	props.lpProps[8].value.MVszA.cValues = 2;
+	props.lpProps[8].value.MVszA.strings = talloc_array(mt->mem_ctx, struct mapi_LPSTR, 2);
+	props.lpProps[8].value.MVszA.strings[0].lppszA = "Contact One";
+	props.lpProps[8].value.MVszA.strings[1].lppszA = "Contact Two Jr.";
+
+	mapidump_task(&props, "[dummy ID]");
+
+	props.lpProps[7].ulPropTag = PidLidTaskStatus;
+	props.lpProps[7].value.l = olTaskComplete;
+
+	props.lpProps[3].ulPropTag = PidLidTaskDateCompleted;
+	props.lpProps[3].value.ft.dwLowDateTime = 0x22345678;
+	props.lpProps[3].value.ft.dwHighDateTime = 0x01CA6CB4;
+
+	mapidump_task(&props, "[dummy ID]");
+
+	if (strcmp("Low", get_importance(IMPORTANCE_LOW)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result IMPORTANCE_LOW\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("Normal", get_importance(IMPORTANCE_NORMAL)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result IMPORTANCE_NORMAL\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("High", get_importance(IMPORTANCE_HIGH)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result IMPORTANCE_HIGH\n", "mapidump_task");
+		return false;
+	}
+	if (get_importance(IMPORTANCE_HIGH+1) != 0) {
+		mapitest_print(mt, "* %-40s: bad result OUT_OF_RANGE\n", "mapidump_task");
+		return false;
+	}
+
+	if (strcmp("Not Started", get_task_status(olTaskNotStarted)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result olTaskNotStarted\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("In Progress", get_task_status(olTaskInProgress)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result olTaskInProgress\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("Completed", get_task_status(olTaskComplete)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result olTaskCompleted\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("Waiting on someone else", get_task_status(olTaskWaiting)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result olTaskWaiting\n", "mapidump_task");
+		return false;
+	}
+	if (strcmp("Deferred", get_task_status(olTaskDeferred)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result olTaskDeferred\n", "mapidump_task");
+		return false;
+	}
+	if (get_task_status(olTaskDeferred+1) != 0) {
+		mapitest_print(mt, "* %-40s: bad result OUT_OF_RANGE\n", "mapidump_task");
+		return false;
+	}
+	return true;
+}
+
+/**
+   \details Test dump using mapidump_contact
+
+   This function:
+   -# Tests the mapidump_contact() function
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_contact(struct mapitest *mt)
+{
+	struct mapi_SPropValue_array	props;
+
+	props.cValues = 8;
+	props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues);
+
+	props.lpProps[0].ulPropTag = PR_POSTAL_ADDRESS;
+	props.lpProps[0].value.lpszA = "P.O. Box 543, KTown";
+
+	props.lpProps[1].ulPropTag = PR_STREET_ADDRESS;
+	props.lpProps[1].value.lpszA = "1 My Street, KTown";
+
+	props.lpProps[2].ulPropTag = PR_COMPANY_NAME;
+	props.lpProps[2].value.lpszA = "Dummy Company Pty Ltd";
+
+	props.lpProps[3].ulPropTag = PR_TITLE;
+	props.lpProps[3].value.lpszA = "Ms.";
+
+	props.lpProps[4].ulPropTag = PR_COUNTRY;
+	props.lpProps[4].value.lpszA = "Australia";
+
+	props.lpProps[5].ulPropTag = PR_GIVEN_NAME;
+	props.lpProps[5].value.lpszA = "Konq.";
+
+	props.lpProps[6].ulPropTag = PR_SURNAME;
+	props.lpProps[6].value.lpszA = "Dragoon";
+
+	props.lpProps[7].ulPropTag = PR_DEPARTMENT_NAME;
+	props.lpProps[7].value.lpszA = "Research and Marketing";
+
+	mapidump_contact(&props, "[dummy ID]");
+
+	props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC;
+	props.lpProps[1].value.lpszA = "Contact Topic";
+
+	mapidump_contact(&props, "[dummy ID]");
+
+	props.lpProps[0].ulPropTag = PidLidFileUnder;
+	props.lpProps[0].value.lpszA = "Card Label";
+
+	props.lpProps[4].ulPropTag = PR_DISPLAY_NAME;
+	props.lpProps[4].value.lpszA = "Konqi Dragon";
+
+	mapidump_contact(&props, "[dummy ID]");
+
+	return true;
+}
+
+/**
+   \details Test message dump using mapidump_appointment
+
+   This function:
+   -# Tests the mapidump_appointment() function
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_appointment(struct mapitest *mt)
+{
+	struct mapi_SPropValue_array	props;
+
+	props.cValues = 8;
+	props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues);
+
+	props.lpProps[0].ulPropTag = PidLidContacts;
+	props.lpProps[0].value.MVszA.cValues = 2;
+	props.lpProps[0].value.MVszA.strings = talloc_array(mt->mem_ctx, struct mapi_LPSTR, 2);
+	props.lpProps[0].value.MVszA.strings[0].lppszA = "Contact One";
+	props.lpProps[0].value.MVszA.strings[1].lppszA = "Contact Two Jr.";
+
+	props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC;
+	props.lpProps[1].value.lpszA = "Dummy Appointment topic";
+
+	props.lpProps[2].ulPropTag = PidLidTimeZoneDescription;
+	props.lpProps[2].value.lpszA = "AEDT";
+
+	props.lpProps[3].ulPropTag = PidLidLocation;
+	props.lpProps[3].value.lpszA = "OpenChange Conference Room #3";
+
+	props.lpProps[4].ulPropTag = PidLidBusyStatus;
+	props.lpProps[4].value.l = olTaskNotStarted;
+
+	props.lpProps[5].ulPropTag = PidLidPrivate;
+	props.lpProps[5].ulPropTag = true;
+
+	props.lpProps[6].ulPropTag = PR_END_DATE;
+	props.lpProps[6].value.ft.dwLowDateTime = 0x12345678;
+	props.lpProps[6].value.ft.dwHighDateTime = 0x01CA6CE4;
+
+	props.lpProps[7].ulPropTag = PR_START_DATE;
+	props.lpProps[7].value.ft.dwLowDateTime = 0x09876543;
+	props.lpProps[7].value.ft.dwHighDateTime = 0x01CA6AE4;
+
+	mapidump_appointment(&props, "[dummy ID]");
+
+	return true;
+}
+
+/**
+   \details Test dump of an email message using mapidump_message
+
+   This function:
+   -# Builds an indicative email using mapi_SPropValues (sets no codepage)
+   -# Calls the mapidump_appointment() function
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_message(struct mapitest *mt)
+{
+	struct mapi_SPropValue_array	props;
+
+	props.cValues = 9;
+	props.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, props.cValues);
+
+	props.lpProps[0].ulPropTag = PR_INTERNET_MESSAGE_ID;
+	props.lpProps[0].value.lpszA = "dummy-3535395fds at example.com";
+	
+	props.lpProps[1].ulPropTag = PR_CONVERSATION_TOPIC;
+	props.lpProps[1].value.lpszA = "Dummy Email Subject";
+
+	props.lpProps[2].ulPropTag = PR_BODY;
+	props.lpProps[2].value.lpszA = "This is the body of the email. It has two sentences.\n";
+
+	props.lpProps[3].ulPropTag = PR_SENT_REPRESENTING_NAME;
+	props.lpProps[3].value.lpszA = "The Sender <sender at example.com>";
+
+	props.lpProps[4].ulPropTag = PR_DISPLAY_TO;
+	props.lpProps[4].value.lpszA = "The Recipient <to at example.com>";
+
+	props.lpProps[5].ulPropTag = PR_DISPLAY_CC;
+	props.lpProps[5].value.lpszA = "Other Recipient <cc at example.com>";
+
+	props.lpProps[6].ulPropTag = PR_DISPLAY_BCC;
+	props.lpProps[6].value.lpszA = "Ms. Anonymous <bcc at example.com>";
+
+	props.lpProps[7].ulPropTag = PR_STATUS;
+	props.lpProps[7].value.l = 0;
+
+	props.lpProps[8].ulPropTag = PR_HASATTACH;
+	props.lpProps[8].value.b = false;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_USASCII;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_UNICODE;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_JAUTODETECT;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_KAUTODETECT;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_ISO2022JPESC;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	props.lpProps[7].ulPropTag = PR_MESSAGE_CODEPAGE;
+	props.lpProps[7].value.l = CP_ISO2022JPSIO;
+
+	mapidump_message(&props, "[dummy ID]", NULL);
+
+	return true;
+}
+
+/**
+   \details Test dump of an new mail notification
+
+   This function:
+   -# Tests the mapidump_msgflags function with no bits set
+   -# Tests the mapidump_msgflags function with one bit set
+   -# Tests the mapidump_msgflags function with all bits set
+   -# Builds an indicative new mail notification
+   -# Calls the mapidump_newmail function to test dumping of that new mail notification
+  
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_newmail(struct mapitest *mt)
+{
+	struct NewMailNotification notif;
+
+	mapidump_msgflags(0x0, "[sep]");
+
+	mapidump_msgflags(0x100, "[sep]");
+
+	mapidump_msgflags(0x1|0x2|0x4|0x8|0x10|0x20|0x40|0x80|0x100|0x200, "[sep]");
+
+	notif.FID = 0xFEDCBA9876543210LL;
+	notif.MID = 0xBADCAFEBEEF87625LL;
+	notif.MessageFlags = 0x20|0x2;
+	notif.UnicodeFlag = false;
+	notif.MessageClass.lpszA = "Dummy class";
+
+	mapidump_newmail(&notif, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a free/busy event
+
+   This function:
+   -# builds a freebusy binary event
+   -# tests dumping it using mapidump_freebusy_event()
+   -# modifies the event, and dumps it again
+   -# modifies the event, and dumps it again
+   -# tests dumping a date using mapidump_freebusy_date()
+   -# tests each months for mapidump_freebusy_month()
+   
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_freebusy(struct mapitest *mt)
+{
+	struct Binary_r bin;
+	
+	bin.cb = 4;
+	bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb);
+	/* this example from MS-OXOPFFB Section 4.4.3 */
+	bin.lpb[0] = 0x50;
+	bin.lpb[1] = 0x0A;
+	bin.lpb[2] = 0xC8;
+	bin.lpb[3] = 0x0A;
+	
+	mapidump_freebusy_event(&bin, 2009*16+11, 2008, "[sep]");
+
+	/* this example adapted from MS-OXOPFFB Section 4.4.3 */
+	bin.lpb[0] = 0x50;
+	bin.lpb[1] = 0x0A;
+	bin.lpb[2] = 0xCA;
+	bin.lpb[3] = 0x0A;
+	
+	mapidump_freebusy_event(&bin, 2009*16+11, 2009, "[sep]");
+
+	/* this example adapted from MS-OXOPFFB Section 4.4.3 */
+	bin.lpb[0] = 0x50;
+	bin.lpb[1] = 0x0A;
+	bin.lpb[2] = 0x80;
+	bin.lpb[3] = 0x0A;
+
+	mapidump_freebusy_event(&bin, 2009*16+11, 2009, "[sep]");
+
+	mapidump_freebusy_date(0x0CD18345, "[sep]");
+
+	if (strcmp("January", mapidump_freebusy_month(2009*16+1, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result January\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("February", mapidump_freebusy_month(2009*16+2, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result February\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("March", mapidump_freebusy_month(2009*16+3, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result March\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("April", mapidump_freebusy_month(2009*16+4, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result April\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("May", mapidump_freebusy_month(2009*16+5, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result May\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("June", mapidump_freebusy_month(2009*16+6, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result June\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("July", mapidump_freebusy_month(2009*16+7, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result July\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("August", mapidump_freebusy_month(2009*16+8, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result August\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("September", mapidump_freebusy_month(2009*16+9, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result September\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("October", mapidump_freebusy_month(2009*16+10, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result October\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("November", mapidump_freebusy_month(2009*16+11, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result November\n", "mapidump_freebusy");
+		return false;
+	}
+	if (strcmp("December", mapidump_freebusy_month(2009*16+12, 2009)) != 0) {
+		mapitest_print(mt, "* %-40s: bad result December\n", "mapidump_freebusy");
+		return false;
+	}
+	if (mapidump_freebusy_month(2009*16+0, 2009) != 0) {
+		mapitest_print(mt, "* %-40s: bad result underrange\n", "mapidump_freebusy");
+		return false;
+	}
+	if (mapidump_freebusy_month(2009*16+13, 2009) != 0) {
+		mapitest_print(mt, "* %-40s: bad result overrange\n", "mapidump_freebusy");
+		return false;
+	}
+	return true;
+}
+
+/**
+   \details Test dump of a set of recipients
+
+   This function:
+   -# builds a recipient list
+   -# dumps out the recipient list using mapidump_Recipients()
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_recipients(struct mapitest *mt)
+{
+	const char 		**userlist;
+	struct SRowSet 		resolved;
+	struct SPropTagArray 	*flaglist;
+	struct SPropValue	SPropValue;
+
+	userlist = talloc_array(mt->mem_ctx, const char*, 3);
+	userlist[0] = "Mr. Unresolved";
+	userlist[1] = "Mr/Ms. Ambiguous";
+	userlist[2] = "Mrs. Resolved";
+
+	resolved.cRows = 1;
+	resolved.aRow = talloc_array(mt->mem_ctx, struct SRow, resolved.cRows);
+	resolved.aRow[0].cValues = 0;
+	resolved.aRow[0].lpProps = talloc_zero(mt->mem_ctx, struct SPropValue);
+	SPropValue.ulPropTag = PR_OBJECT_TYPE;
+	SPropValue.value.l = MAPI_MAILUSER;
+	SRow_addprop(&(resolved.aRow[0]), SPropValue);
+
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = "gname";
+	SRow_addprop(&(resolved.aRow[0]), SPropValue);
+
+	flaglist = set_SPropTagArray(mt->mem_ctx, 3, MAPI_UNRESOLVED, MAPI_AMBIGUOUS, MAPI_RESOLVED);
+	
+	mapidump_Recipients(userlist, &resolved, flaglist);
+
+	return true;
+}
+
+/**
+   \details Test dump of a Folder deletion notification
+
+   This function:
+   -# Creates a FolderDeletedNotification structure
+   -# Dumps that structure out using mapidump_folderdeleted()
+   -# Tests mapidump_folderdeleted() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_folderdeleted(struct mapitest *mt)
+{
+	struct FolderDeletedNotification folderdeletednotification;
+
+	folderdeletednotification.ParentFID = 0x9876CAFE432LL;
+	folderdeletednotification.FID = 0x1234ABCDLL;
+	mapidump_folderdeleted(&folderdeletednotification, "[sep]");
+	
+	mapidump_folderdeleted(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a folder move notification
+
+   This function:
+   -# Creates a FolderMoveCopyNotification structure
+   -# Dumps that structure out using mapidump_foldermoved()
+   -# Tests mapidump_foldermoved() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_foldermoved(struct mapitest *mt)
+{
+	struct FolderMoveCopyNotification foldermovecopynotification;
+
+	foldermovecopynotification.ParentFID = 0x9876CAFE432LL;
+	foldermovecopynotification.FID = 0x1234ABCDLL;
+	foldermovecopynotification.OldParentFID = 0x9876CAFE43201DLL;
+	foldermovecopynotification.OldFID = 0x1234ABCD01DLL;
+	mapidump_foldermoved(&foldermovecopynotification, "[sep]");
+	
+	mapidump_foldermoved(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a folder copy notification
+
+   This function:
+   -# Creates a FolderMoveCopyNotification structure
+   -# Dumps that structure out using mapidump_foldercopy()
+   -# Tests mapidump_foldercopy() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_foldercopied(struct mapitest *mt)
+{
+	struct FolderMoveCopyNotification foldermovecopynotification;
+
+	foldermovecopynotification.ParentFID = 0x9876CAFE432LL;
+	foldermovecopynotification.FID = 0x1234ABCDLL;
+	foldermovecopynotification.OldParentFID = 0x9876CAFE43201DLL;
+	foldermovecopynotification.OldFID = 0x1234ABCD01DLL;
+	mapidump_foldercopied(&foldermovecopynotification, "[sep]");
+	
+	mapidump_foldercopied(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a Folder creation notification
+
+   This function:
+   -# Creates a FolderCreatedNotification structure with a null tag set
+   -# Dumps that structure out using mapidump_foldercreated()
+   -# Adds a set of tags to the FolderCreatedNotification
+   -# Dumps the modified FolderCreatedNotification structure using mapidump_foldercreated()
+   -# Tests mapidump_foldercreated() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_foldercreated(struct mapitest *mt)
+{
+	struct FolderCreatedNotification foldercreatednotification;
+
+	foldercreatednotification.ParentFID = 0x9876CAFE432LL;
+	foldercreatednotification.FID = 0x1234ABCDLL;
+	foldercreatednotification.Tags = 0;
+	foldercreatednotification.TagCount = 0;
+	mapidump_foldercreated(&foldercreatednotification, "[sep]");
+
+	foldercreatednotification.TagCount = 3;
+	foldercreatednotification.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS,
+						      foldercreatednotification.TagCount);
+	foldercreatednotification.Tags[0] = PR_RECIPIENT_CERTIFICATE;
+	foldercreatednotification.Tags[1] = PR_URL_COMP_NAME;
+	foldercreatednotification.Tags[2] = PR_END_ATTACH;
+
+	mapidump_foldercreated(&foldercreatednotification, "[sep]");
+
+	mapidump_foldercreated(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a Message deletion notification
+
+   This function:
+   -# Creates a MessageDeletedNotification structure
+   -# Dumps that structure out using mapidump_messagedeleted()
+   -# Tests mapidump_messagedeleted() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_messagedeleted(struct mapitest *mt)
+{
+	struct MessageDeletedNotification messagedeletednotification;
+
+	messagedeletednotification.FID = 0x1234ABCDLL;
+	messagedeletednotification.MID = 0x9876FEALL;
+	mapidump_messagedeleted(&messagedeletednotification, "[sep]");
+	
+	mapidump_messagedeleted(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a Message creation notification
+
+   This function:
+   -# Creates a MessageCreatedNotification structure
+   -# Dumps that structure out using mapidump_messagecreated()
+   -# Adds tags to the MessageCreatedNotification structure
+   -# Dumps the structure again.
+   -# Tests mapidump_messagecreated() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_messagecreated(struct mapitest *mt)
+{
+	struct MessageCreatedNotification messagecreatednotification;
+
+	messagecreatednotification.FID = 0x1234ABCDLL;
+	messagecreatednotification.MID = 0x9876FEALL;
+	messagecreatednotification.Tags = 0;
+	messagecreatednotification.TagCount = 0;
+	mapidump_messagecreated(&messagecreatednotification, "[sep]");
+
+	messagecreatednotification.TagCount = 3;
+	messagecreatednotification.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS,
+						       messagecreatednotification.TagCount);
+	messagecreatednotification.Tags[0] = PR_DISPLAY_NAME;
+	messagecreatednotification.Tags[1] = PR_DISPLAY_NAME_UNICODE;
+	messagecreatednotification.Tags[2] = PR_COMPANY_NAME;
+
+	mapidump_messagecreated(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a Message moved notification
+
+   This function:
+   -# Creates a MessageMovedNotification structure
+   -# Dumps that structure out using mapidump_messagemoved()
+   -# Tests mapidump_messagemoved() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_messagemoved(struct mapitest *mt)
+{
+	struct MessageMoveCopyNotification messagemovednotification;
+
+	messagemovednotification.FID = 0x1234ABCDLL;
+	messagemovednotification.MID = 0x9876FEALL;
+	messagemovednotification.OldFID = 0x1234ABCD01dLL;
+	messagemovednotification.OldMID = 0x9876FEA01dLL;
+	mapidump_messagemoved(&messagemovednotification, "[sep]");
+	
+	mapidump_messagemoved(0, "[sep]");
+
+	return true;
+}
+
+
+/**
+   \details Test dump of a Message copied notification
+
+   This function:
+   -# Creates a MessageCopiedNotification structure
+   -# Dumps that structure out using mapidump_messagecopied()
+   -# Tests mapidump_messagecopied() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_messagecopied(struct mapitest *mt)
+{
+	struct MessageMoveCopyNotification messagecopiednotification;
+
+	messagecopiednotification.FID = 0x1234ABCDLL;
+	messagecopiednotification.MID = 0x9876FEALL;
+	messagecopiednotification.OldFID = 0x1234ABCD01dLL;
+	messagecopiednotification.OldMID = 0x9876FEA01dLL;
+	mapidump_messagecopied(&messagecopiednotification, "[sep]");
+	
+	mapidump_messagecopied(0, "[sep]");
+
+	return true;
+}
+
+/**
+   \details Test dump of a Message modification notification
+
+   This function:
+   -# Creates a MessageModifiedNotification structure
+   -# Dumps that structure out using mapidump_messagemodified()
+   -# Adds tags to the MessageModifiedNotification structure
+   -# Dumps the structure again.
+   -# Tests mapidump_messagemodified() with a null argument
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+   
+   \note This currently doesn't check the results are sane, so manual inspection is required
+*/ 
+_PUBLIC_ bool mapitest_mapidump_messagemodified(struct mapitest *mt)
+{
+	struct MessageModifiedNotification messagemodifiednotification;
+
+	messagemodifiednotification.FID = 0x1234ABCDLL;
+	messagemodifiednotification.MID = 0x9876FEALL;
+	messagemodifiednotification.Tags = 0;
+	messagemodifiednotification.TagCount = 0;
+	mapidump_messagemodified(&messagemodifiednotification, "[sep]");
+
+	messagemodifiednotification.TagCount = 3;
+	messagemodifiednotification.Tags = talloc_array(mt->mem_ctx, enum MAPITAGS,
+						        messagemodifiednotification.TagCount);
+	messagemodifiednotification.Tags[0] = PR_DISPLAY_NAME;
+	messagemodifiednotification.Tags[1] = PR_DISPLAY_NAME_UNICODE;
+	messagemodifiednotification.Tags[2] = PR_COMPANY_NAME;
+
+	mapidump_messagemodified(0, "[sep]");
+
+	return true;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_noserver.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_noserver.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_noserver.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -1053,3 +1053,47 @@
 #endif
 	return true;
 }
+
+/**
+     \details Test the get_proptag_value() function
+
+   This function:
+   -# Checks the first value in the list
+   -# Checks a random value from the list
+   -# Checks the last value in the list
+   -# Checks a value that doesn't exist
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_noserver_proptagvalue(struct mapitest *mt) 
+{
+	uint32_t proptag;
+	
+	proptag = get_proptag_value("PR_ACKNOWLEDGEMENT_MODE");
+	if (proptag != PR_ACKNOWLEDGEMENT_MODE) {
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PR_ACKNOWLEDGEMENT_MODE");
+		return false;
+	}
+
+	proptag = get_proptag_value("PR_PROFILE_OPEN_FLAGS");
+	if (proptag != PR_PROFILE_OPEN_FLAGS) {
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PR_PROFILE_OPEN_FLAGS");
+		return false;
+	}
+
+	proptag = get_proptag_value("PR_EMS_AB_SERVER");
+	if (proptag != PR_EMS_AB_SERVER) {
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with PR_EMS_AB_SERVER_ERROR");
+		return false;
+	}
+
+	proptag = get_proptag_value("No such tag, ok?");
+	if (proptag != 0) {
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "get_proptag_value with non-existent tag");
+		return false;
+	}
+
+	return true;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_nspi.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_nspi.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_nspi.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -39,26 +39,31 @@
  */
 _PUBLIC_ bool mapitest_nspi_UpdateStat(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	uint32_t       		plDelta = 1;
 	struct SRowSet		*SRowSet;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_UpdateStat");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	retval = nspi_GetSpecialTable(nspi_ctx, 0x2, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		talloc_free(mem_ctx);
 		return false;
 	}
 
-	retval = nspi_UpdateStat(nspi_ctx, &plDelta);
+	retval = nspi_UpdateStat(nspi_ctx, mem_ctx, &plDelta);
 	mapitest_print_retval(mt, "NspiUpdateStat");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		talloc_free(mem_ctx);
 		return false;
 	}
 	mapitest_print(mt, "* %-35s: %d\n", "plDelta", plDelta);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -73,6 +78,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_QueryRows(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SPropTagArray	*MIds;
@@ -81,14 +87,15 @@
 	struct SPropValue	*lpProp;
 	struct Restriction_r	Filter;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_QueryRows");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Build the array of columns we want to retrieve */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0x2, PR_DISPLAY_NAME,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME,
 					  PR_DISPLAY_TYPE);
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_ACCOUNT;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
@@ -98,28 +105,32 @@
 	Filter.res.resProperty.ulPropTag = PR_ACCOUNT;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
 	mapitest_print_retval(mt, "NspiGetMatches");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	/* Query the rows */
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	retval = nspi_QueryRows(nspi_ctx, NULL, MIds, 1, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi_ctx, mem_ctx, NULL, MIds, 1, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiQueryRows");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
+	talloc_free(mem_ctx);
+
 	return true;
 }
 
@@ -133,34 +144,37 @@
  */
 _PUBLIC_ bool mapitest_nspi_SeekEntries(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SPropValue	pTarget;
 	struct SPropTagArray	*pPropTags;
 	struct SRowSet		*SRowSet;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_SeekEntries");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
 	
 	pTarget.ulPropTag = PR_DISPLAY_NAME;
 	pTarget.dwAlignPad = 0x0;
 	pTarget.value.lpszA = global_mapi_ctx->session->profile->username;
 
-	pPropTags = set_SPropTagArray(mt->mem_ctx, 0x1,
-				      PR_ACCOUNT);
+	pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_ACCOUNT);
 
-	retval = nspi_SeekEntries(nspi_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &SRowSet);
+	retval = nspi_SeekEntries(nspi_ctx, mem_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &SRowSet);
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		mapitest_print_retval(mt, "NspiSeekEntries");
 		talloc_free(pPropTags);
 		talloc_free(SRowSet);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	mapitest_print_retval(mt, "NspiSeekEntries");
 	MAPIFreeBuffer(SRowSet);
 	MAPIFreeBuffer(pPropTags);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -175,6 +189,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetMatches(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SPropTagArray	*MIds;
@@ -183,14 +198,15 @@
 	struct SPropValue	*lpProp;
 	struct Restriction_r	Filter;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetMatches");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Build the array of columns we want to retrieve */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0x2, PR_DISPLAY_NAME,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME,
 					  PR_DISPLAY_TYPE);
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_ACCOUNT;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
@@ -200,19 +216,20 @@
 	Filter.res.resProperty.ulPropTag = PR_ACCOUNT;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(MIds);
 	mapitest_print_retval(mt, "NspiGetMatches");
 	if (GetLastError() != MAPI_E_SUCCESS) {
-		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
+	talloc_free(mem_ctx);
 	return true;
 }
 
@@ -226,6 +243,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_ResortRestriction(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct Restriction_r	Filter;
@@ -235,10 +253,11 @@
 	struct SPropTagArray	*MIds = NULL;
 	struct SPropTagArray	*ppMIds = NULL;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_ResortRestriction");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Build the array of columns we want to retrieve */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0xb,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xb,
 					  PR_DISPLAY_NAME,
 					  PR_OFFICE_TELEPHONE_NUMBER,
 					  PR_OFFICE_LOCATION,
@@ -253,7 +272,7 @@
 					  );
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_OBJECT_TYPE;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.l = 6;
@@ -263,29 +282,32 @@
 	Filter.res.resProperty.ulPropTag = PR_OBJECT_TYPE;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(nspi_ctx->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(nspi_ctx->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiGetMatches");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
-	ppMIds = talloc_zero(nspi_ctx->mem_ctx, struct SPropTagArray);
-	retval = nspi_ResortRestriction(nspi_ctx, SortTypeDisplayName, MIds, &ppMIds);
+	ppMIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_ResortRestriction(nspi_ctx, mem_ctx, SortTypeDisplayName, MIds, &ppMIds);
 	mapitest_print_retval(mt, "NspiResortRestriction");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
 		MAPIFreeBuffer(ppMIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	MAPIFreeBuffer(MIds);
 	MAPIFreeBuffer(ppMIds);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -300,22 +322,25 @@
  */
 _PUBLIC_ bool mapitest_nspi_DNToMId(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct StringsArray_r	pNames;
 	struct SPropTagArray	*MId;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_DNToMId");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	pNames.Count = 0x1;
-	pNames.Strings = (const char **) talloc_array(mt->mem_ctx, char **, 1);
+	pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
 	pNames.Strings[0] = global_mapi_ctx->session->profile->homemdb;
 
-	MId = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	MId = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	retval = nspi_DNToMId(nspi_ctx, &pNames, &MId);
+	retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &MId);
 	MAPIFreeBuffer((char **)pNames.Strings);
 	MAPIFreeBuffer(MId);
+	talloc_free(mem_ctx);
 
 	mapitest_print_retval(mt, "NspiDNToMId");
 
@@ -336,6 +361,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetPropList(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SPropTagArray	*pPropTags;
@@ -345,11 +371,12 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		*SRowSet;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetPropList");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Step 1. Query for current profile username */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0x1, PR_DISPLAY_NAME);
-	lpProp = talloc_zero(nspi_ctx->mem_ctx, struct SPropValue);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_ANR_UNICODE;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.lpszW = global_mapi_ctx->session->profile->username;
@@ -359,31 +386,34 @@
 	Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(nspi_ctx->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(nspi_ctx->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SRowSet);
 	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return retval;
 	}
 
 
 	/* Step 2. Call NspiGetPropList using the MId returned by NspiGetMatches */
 	pPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetPropList(nspi_ctx, 0, MIds->aulPropTag[0], &pPropTags);
+	retval = nspi_GetPropList(nspi_ctx, mem_ctx, 0, MIds->aulPropTag[0], &pPropTags);
 	MAPIFreeBuffer(MIds);
 	mapitest_print_retval(mt, "NspiGetPropList");
 
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(pPropTags);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	mapitest_print(mt, "* %-35s: %d\n", "Properties number", pPropTags->cValues);
 	MAPIFreeBuffer(pPropTags);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -398,6 +428,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetProps(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct StringsArray_r	pNames;
@@ -405,31 +436,35 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		*SRowSet;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetProps");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	pNames.Count = 0x1;
-	pNames.Strings = (const char **) talloc_array(mt->mem_ctx, char **, 1);
+	pNames.Strings = (const char **) talloc_array(mem_ctx, char **, 1);
 	pNames.Strings[0] = global_mapi_ctx->session->profile->homemdb;
 
-	MId = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	MId = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	retval = nspi_DNToMId(nspi_ctx, &pNames, &MId);
+	retval = nspi_DNToMId(nspi_ctx, mem_ctx, &pNames, &MId);
 	MAPIFreeBuffer((char **)pNames.Strings);
 	mapitest_print_retval(mt, "NspiDNToMId");
 
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MId);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
-	retval = nspi_GetProps(nspi_ctx, SPropTagArray, MId, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
+	retval = nspi_GetProps(nspi_ctx, mem_ctx, SPropTagArray, MId, &SRowSet);
 	mapitest_print_retval(mt, "NspiGetProps");
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(MId);
 	MAPIFreeBuffer(SRowSet);
 
+	talloc_free(mem_ctx);
+
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		return false;
 	}
@@ -447,6 +482,7 @@
  */
 _PUBLIC_ bool mapitest_nspi_CompareMIds(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	uint32_t		plResult;
@@ -456,13 +492,14 @@
 	struct SPropValue	*lpProp;
 	struct Restriction_r	Filter;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_CompareMIds");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Build the array of columns we want to retrieve */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0x1, PR_DISPLAY_NAME);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME);
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_OBJECT_TYPE;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.l = 6;
@@ -472,15 +509,16 @@
 	Filter.res.resProperty.ulPropTag = PR_OBJECT_TYPE;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(nspi_ctx->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(nspi_ctx->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SPropTagArray);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiGetMatches");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
@@ -488,17 +526,20 @@
 	if (MIds->cValues < 2) {
 		mapitest_print(mt, "* Only one result found, can't compare\n");
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
-	retval = nspi_CompareMIds(nspi_ctx, MIds->aulPropTag[0], MIds->aulPropTag[1], &plResult);
+	retval = nspi_CompareMIds(nspi_ctx, mem_ctx, MIds->aulPropTag[0], MIds->aulPropTag[1], &plResult);
 	mapitest_print_retval(mt, "NspiCompareMIds");
 	MAPIFreeBuffer(MIds);
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	mapitest_print(mt, "* %-35s: %d\n", "value of the comparison", plResult);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -513,6 +554,7 @@
 */
 _PUBLIC_ bool mapitest_nspi_ModProps(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SRow		*pRow;
@@ -524,14 +566,15 @@
 	struct SPropValue	*lpProp;
 	struct Restriction_r	Filter;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_ModProps");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 	/* Build the array of columns we want to retrieve */
-	SPropTagArray = set_SPropTagArray(nspi_ctx->mem_ctx, 0x2, PR_DISPLAY_NAME,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_DISPLAY_NAME,
 					  PR_DISPLAY_TYPE);
 
 	/* Build the restriction we want for NspiGetMatches */
-	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp = talloc_zero(mem_ctx, struct SPropValue);
 	lpProp->ulPropTag = PR_ACCOUNT;
 	lpProp->dwAlignPad = 0;
 	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
@@ -541,41 +584,44 @@
 	Filter.res.resProperty.ulPropTag = PR_ACCOUNT;
 	Filter.res.resProperty.lpProp = lpProp;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	MIds = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetMatches(nspi_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	MIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi_ctx, mem_ctx, SPropTagArray, &Filter, &SRowSet, &MIds);
 	MAPIFreeBuffer(lpProp);
 	MAPIFreeBuffer(SRowSet);
 	MAPIFreeBuffer(SPropTagArray);
 	mapitest_print_retval(mt, "NspiGetMatches");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	/* Query the rows */
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	retval = nspi_QueryRows(nspi_ctx, NULL, MIds, 1, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi_ctx, mem_ctx, NULL, MIds, 1, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiQueryRows");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(MIds);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	/* Build the SRow and SPropTagArray for NspiModProps */
-	pRow = talloc_zero(mt->mem_ctx, struct SRow);
+	pRow = talloc_zero(mem_ctx, struct SRow);
 	modProp.ulPropTag = PR_DISPLAY_NAME_UNICODE;
 	modProp.value.lpszW = "mapitest ModProps";
 	SRow_addprop(pRow, modProp);
 
-	pPropTags = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME_UNICODE);
+	pPropTags = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME_UNICODE);
 
-	retval = nspi_ModProps(nspi_ctx, MIds->aulPropTag[0], pPropTags, pRow);
+	retval = nspi_ModProps(nspi_ctx, mem_ctx, MIds->aulPropTag[0], pPropTags, pRow);
 	mapitest_print_retval(mt, "NspiModProps");
 	MAPIFreeBuffer(MIds);
 	MAPIFreeBuffer(pPropTags);
 	MAPIFreeBuffer(pRow);
+	talloc_free(mem_ctx);
 
 	/* Assuming true for the moment */
 	return true;
@@ -591,25 +637,29 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetSpecialTable(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SRowSet		*SRowSet;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetSpecialTable");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
-	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	retval = nspi_GetSpecialTable(nspi_ctx, 0x0, &SRowSet);
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x0, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiGetSpecialTable (Hierarchy Table)");
 
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
-	retval = nspi_GetSpecialTable(nspi_ctx, 0x2, &SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, mem_ctx, 0x2, &SRowSet);
 	MAPIFreeBuffer(SRowSet);
 	mapitest_print_retval(mt, "NspiGetSpecialTable (Address Creation Template)");
+	talloc_free(mem_ctx);
 
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		return false;
@@ -628,18 +678,21 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetTemplateInfo(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SRow		*ppData = NULL;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetTemplateInfo");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
-	ppData = talloc_zero(mt->mem_ctx, struct SRow);
-	retval = nspi_GetTemplateInfo(nspi_ctx, 
+	ppData = talloc_zero(mem_ctx, struct SRow);
+	retval = nspi_GetTemplateInfo(nspi_ctx, mem_ctx,
 				      TI_TEMPLATE|TI_SCRIPT|TI_EMT|TI_HELPFILE_NAME|TI_HELPFILE_CONTENTS,
 				      0, NULL, &ppData);
 	mapitest_print_retval(mt, "NspiGetTemplateInfo");
 	MAPIFreeBuffer(ppData);
+	talloc_free(mem_ctx);
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		return false;
 	}
@@ -687,24 +740,28 @@
  */
 _PUBLIC_ bool mapitest_nspi_QueryColumns(struct mapitest *mt)
 {
+	TALLOC_CTX		*mem_ctx;
 	enum MAPISTATUS		retval;
 	struct nspi_context	*nspi_ctx;
 	struct SPropTagArray	*SPropTagArray = NULL;
 	
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_QueryColumns");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 	
-	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
 
-	retval = nspi_QueryColumns(nspi_ctx, true, &SPropTagArray);
+	retval = nspi_QueryColumns(nspi_ctx, mem_ctx, true, &SPropTagArray);
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		mapitest_print_retval(mt, "NspiQueryColumns");
 		MAPIFreeBuffer(SPropTagArray);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
 	mapitest_print(mt, "* %d columns returned\n", SPropTagArray->cValues);
 	mapitest_print_retval(mt, "NspiQueryColumns");
 	MAPIFreeBuffer(SPropTagArray);
+	talloc_free(mem_ctx);
 
 	return true;
 }
@@ -719,20 +776,23 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetNamesFromIDs(struct mapitest *mt)
 {
+	TALLOC_CTX			*mem_ctx;
 	enum MAPISTATUS			retval;
 	struct nspi_context		*nspi_ctx;
 	struct SPropTagArray		*ppReturnedPropTags;
 	struct PropertyNameSet_r	*ppNames;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetNamesFromIDs");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 
-	ppReturnedPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	ppNames = talloc_zero(mt->mem_ctx, struct PropertyNameSet_r);
-	retval = nspi_GetNamesFromIDs(nspi_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames);
+	ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray);
+	ppNames = talloc_zero(mem_ctx, struct PropertyNameSet_r);
+	retval = nspi_GetNamesFromIDs(nspi_ctx, mem_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames);
 	mapitest_print_retval(mt, "NspiGetNamesFromIDs");
 	MAPIFreeBuffer(ppReturnedPropTags);
 	MAPIFreeBuffer(ppNames);
+	talloc_free(mem_ctx);
 
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		return false;
@@ -751,31 +811,35 @@
  */
 _PUBLIC_ bool mapitest_nspi_GetIDsFromNames(struct mapitest *mt)
 {
+	TALLOC_CTX			*mem_ctx;
 	enum MAPISTATUS			retval;
 	struct nspi_context		*nspi_ctx;
 	struct SPropTagArray		*ppReturnedPropTags;
 	struct PropertyNameSet_r	*ppNames;
 
+	mem_ctx = talloc_named(NULL, 0, "mapitest_nspi_GetIDsFromNames");
 	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
 
 
-	ppReturnedPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	ppNames = talloc_zero(mt->mem_ctx, struct PropertyNameSet_r);
-	retval = nspi_GetNamesFromIDs(nspi_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames);
+	ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray);
+	ppNames = talloc_zero(mem_ctx, struct PropertyNameSet_r);
+	retval = nspi_GetNamesFromIDs(nspi_ctx, mem_ctx, NULL, NULL, &ppReturnedPropTags, &ppNames);
 	mapitest_print_retval(mt, "NspiGetNamesFromIDs");
 	MAPIFreeBuffer(ppReturnedPropTags);
 
 	if (retval != MAPI_E_SUCCESS) {
 		MAPIFreeBuffer(ppNames);
+		talloc_free(mem_ctx);
 		return false;
 	}
 
-	ppReturnedPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
-	retval = nspi_GetIDsFromNames(nspi_ctx, true, ppNames->cNames, ppNames->aNames, &ppReturnedPropTags);
+	ppReturnedPropTags = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = nspi_GetIDsFromNames(nspi_ctx, mem_ctx, true, ppNames->cNames, ppNames->aNames, &ppReturnedPropTags);
 	mapitest_print_retval(mt, "NspiGetIDsFromNames");
 	MAPIFreeBuffer(ppReturnedPropTags);
 	MAPIFreeBuffer(ppNames);
-	
+	talloc_free(mem_ctx);
+
 	if (retval != MAPI_E_SUCCESS) {
 		return false;
 	}
@@ -854,3 +918,67 @@
 
 	return true;
 }
+
+/**
+   \details Test the GetGALTable function
+
+   \param mt pointer to the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetGALTable(struct mapitest *mt)
+{
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		*SRowSet;
+	enum MAPISTATUS		retval;
+	uint32_t		i;
+	uint32_t		count;
+	uint8_t			ulFlags;
+	uint32_t		rowsFetched = 0;
+	uint32_t		totalRowsFetched = 0;
+	bool			ret = true;
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xc,
+					  PR_INSTANCE_KEY,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_DISPLAY_TYPE,
+					  PR_OBJECT_TYPE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_OFFICE_TELEPHONE_NUMBER_UNICODE,
+					  PR_OFFICE_LOCATION_UNICODE,
+					  PR_TITLE_UNICODE,
+					  PR_COMPANY_NAME_UNICODE,
+					  PR_ACCOUNT_UNICODE);
+
+	count = 0x20;
+	ulFlags = TABLE_START;
+	do {
+		retval = GetGALTable(mt->session, SPropTagArray, &SRowSet, count, ulFlags);
+		mapitest_print_retval(mt, "GetGALTable");
+		if ((!SRowSet) || (!(SRowSet->aRow))) {
+			ret = false;
+			goto cleanup;
+		}
+		rowsFetched = SRowSet->cRows;
+		totalRowsFetched += rowsFetched;
+		if (rowsFetched) {
+			for (i = 0; i < rowsFetched; i++) {
+				mapidump_PAB_entry(&SRowSet->aRow[i]);
+			}
+		}
+		ulFlags = TABLE_CUR;
+		MAPIFreeBuffer(SRowSet);
+	} while (rowsFetched == count);
+
+	if (totalRowsFetched < 1) {
+		/* We should always have at least ourselves in the list */
+		/* So if we got no rows at all, there is a problem */
+		ret = false;
+	}
+cleanup:
+	MAPIFreeBuffer(SPropTagArray);
+
+	return ret;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_oxcfold.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcfold.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxcfold.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -730,6 +730,7 @@
 	mapitest_print_retval(mt, "DeleteMessage");
 
 	/* Release */
+	mapi_object_release(&dst_contents);
 	mapi_object_release(&obj_folder_src);
 	mapi_object_release(&obj_folder_dst);
 	mapi_object_release(&obj_store);
@@ -988,6 +989,7 @@
 	/* Step 1. Logon */
 	mapi_object_init(&obj_store);
 	mapi_object_init(&obj_folder);
+	mapi_object_init(&contents);
 
 	retval = OpenMsgStore(mt->session, &obj_store);
 	mapitest_print_retval(mt, "OpenMsgStore");
@@ -1011,7 +1013,6 @@
 		goto cleanup;
 	}
 
-	mapi_object_init(&(contents));
 	retval = GetContentsTable(&(obj_folder), &(contents), 0, &count);
 	mapitest_print_retval(mt, "GetContentsTable");
 	if (retval != MAPI_E_SUCCESS) {
@@ -1095,6 +1096,7 @@
 
 cleanup:
 	/* Release */
+	mapi_object_release(&contents);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_store);
 

Modified: trunk/openchange/utils/mapitest/modules/module_oxcmsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -279,13 +279,17 @@
 
 
 	/* Step 4. Resolve the recipients and call ModifyRecipients */
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_OBJECT_TYPE,
 					  PR_DISPLAY_TYPE,
-					  PR_7BIT_DISPLAY_NAME,
-					  PR_DISPLAY_NAME,
-					  PR_SMTP_ADDRESS,
-					  PR_GIVEN_NAME);
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_SEND_RICH_INFO,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
 
 	username = talloc_array(mt->mem_ctx, char *, 2);
 	username[0] = mt->info.szDisplayName;
@@ -293,7 +297,7 @@
 
 	retval = ResolveNames(mapi_object_get_session(&obj_message), 
 			      (const char **)username, SPropTagArray, 
-			      &SRowSet, &flaglist, 0);
+			      &SRowSet, &flaglist, MAPI_UNICODE);
 	mapitest_print_retval(mt, "ResolveNames");
 
 	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
@@ -305,6 +309,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -313,6 +319,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -322,6 +330,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -330,9 +340,13 @@
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print_retval(mt, "DeleteMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 	/* Release */
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_store);
@@ -401,13 +415,17 @@
 		return false;
 	}
 
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_OBJECT_TYPE,
 					  PR_DISPLAY_TYPE,
-					  PR_7BIT_DISPLAY_NAME,
-					  PR_DISPLAY_NAME,
-					  PR_SMTP_ADDRESS,
-					  PR_GIVEN_NAME);
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_SEND_RICH_INFO,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
 
 	username = talloc_array(mt->mem_ctx, char *, 2);
 	username[0] = mt->info.szDisplayName;
@@ -415,7 +433,7 @@
 
 	retval = ResolveNames(mapi_object_get_session(&obj_message),
 			      (const char **)username, SPropTagArray, 
-			      &SRowSet, &flaglist, 0);
+			      &SRowSet, &flaglist, MAPI_UNICODE);
 	mapitest_print_retval(mt, "ResolveNames");
 
 	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
@@ -426,6 +444,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -433,6 +453,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -441,6 +463,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -450,6 +474,8 @@
 	retval = RemoveAllRecipients(&obj_message);
 	mapitest_print_retval(mt, "RemoveAllRecipients");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		ret = false;
 	}
 
@@ -457,6 +483,8 @@
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
 	mapitest_print_retval(mt, "SaveChangesMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -466,10 +494,14 @@
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print_retval(mt, "DeleteMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		ret = false;
 	}
 
 	/* Release */
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_store);
@@ -540,13 +572,17 @@
 		return false;
 	}
 
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_OBJECT_TYPE,
 					  PR_DISPLAY_TYPE,
-					  PR_7BIT_DISPLAY_NAME,
-					  PR_DISPLAY_NAME,
-					  PR_SMTP_ADDRESS,
-					  PR_GIVEN_NAME);
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_SEND_RICH_INFO,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
 
 	username = talloc_array(mt->mem_ctx, char *, 2);
 	username[0] = mt->info.szDisplayName;
@@ -554,7 +590,7 @@
 
 	retval = ResolveNames(mapi_object_get_session(&obj_message),
 			      (const char **)username, SPropTagArray, 
-			      &SRowSet, &flaglist, 0);
+			      &SRowSet, &flaglist, MAPI_UNICODE);
 	mapitest_print_retval(mt, "ResolveNames");
 
 	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
@@ -566,6 +602,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -574,6 +612,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -583,6 +623,8 @@
 	retval = ModifyRecipients(&obj_message, SRowSet);
 	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -592,6 +634,8 @@
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
 	mapitest_print_retval(mt, "SaveChangesMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		return false;
 	}
 
@@ -601,6 +645,8 @@
 	mapitest_print_retval(mt, "ReadRecipients");
 	MAPIFreeBuffer(RecipientRows);
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		ret = false;
 	}
 
@@ -610,10 +656,14 @@
 	retval = DeleteMessage(&obj_folder, id_msgs, 1);
 	mapitest_print_retval(mt, "DeleteMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		MAPIFreeBuffer(flaglist);
 		ret = false;
 	}
 
 	/* Release */
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_store);
@@ -1066,12 +1116,14 @@
 			mapitest_print(mt, "* %-35s: unexpected flag 0x%x\n", "QueryRows", 
 				       (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1]))));
 			ret = false;
+
 			goto cleanup;
 		}
 	}
 
  cleanup:
 	/* Cleanup and release */
+	talloc_free(SRowSet.aRow);
 	mapi_object_release(&obj_htable);
 	mapitest_common_cleanup(mt);
 
@@ -1168,6 +1220,7 @@
 	retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1177,6 +1230,7 @@
 
 	ret = mapitest_common_message_fill(mt, &obj_embeddedmsg, "[MT] EmbeddedMessage");
 	if (ret == false) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1188,6 +1242,7 @@
 	retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1198,6 +1253,7 @@
 	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesAttachment", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1208,6 +1264,7 @@
 	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1220,6 +1277,7 @@
 	retval = OpenAttach(&obj_message, 0, &obj_attach);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenAttach", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1229,6 +1287,7 @@
 	retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_READONLY);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval);
 	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_embeddedmsg);
 		mapi_object_release(&obj_attach);
 		mapi_object_release(&obj_message);
 		mapi_object_release(&obj_folder);
@@ -1336,15 +1395,16 @@
 	mapitest_print(mt, "* %-35s: 0x%.8x (%d)\n", "GetValidAttach", retval, numAttach);
 	if (numAttach != 0) {
 		ret = false;
-		goto cleanup;
+		goto cleanup_wo_attach;
 	}
 	if (retval != MAPI_E_SUCCESS) {
 		ret = false;
-		goto cleanup;
+		goto cleanup_wo_attach;
 	}
 
 	/* Step 5. Create two attachments to the message */
 	mapi_object_init(&obj_attach0);
+	mapi_object_init(&obj_attach1);
 	retval = CreateAttach(&obj_message, &obj_attach0);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateAttach", retval);
 	if (retval != MAPI_E_SUCCESS) {
@@ -1374,7 +1434,6 @@
 		goto cleanup;
 	}
 
-	mapi_object_init(&obj_attach1);
 	retval = CreateAttach(&obj_message, &obj_attach1);
 	mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateAttach", retval);
 	if (retval != MAPI_E_SUCCESS) {
@@ -1463,10 +1522,12 @@
 		ret = false;
 		goto cleanup;
 	}
+
 cleanup:
 	/* Release */
 	mapi_object_release(&obj_attach0);
 	mapi_object_release(&obj_attach1);
+cleanup_wo_attach:
 	mapi_object_release(&obj_message);
 	mapi_object_release(&obj_folder);
 	mapi_object_release(&obj_store);
@@ -1501,6 +1562,8 @@
 
 	ret = true;
 
+	mapi_object_init(&obj_folder);
+	mapi_object_init(&obj_message);
 	/* Step 1. Logon */
 	mapi_object_init(&obj_store);
 	retval = OpenMsgStore(mt->session, &obj_store);
@@ -1518,7 +1581,6 @@
 		goto cleanup;
 	}
 
-	mapi_object_init(&obj_folder);
 	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
 	mapitest_print_retval(mt, "OpenFolder");
 	if (retval != MAPI_E_SUCCESS) {
@@ -1527,7 +1589,6 @@
 	}
 
 	/* Step 3. Create the message */
-	mapi_object_init(&obj_message);
 	retval = CreateMessage(&obj_folder, &obj_message);
 	mapitest_print_retval(mt, "CreateMessage");
 	if (retval != MAPI_E_SUCCESS) {

Modified: trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -63,6 +63,7 @@
 	retval = GetPropList(&obj_store, SPropTagArray);
 	mapitest_print_retval(mt, "GetPropList");
 	if (retval != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SPropTagArray);
 		return false;
 	}
 
@@ -70,6 +71,7 @@
 	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
 	mapitest_print_retval(mt, "GetProps");
 	if (retval != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SPropTagArray);
 		return false;
 	}
 	MAPIFreeBuffer(SPropTagArray);
@@ -692,7 +694,9 @@
 	retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite|CopyFlagsMove,
 			   &problem_count, &problems);
 	MAPIFreeBuffer(SPropTagArray);
-	MAPIFreeBuffer(problems);
+	if (problem_count) {
+		MAPIFreeBuffer(problems);
+	}
 	mapitest_print_retval_step_fmt(mt, "11.", "CopyProps", "(%s)", "move");
 	if (retval != MAPI_E_SUCCESS) {
 		return false;

Modified: trunk/openchange/utils/mapitest/modules/module_oxcstor.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcstor.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxcstor.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -499,3 +499,355 @@
 	mapi_object_release(&obj_store);
 	return ret;
 }
+
+/**
+   \details Test the IsMailboxFolder convenience function
+
+   This function:
+   -# Logs into the user private mailbox
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_IsMailboxFolder(struct mapitest *mt)
+{
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_pf_store;
+	bool			ret = true;
+	mapi_object_store_t *	store;
+	mapi_object_store_t *	pf_store;
+	uint32_t 		olFolderNumber;
+	bool			callResult;
+	enum MAPISTATUS		retval;
+
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_pf_store);
+	
+	/* Step 1. Logon Private Mailbox */
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	store = (mapi_object_store_t *) obj_store.private_data;
+	if (! store) {
+		mapitest_print(mt, "* FAILED to get store private_data\n" );
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_top_information_store, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for top_information_store\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderTopInformationStore) {
+		mapitest_print(mt, "* FAILED - wrong folder number for top_information_store\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_deleted_items, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for deleted_items\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderDeletedItems) {
+		mapitest_print(mt, "* FAILED - wrong folder number for deleted_items\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_outbox, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for outbox\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderOutbox) {
+		mapitest_print(mt, "* FAILED - wrong folder number for outbox\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_sent_items, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for sent items\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderSentMail) {
+		mapitest_print(mt, "* FAILED - wrong folder number for sent items\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_inbox, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for inbox\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderInbox) {
+		mapitest_print(mt, "* FAILED - wrong folder number for inbox\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_common_views, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for views\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderCommonView) {
+		mapitest_print(mt, "* FAILED - wrong folder number for views\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_calendar, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for calendar\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderCalendar) {
+		mapitest_print(mt, "* FAILED - wrong folder number for calendar\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_contact, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for contacts\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderContacts) {
+		mapitest_print(mt, "* FAILED - wrong folder number for contacts\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_journal, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for journal\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderJournal) {
+		mapitest_print(mt, "* FAILED - wrong folder number for journal\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_note, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for notes\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderNotes) {
+		mapitest_print(mt, "* FAILED - wrong folder number for note\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_task, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for tasks\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderTasks) {
+		mapitest_print(mt, "* FAILED - wrong folder number for tasks\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_drafts, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for drafts\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderDrafts) {
+		mapitest_print(mt, "* FAILED - wrong folder number for drafts\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_store, store->fid_search, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for search\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderFinder) {
+		mapitest_print(mt, "* FAILED - wrong folder number for search\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	retval = OpenPublicFolder(mt->session, &obj_pf_store);
+	mapitest_print_retval(mt, "OpenPublicFolder");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	pf_store = (mapi_object_store_t *) obj_pf_store.private_data;
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_OfflineAB, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for offline address book\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicOfflineAB) {
+		mapitest_print(mt, "* FAILED - wrong folder number for offline address book\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_FreeBusyRoot, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for free-busy root\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicFreeBusyRoot) {
+		mapitest_print(mt, "* FAILED - wrong folder number for free-busy root\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_EFormsRegistryRoot, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for EForms root\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicEFormsRoot) {
+		mapitest_print(mt, "* FAILED - wrong folder number for EForms root\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	/* this one is a bit sensitive. sometimes the EFormsRegistry is null */
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_EFormsRegistry, &olFolderNumber);
+	if (pf_store->fid_pf_EFormsRegistry != 0) {
+		if (! callResult) {
+			mapitest_print(mt, "* FAILED to get folder number for EForms registry\n");
+			ret = false;
+			goto cleanup;
+		}
+		if (olFolderNumber != olFolderPublicEFormsRegistry) {
+			mapitest_print(mt, "* FAILED - wrong folder number for EForms registry\n");
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_public_root, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for Public root\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicRoot) {
+		mapitest_print(mt, "* FAILED - wrong folder number for Public root\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_ipm_subtree, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for IPM subtree\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicIPMSubtree) {
+		mapitest_print(mt, "* FAILED - wrong folder number for IPM subtree\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_non_ipm_subtree, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for non-IPM subtree\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicNonIPMSubtree) {
+		mapitest_print(mt, "* FAILED - wrong folder number for non-IPM subtree\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_LocalSiteFreeBusy, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for local free busy folder\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicLocalFreeBusy) {
+		mapitest_print(mt, "* FAILED - wrong folder number for local free busy folder\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_LocalSiteOfflineAB, &olFolderNumber);
+	if (! callResult) {
+		mapitest_print(mt, "* FAILED to get folder number for local offline address book\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != olFolderPublicLocalOfflineAB) {
+		mapitest_print(mt, "* FAILED - wrong folder number for local offline address folder\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	/* this one is a bit sensitive. sometimes the NNTP Articles Folder ID is null */
+	callResult = IsMailboxFolder(&obj_pf_store, pf_store->fid_pf_NNTPArticle, &olFolderNumber);
+	if (pf_store->fid_pf_NNTPArticle != 0) {
+		if (! callResult) {
+			mapitest_print(mt, "* FAILED to get folder number for NNTP Articles\n");
+			ret = false;
+			goto cleanup;
+		}
+		if (olFolderNumber != olFolderPublicNNTPArticle) {
+			mapitest_print(mt, "* FAILED - wrong folder number for NNTP Articles\n");
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	/* this is meant to break */
+	callResult = IsMailboxFolder(&obj_store, 0xFFEEDDCC, &olFolderNumber);
+	if (callResult) {
+		mapitest_print(mt, "* FAILED - expected no folder number\n");
+		ret = false;
+		goto cleanup;
+	}
+	if (olFolderNumber != 0xFFFFFFFF) {
+		mapitest_print(mt, "* FAILED - wrong folder number for bad folder id\n");
+		ret = false;
+		goto cleanup;
+	}
+
+	mapitest_print(mt, "* All PASSED\n");
+
+cleanup:
+	mapi_object_release(&obj_store);
+	mapi_object_release(&obj_pf_store);
+
+	return ret;
+}

Modified: trunk/openchange/utils/mapitest/modules/module_oxctable.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxctable.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxctable.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -93,7 +93,6 @@
 	mapi_object_t		obj_htable;
 	mapi_object_t		obj_test_folder;
 	struct SPropTagArray	columns;
-	struct SPropTagArray	*SPropTagArray;
 	struct mt_common_tf_ctx	*context;
 	uint32_t		count;
 
@@ -124,19 +123,7 @@
 	}
 
 
-	/* Step 4. SetColumns */
-	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3,
-					  PR_DISPLAY_NAME,
-					  PR_FID,
-					  PR_FOLDER_CHILD_COUNT);
-	retval = SetColumns(&(obj_test_folder), SPropTagArray);
-	MAPIFreeBuffer(SPropTagArray);
-	if (GetLastError() != MAPI_E_SUCCESS) {
-		mapitest_print_retval(mt, "SetColumns");
-		return false;
-	}
-
-	/* Step 5. QueryColumns on a contents folder */
+	/* Step 4. QueryColumns on a contents folder */
 	retval = QueryColumns(&(obj_test_folder), &columns);
 	mapitest_print_retval(mt, "QueryColumns");
 	if (GetLastError() != MAPI_E_SUCCESS) {
@@ -419,9 +406,10 @@
 	/* Step 2. GetStatus */
 	retval = GetStatus(&obj_htable, &TableStatus);
 	mapitest_print_retval(mt, "GetStatus");
-	mapitest_print(mt, "* %-35s: TableStatus: %d\n", "GetStatus", TableStatus);
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		ret = false;
+	} else {
+		mapitest_print(mt, "* %-35s: TableStatus: %d\n", "GetStatus", TableStatus);
 	}
 
 	/* Step 3. Release */

Modified: trunk/openchange/utils/mapitest/modules/module_oxomsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxomsg.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/mapitest/modules/module_oxomsg.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -242,6 +242,7 @@
 	mapitest_print_retval(mt, "DeleteMessage");
 	if ((retval != MAPI_E_SUCCESS) && (retval != ecNoDelSubmitMsg)) {
 		ret = false;
+		goto mapitest_oxomsg_AbortSubmit_bailout;
 	}
 	/* Step 6. Clean up anything else */
 	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
@@ -447,6 +448,7 @@
 	mapitest_print_retval(mt, "SaveChangesMessage");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		ret = false;
+		goto mapitest_oxomsg_TransportSend_bailout;
 	}
 
 	/* Step 5. TransportSend */
@@ -454,6 +456,7 @@
 	mapitest_print_retval(mt, "TransportSend");
 	if (GetLastError() != MAPI_E_SUCCESS) {
 		ret = false;
+		goto mapitest_oxomsg_TransportSend_bailout;
 	}
 
 	/* Step 6. Dump the properties */

Modified: trunk/openchange/utils/openchange-tools.c
===================================================================
--- trunk/openchange/utils/openchange-tools.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/openchange-tools.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -45,7 +45,7 @@
 /*
  * Retrieve the property value for a given SRow and property tag.  
  *
- * If the property type is a string: fetch PT_STRING8 then PT_UNICODE
+ * If the property type is a string: fetch PT_UNICODE then PT_STRING8
  * in case the desired property is not available in first choice.
  *
  * Fetch property normally for any others properties
@@ -56,11 +56,11 @@
 
 	if (((proptag & 0xFFFF) == PT_STRING8) ||
 	    ((proptag & 0xFFFF) == PT_UNICODE)) {
-		proptag = (proptag & 0xFFFF0000) | PT_STRING8;
+		proptag = (proptag & 0xFFFF0000) | PT_UNICODE;
 		str = (const char *) find_SPropValue_data(aRow, proptag);
 		if (str) return (void *)str;
 
-		proptag = (proptag & 0xFFFF0000) | PT_UNICODE;
+		proptag = (proptag & 0xFFFF0000) | PT_STRING8;
 		str = (const char *) find_SPropValue_data(aRow, proptag);
 		return (void *)str;
 	} 
@@ -72,7 +72,7 @@
 /*
  * Read a stream and store it in a DATA_BLOB
  */
-static enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx,
+_PUBLIC_ enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx,
 					 mapi_object_t *obj_stream, 
 					 DATA_BLOB *body)
 {
@@ -125,13 +125,13 @@
 
 	switch (format) {
 	case olEditorText:
-		data = octool_get_propval(aRow, PR_BODY);
+		data = octool_get_propval(aRow, PR_BODY_UNICODE);
 		if (data) {
 			body->data = talloc_memdup(mem_ctx, data, strlen(data));
 			body->length = strlen(data);
 		} else {
 			mapi_object_init(&obj_stream);
-			retval = OpenStream(obj_message, PR_BODY, 0, &obj_stream);
+			retval = OpenStream(obj_message, PR_BODY_UNICODE, 0, &obj_stream);
 			MAPI_RETVAL_IF(retval, GetLastError(), NULL);
 			
 			retval = octool_get_stream(mem_ctx, &obj_stream, body);
@@ -239,9 +239,9 @@
 	}
 	
 	from = (const char *) octool_get_propval(&aRow, PR_SENT_REPRESENTING_NAME);
-	to = (const char *) octool_get_propval(&aRow, PR_DISPLAY_TO);
-	cc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_CC);
-	bcc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_BCC);
+	to = (const char *) octool_get_propval(&aRow, PR_DISPLAY_TO_UNICODE);
+	cc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_CC_UNICODE);
+	bcc = (const char *) octool_get_propval(&aRow, PR_DISPLAY_BCC_UNICODE);
 
 	has_attach = (const uint8_t *) octool_get_propval(&aRow, PR_HASATTACH);
 	cp = (const uint32_t *) octool_get_propval(&aRow, PR_MESSAGE_CODEPAGE);

Modified: trunk/openchange/utils/openchange-tools.h
===================================================================
--- trunk/openchange/utils/openchange-tools.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/openchange-tools.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -55,6 +55,9 @@
 _PUBLIC_ void *octool_get_propval(struct SRow *, uint32_t);
 _PUBLIC_ enum MAPISTATUS octool_get_body(TALLOC_CTX *, mapi_object_t *,
 					 struct SRow *, DATA_BLOB *);
+_PUBLIC_ enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx,
+					 mapi_object_t *obj_stream, 
+					 DATA_BLOB *body);
 _PUBLIC_ struct mapi_session *octool_init_mapi(const char *, const char *, uint32_t);
 __END_DECLS
 

Modified: trunk/openchange/utils/openchangeclient.c
===================================================================
--- trunk/openchange/utils/openchangeclient.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/openchangeclient.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -65,6 +65,7 @@
 	oclient->private = false;
 	oclient->freebusy = NULL;
 	oclient->force = false;
+	oclient->summary = false;
 
 	/* contact related parameters */
 	oclient->email = NULL;
@@ -93,14 +94,6 @@
 	oclient->ocpf_dump = NULL;
 }
 
-static char *utf8tolinux(TALLOC_CTX *mem_ctx, const char *wstring)
-{
-	char		*newstr;
-
-	newstr = windows_to_utf8(mem_ctx, wstring);
-	return newstr;
-}
-
 static enum MAPISTATUS openchangeclient_getdir(TALLOC_CTX *mem_ctx,
 					       mapi_object_t *obj_container,
 					       mapi_object_t *obj_child,
@@ -111,7 +104,6 @@
 	struct SRowSet		SRowSet;
 	mapi_object_t		obj_htable;
 	mapi_object_t		obj_folder;
-	char			*newname;
 	char     		**folder  = NULL;
 	const char		*name;
 	const uint64_t		*fid;
@@ -140,17 +132,15 @@
 		while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) {
 			for (index = 0; (index < SRowSet.cRows) && (found == false); index++) {
 				fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[index], PR_FID);
-				name = (const char *)find_SPropValue_data(&SRowSet.aRow[index], PR_DISPLAY_NAME);
+				name = (const char *)find_SPropValue_data(&SRowSet.aRow[index], PR_DISPLAY_NAME_UNICODE);
 
-				newname = utf8tolinux(mem_ctx, name);
-				if (newname && fid && !strcmp(newname, folder[i])) {
+				if (name && fid && !strcmp(name, folder[i])) {
 					retval = OpenFolder(&obj_folder, *fid, obj_child);
 					MAPI_RETVAL_IF(retval, retval, folder);
 
 					found = true;
 					mapi_object_copy(&obj_folder, obj_child);
 				}
-				MAPIFreeBuffer(newname);
 			}
 		}
 
@@ -213,7 +203,7 @@
 		oclient->attach[oclient->attach_num].filename = talloc_strdup(mem_ctx, filename);
 		oclient->attach[oclient->attach_num].bin.lpb = talloc_size(mem_ctx, sb.st_size);
 		oclient->attach[oclient->attach_num].bin.cb = sb.st_size;
-		if ((oclient->attach[oclient->attach_num].bin.lpb = mmap(NULL, sb.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0)) == (void *) -1) {
+		if ((oclient->attach[oclient->attach_num].bin.lpb = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0)) == (void *) -1) {
 			perror("mmap");
 			close(fd);
 			return false;
@@ -446,77 +436,81 @@
 					     rowset.aRow[i].lpProps[1].value.d,
 					     &obj_message, 0);
 			if (GetLastError() == MAPI_E_SUCCESS) {
-				struct SPropValue	*lpProps;
-				struct SRow		aRow;
-
-				SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_HASATTACH);
-				lpProps = talloc_zero(mem_ctx, struct SPropValue);
-				retval = GetProps(&obj_message, SPropTagArray, &lpProps, &count);
-				MAPIFreeBuffer(SPropTagArray);
-				if (retval != MAPI_E_SUCCESS) return retval;
-
-				aRow.ulAdrEntryPad = 0;
-				aRow.cValues = count;
-				aRow.lpProps = lpProps;
-
-				retval = octool_message(mem_ctx, &obj_message);
-
-				has_attach = (const uint8_t *) get_SPropValue_SRow_data(&aRow, PR_HASATTACH);
-
- 				/* If we have attachments, retrieve them */
-				if (has_attach && *has_attach) {
-					mapi_object_init(&obj_tb_attach);
-					retval = GetAttachmentTable(&obj_message, &obj_tb_attach);
-					if (retval == MAPI_E_SUCCESS) {
-						SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
-						retval = SetColumns(&obj_tb_attach, SPropTagArray);
-						if (retval != MAPI_E_SUCCESS) return retval;
-						MAPIFreeBuffer(SPropTagArray);
-						
-						retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
-						if (retval != MAPI_E_SUCCESS) return retval;
-
-						for (j = 0; j < rowset_attach.cRows; j++) {
-							attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[j]), PR_ATTACH_NUM);
-							retval = OpenAttach(&obj_message, *attach_num, &obj_attach);
-							if (retval == MAPI_E_SUCCESS) {
-								struct SPropValue	*lpProps2;
-								uint32_t		count2;
-
-								SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, 
-												  PR_ATTACH_FILENAME,
-												  PR_ATTACH_LONG_FILENAME,
-												  PR_ATTACH_SIZE);
-								lpProps2 = talloc_zero(mem_ctx, struct SPropValue);
-								retval = GetProps(&obj_attach, SPropTagArray, &lpProps2, &count2);
-								MAPIFreeBuffer(SPropTagArray);
-								if (retval != MAPI_E_SUCCESS) return retval;
-								
-								aRow.ulAdrEntryPad = 0;
-								aRow.cValues = count2;
-								aRow.lpProps = lpProps2;
-
-								attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_LONG_FILENAME));
-								if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) {
-									attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_FILENAME));
-								}
-								attach_size = (const uint32_t *) octool_get_propval(&aRow, PR_ATTACH_SIZE);
-								printf("[%u] %s (%u Bytes)\n", j, attach_filename, attach_size ? *attach_size : 0);
-								fflush(0);
-								if (oclient->store_folder) {
-								  status = store_attachment(obj_attach, attach_filename, attach_size ? *attach_size : 0, oclient);
-									if (status == false) {
-										printf("A Problem was encountered while storing attachments on the filesystem\n");
-										MAPI_RETVAL_IF(status == false, MAPI_E_UNABLE_TO_COMPLETE, mem_ctx);
-
+				if (oclient->summary) {
+					mapidump_message_summary(&obj_message);
+				} else {
+					struct SPropValue	*lpProps;
+					struct SRow		aRow;
+					
+					SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_HASATTACH);
+					lpProps = talloc_zero(mem_ctx, struct SPropValue);
+					retval = GetProps(&obj_message, SPropTagArray, &lpProps, &count);
+					MAPIFreeBuffer(SPropTagArray);
+					if (retval != MAPI_E_SUCCESS) return retval;
+					
+					aRow.ulAdrEntryPad = 0;
+					aRow.cValues = count;
+					aRow.lpProps = lpProps;
+					
+					retval = octool_message(mem_ctx, &obj_message);
+					
+					has_attach = (const uint8_t *) get_SPropValue_SRow_data(&aRow, PR_HASATTACH);
+					
+					/* If we have attachments, retrieve them */
+					if (has_attach && *has_attach) {
+						mapi_object_init(&obj_tb_attach);
+						retval = GetAttachmentTable(&obj_message, &obj_tb_attach);
+						if (retval == MAPI_E_SUCCESS) {
+							SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
+							retval = SetColumns(&obj_tb_attach, SPropTagArray);
+							if (retval != MAPI_E_SUCCESS) return retval;
+							MAPIFreeBuffer(SPropTagArray);
+							
+							retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
+							if (retval != MAPI_E_SUCCESS) return retval;
+							
+							for (j = 0; j < rowset_attach.cRows; j++) {
+								attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[j]), PR_ATTACH_NUM);
+								retval = OpenAttach(&obj_message, *attach_num, &obj_attach);
+								if (retval == MAPI_E_SUCCESS) {
+									struct SPropValue	*lpProps2;
+									uint32_t		count2;
+									
+									SPropTagArray = set_SPropTagArray(mem_ctx, 0x3, 
+													  PR_ATTACH_FILENAME,
+													  PR_ATTACH_LONG_FILENAME,
+													  PR_ATTACH_SIZE);
+									lpProps2 = talloc_zero(mem_ctx, struct SPropValue);
+									retval = GetProps(&obj_attach, SPropTagArray, &lpProps2, &count2);
+									MAPIFreeBuffer(SPropTagArray);
+									if (retval != MAPI_E_SUCCESS) return retval;
+									
+									aRow.ulAdrEntryPad = 0;
+									aRow.cValues = count2;
+									aRow.lpProps = lpProps2;
+									
+									attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_LONG_FILENAME));
+									if (!attach_filename || (attach_filename && !strcmp(attach_filename, ""))) {
+										attach_filename = get_filename(octool_get_propval(&aRow, PR_ATTACH_FILENAME));
 									}
+									attach_size = (const uint32_t *) octool_get_propval(&aRow, PR_ATTACH_SIZE);
+									printf("[%u] %s (%u Bytes)\n", j, attach_filename, attach_size ? *attach_size : 0);
+									fflush(0);
+									if (oclient->store_folder) {
+										status = store_attachment(obj_attach, attach_filename, attach_size ? *attach_size : 0, oclient);
+										if (status == false) {
+											printf("A Problem was encountered while storing attachments on the filesystem\n");
+											MAPI_RETVAL_IF(status == false, MAPI_E_UNABLE_TO_COMPLETE, mem_ctx);
+											
+										}
+									}
+									MAPIFreeBuffer(lpProps2);
 								}
-								MAPIFreeBuffer(lpProps2);
 							}
+							errno = 0;
 						}
-						errno = 0;
+						MAPIFreeBuffer(lpProps);
 					}
-					MAPIFreeBuffer(lpProps);
 				}
 			}
 			mapi_object_release(&obj_message);
@@ -774,19 +768,23 @@
 	if (retval != MAPI_E_SUCCESS) return retval;
 
 	/* Recipients operations */
-	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xA,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_OBJECT_TYPE,
 					  PR_DISPLAY_TYPE,
-					  PR_7BIT_DISPLAY_NAME,
-					  PR_DISPLAY_NAME,
-					  PR_SMTP_ADDRESS,
-					  PR_GIVEN_NAME);
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_SEND_RICH_INFO,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
 
 	oclient->usernames = collapse_recipients(mem_ctx, oclient);
 
 	/* ResolveNames */
 	retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)oclient->usernames, 
-			      SPropTagArray, &SRowSet, &flaglist, 0);
+			      SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
 	MAPIFreeBuffer(SPropTagArray);
 	if (retval != MAPI_E_SUCCESS) return retval;
 
@@ -811,7 +809,7 @@
 	/* set message properties */
 	msgflag = MSGFLAG_UNSENT;
 	oclient->subject = (!oclient->subject) ? "" : oclient->subject;
-	set_SPropValue_proptag(&props[0], PR_SUBJECT, 
+	set_SPropValue_proptag(&props[0], PR_SUBJECT_UNICODE, 
 			       (const void *)oclient->subject);
 	set_SPropValue_proptag(&props[1], PR_MESSAGE_FLAGS, 
 			       (const void *)&msgflag);
@@ -829,7 +827,7 @@
 			bin.cb = strlen(oclient->pr_body);
 			openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_BODY, 2, bin);
 		} else {
-			set_SPropValue_proptag(&props[2], PR_BODY, 
+			set_SPropValue_proptag(&props[2], PR_BODY_UNICODE, 
 								   (const void *)oclient->pr_body);
 			prop_count++;
 		}
@@ -1057,13 +1055,13 @@
 	lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
 
 	if (oclient->subject) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC, 
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, 
 			       (const void *) oclient->subject);
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT,
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE,
 			       (const void *) oclient->subject);
 	}
 	if (oclient->pr_body) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY, (const void *)oclient->pr_body);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->pr_body);
 	}
 	if (oclient->location) {
 		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidLocation, (const void *)oclient->location);
@@ -1224,12 +1222,12 @@
 	lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
 
 	if (oclient->card_name) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name);
 		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidFileUnder, (const void *)oclient->card_name);
 		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, SPropTagArray->aulPropTag[0], (const void *)oclient->card_name);
 	}
 	if (oclient->full_name) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_DISPLAY_NAME, (const void *)oclient->full_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_DISPLAY_NAME_UNICODE, (const void *)oclient->full_name);
 	}
 	if (oclient->email) {
 		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidEmail1OriginalDisplayName, (const void *)oclient->email);
@@ -1268,7 +1266,7 @@
 		if (retval != MAPI_E_SUCCESS) return false;
 	}
 
-	/* Create contact mesage */
+	/* Create contact message */
 	mapi_object_init(&obj_message);
 	retval = CreateMessage(&obj_contact, &obj_message);
 	if (retval != MAPI_E_SUCCESS) return false;
@@ -1311,8 +1309,8 @@
 	lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
 
 	if (oclient->card_name) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC, (const void *)oclient->card_name);
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name);
 	}
 
 	if (oclient->dtstart) {
@@ -1340,7 +1338,7 @@
 	}
 
 	if (oclient->pr_body) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY, (const void *)oclient->pr_body);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->pr_body);
 	}
 
 	if (!oclient->update) {
@@ -1387,7 +1385,7 @@
 		if (retval != MAPI_E_SUCCESS) return false;
 	}
 
-	/* Create contact mesage */
+	/* Create contact message */
 	mapi_object_init(&obj_message);
 	retval = CreateMessage(&obj_task, &obj_message);
 	if (retval != MAPI_E_SUCCESS) return false;
@@ -1427,10 +1425,10 @@
 	lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
 
 	if (oclient->card_name) {
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC, (const void *)oclient->card_name);
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_SUBJECT, (const void *)oclient->card_name);
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT, (const void *)oclient->card_name);
-		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC_UNICODE, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_SUBJECT_UNICODE, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT_UNICODE, (const void *)oclient->card_name);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY_UNICODE, (const void *)oclient->card_name);
 	}
 
 	if (!oclient->update) {
@@ -1496,7 +1494,7 @@
 		if (retval != MAPI_E_SUCCESS) return false;
 	}
 
-	/* Create contact mesage */
+	/* Create contact message */
 	mapi_object_init(&obj_message);
 	retval = CreateMessage(&obj_note, &obj_message);
 	if (retval != MAPI_E_SUCCESS) return false;
@@ -1552,7 +1550,6 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		rowset;
 	const char	       	*name;
-	char			*newname;
 	const char		*comment;
 	const uint32_t		*total;
 	const uint32_t		*unread;
@@ -1570,9 +1567,9 @@
 	if (retval != MAPI_E_SUCCESS) return false;
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
-					  PR_DISPLAY_NAME,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_FID,
-					  PR_COMMENT,
+					  PR_COMMENT_UNICODE,
 					  PR_CONTENT_UNREAD,
 					  PR_CONTENT_COUNT,
 					  PR_FOLDER_CHILD_COUNT);
@@ -1583,8 +1580,8 @@
 	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) {
 		for (index = 0; index < rowset.cRows; index++) {
 			fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID);
-			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
-			comment = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_COMMENT);
+			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE);
+			comment = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_COMMENT_UNICODE);
 			total = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_CONTENT_COUNT);
 			unread = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_CONTENT_UNREAD);
 			child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT);
@@ -1592,11 +1589,9 @@
 			for (i = 0; i < count; i++) {
 				printf("|   ");
 			}
-			newname = utf8tolinux(mem_ctx, name);
 			printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%016"PRIx64"]\n", 
-			       newname, comment?comment:"", total?*total:0, unread?*unread:0,
+			       name, comment?comment:"", total?*total:0, unread?*unread:0,
 			       get_container_class(mem_ctx, parent, *fid), *fid);
-			MAPIFreeBuffer(newname);
 			if (child && *child) {
 				ret = get_child_folders(mem_ctx, &obj_folder, *fid, count + 1);
 				if (ret == false) return ret;
@@ -1616,7 +1611,6 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		rowset;
 	const char	       	*name;
-	char			*newname;
 	const uint32_t		*child;
 	uint32_t		index;
 	const uint64_t		*fid;
@@ -1631,7 +1625,7 @@
 	if (retval != MAPI_E_SUCCESS) return false;
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
-					  PR_DISPLAY_NAME,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_FID,
 					  PR_FOLDER_CHILD_COUNT);
 	retval = SetColumns(&obj_htable, SPropTagArray);
@@ -1641,15 +1635,13 @@
 	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) {
 		for (index = 0; index < rowset.cRows; index++) {
 			fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID);
-			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
+			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE);
 			child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT);
 
 			for (i = 0; i < count; i++) {
 				printf("|   ");
 			}
-			newname = utf8tolinux(mem_ctx, name);
-			printf("|---+ %-15s [FID: 0x%016"PRIx64"]\n", newname, *fid);
-			MAPIFreeBuffer(newname);
+			printf("|---+ %-15s [FID: 0x%016"PRIx64"]\n", name, *fid);
 			if (*child) {
 				ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
 				if (ret == false) return ret;
@@ -1682,16 +1674,15 @@
 	struct SPropValue		*lpProps;
 	uint32_t			cValues;
 	const char			*mailbox_name;
-	char				*utf8_mailbox_name;
 
 	/* Retrieve the mailbox folder name */
-	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_DISPLAY_NAME_UNICODE);
 	retval = GetProps(obj_store, SPropTagArray, &lpProps, &cValues);
 	MAPIFreeBuffer(SPropTagArray);
 	if (retval != MAPI_E_SUCCESS) return false;
 
-	if (lpProps[0].value.lpszA) {
-		mailbox_name = lpProps[0].value.lpszA;
+	if (lpProps[0].value.lpszW) {
+		mailbox_name = lpProps[0].value.lpszW;
 	} else {
 		return false;
 	}
@@ -1700,9 +1691,7 @@
 	retval = GetDefaultFolder(obj_store, &id_mailbox, olFolderTopInformationStore);
 	if (retval != MAPI_E_SUCCESS) return false;
 
-	utf8_mailbox_name = utf8tolinux(mem_ctx, mailbox_name);
-	printf("+ %s\n", utf8_mailbox_name);
-	MAPIFreeBuffer(utf8_mailbox_name);
+	printf("+ %s\n", mailbox_name);
 	return get_child_folders(mem_ctx, obj_store, id_mailbox, 0);
 }
 
@@ -1788,33 +1777,37 @@
 					     SRowSet.aRow[i].lpProps[1].value.d,
 					     &obj_message, 0);
 			if (retval != MAPI_E_NOT_FOUND) {
-				retval = GetPropsAll(&obj_message, &properties_array);
-				if (retval == MAPI_E_SUCCESS) {
-					id = talloc_asprintf(mem_ctx, ": %"PRIX64"/%"PRIX64,
-							     SRowSet.aRow[i].lpProps[0].value.d,
-							     SRowSet.aRow[i].lpProps[1].value.d);
-					mapi_SPropValue_array_named(&obj_message, 
-								    &properties_array);
-					switch (olFolder) {
-					case olFolderInbox:
-					  mapidump_message(&properties_array, id);
-						break;
-					case olFolderCalendar:
-						mapidump_appointment(&properties_array, id);
-						break;
-					case olFolderContacts:
-						mapidump_contact(&properties_array, id);
-						break;
-					case olFolderTasks:
-						mapidump_task(&properties_array, id);
-						break;
-					case olFolderNotes:
-						mapidump_note(&properties_array, id);
-						break;
+				if (oclient->summary) {
+					mapidump_message_summary(&obj_message);
+				} else {
+					retval = GetPropsAll(&obj_message, &properties_array);
+					if (retval == MAPI_E_SUCCESS) {
+						id = talloc_asprintf(mem_ctx, ": %"PRIX64"/%"PRIX64,
+								     SRowSet.aRow[i].lpProps[0].value.d,
+								     SRowSet.aRow[i].lpProps[1].value.d);
+						mapi_SPropValue_array_named(&obj_message, 
+									    &properties_array);
+						switch (olFolder) {
+						case olFolderInbox:
+						  mapidump_message(&properties_array, id, NULL);
+							break;
+						case olFolderCalendar:
+							mapidump_appointment(&properties_array, id);
+							break;
+						case olFolderContacts:
+							mapidump_contact(&properties_array, id);
+							break;
+						case olFolderTasks:
+							mapidump_task(&properties_array, id);
+							break;
+						case olFolderNotes:
+							mapidump_note(&properties_array, id);
+							break;
+						}
+						talloc_free(id);
 					}
-					talloc_free(id);
-					mapi_object_release(&obj_message);
 				}
+				mapi_object_release(&obj_message);
 			}
 		}
 	}
@@ -1870,7 +1863,7 @@
 				mapi_object_release(&obj_htable);
 				mapi_object_release(&obj_folder);
 				return MAPI_E_SUCCESS;
-			} else {
+			} else if (fid) {
 				retval = folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret);
 				if (retval == MAPI_E_SUCCESS) {
 					mapi_object_release(&obj_htable);
@@ -2123,7 +2116,7 @@
 						id = talloc_asprintf(mem_ctx, ": %"PRIX64"/%"PRIX64,
 								     SRowSet.aRow[i].lpProps[0].value.d,
 								     SRowSet.aRow[i].lpProps[1].value.d);
-						mapidump_message(&properties_array, id);
+						mapidump_message(&properties_array, id, NULL);
 						mapi_object_release(&obj_message);
 						talloc_free(id);
 
@@ -2318,7 +2311,7 @@
 	if (retval != MAPI_E_SUCCESS) return false;
 
 	/* wait for notifications: infinite loop */
-	retval = MonitorNotification(mapi_object_get_session(obj_store), (void *)obj_store);
+	retval = MonitorNotification(mapi_object_get_session(obj_store), (void *)obj_store, NULL);
 	if (retval != MAPI_E_SUCCESS) return false;
 
 	retval = Unsubscribe(mapi_object_get_session(obj_store), ulConnection);
@@ -2429,6 +2422,7 @@
 	uint32_t		i;
 	uint32_t		count;
 	uint8_t			ulFlags;
+	uint32_t		rowsFetched = 0;
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0xc,
 					  PR_INSTANCE_KEY,
@@ -2452,14 +2446,15 @@
 		if ((!SRowSet) || (!(SRowSet->aRow))) {
 			return false;
 		}
-		if (SRowSet->cRows) {
-			for (i = 0; i < SRowSet->cRows; i++) {
+		rowsFetched = SRowSet->cRows;
+		if (rowsFetched) {
+			for (i = 0; i < rowsFetched; i++) {
 				mapidump_PAB_entry(&SRowSet->aRow[i]);
 			}
 		}
 		ulFlags = TABLE_CUR;
 		MAPIFreeBuffer(SRowSet);
-	} while (SRowSet->cRows == count);
+	} while (rowsFetched == count);
 	mapi_errstr("GetPABTable", GetLastError());
 
 	MAPIFreeBuffer(SPropTagArray);
@@ -2680,7 +2675,7 @@
 	year = GetFreeBusyYear(publish_start);
 
 	DEBUG(0, ("FreeBusy (%s):\n", message_name));
-	mapidump_date_SPropValue(aRow.lpProps[1], "* FreeBusy Last Modification Time");
+	mapidump_date_SPropValue(aRow.lpProps[1], "* FreeBusy Last Modification Time", "\t");
 	mapidump_freebusy_date(*publish_start, "\t* FreeBusy Publishing Start:");
 	mapidump_freebusy_date(*publish_end, "\t *FreeBusy Publishing End:  ");
 
@@ -2791,7 +2786,7 @@
 	      OPT_FOLDER, OPT_MAPI_COLOR, OPT_SENDNOTE, OPT_MKDIR, OPT_RMDIR,
 	      OPT_FOLDER_NAME, OPT_FOLDER_COMMENT, OPT_USERLIST, OPT_MAPI_PRIVATE,
 	      OPT_UPDATE, OPT_DELETEITEMS, OPT_OCPF_FILE, OPT_OCPF_SYNTAX,
-	      OPT_OCPF_SENDER, OPT_OCPF_DUMP, OPT_FREEBUSY, OPT_FORCE};
+	      OPT_OCPF_SENDER, OPT_OCPF_DUMP, OPT_FREEBUSY, OPT_FORCE, OPT_FETCHSUMMARY};
 
 	struct poptOption long_options[] = {
 		POPT_AUTOHELP
@@ -2805,6 +2800,7 @@
 		{"sendtask", 0, POPT_ARG_NONE, NULL, OPT_SENDTASK, "send a task", NULL },
 		{"sendnote", 0, POPT_ARG_NONE, NULL, OPT_SENDNOTE, "send a note", NULL },
 		{"fetchmail", 'F', POPT_ARG_NONE, NULL, OPT_FETCHMAIL, "fetch user INBOX mails", NULL },
+		{"fetchsummary", 0, POPT_ARG_NONE, NULL, OPT_FETCHSUMMARY, "fetch message summaries only", NULL },
 		{"storemail", 'G', POPT_ARG_STRING, NULL, OPT_STOREMAIL, "retrieve a mail on the filesystem", NULL },
 		{"fetch-items", 'i', POPT_ARG_STRING, NULL, OPT_FETCHITEMS, "fetch specified user INBOX items", NULL },
 		{"freebusy", 0, POPT_ARG_STRING, NULL, OPT_FREEBUSY, "display free / busy information for the specified user", NULL },
@@ -2903,6 +2899,9 @@
 		case OPT_FETCHITEMS:
 			opt_fetchitems = poptGetOptArg(pc);
 			break;
+		case OPT_FETCHSUMMARY:
+			oclient.summary = true;
+			break;
 		case OPT_DELETEITEMS:
 			oclient.delete = poptGetOptArg(pc);
 			break;

Modified: trunk/openchange/utils/openchangeclient.h
===================================================================
--- trunk/openchange/utils/openchangeclient.h	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/openchangeclient.h	2010-02-11 11:16:26 UTC (rev 3288)
@@ -75,6 +75,7 @@
 	const char		*folder_comment;
 	const char		*freebusy;
 	bool			force;
+	bool			summary;
 	/* PF related options */
 	bool			pf;
 	const char		*folder;

Modified: trunk/openchange/utils/openchangepfadmin.c
===================================================================
--- trunk/openchange/utils/openchangepfadmin.c	2010-02-10 18:53:01 UTC (rev 3287)
+++ trunk/openchange/utils/openchangepfadmin.c	2010-02-11 11:16:26 UTC (rev 3288)
@@ -76,14 +76,6 @@
 	}
 }
 
-static char *utf8tolinux(TALLOC_CTX *mem_ctx, const char *wstring)
-{
-	char		*newstr;
-
-	newstr = windows_to_utf8(mem_ctx, wstring);
-	return newstr;
-}
-
 static bool get_child_folders_pf(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count)
 {
 	enum MAPISTATUS		retval;
@@ -93,7 +85,6 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		rowset;
 	const char	       	*name;
-	char			*newname;
 	const uint32_t		*child;
 	uint32_t		index;
 	const uint64_t		*fid;
@@ -108,7 +99,7 @@
 	if (retval != MAPI_E_SUCCESS) return false;
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
-					  PR_DISPLAY_NAME,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_FID,
 					  PR_FOLDER_CHILD_COUNT);
 	retval = SetColumns(&obj_htable, SPropTagArray);
@@ -118,15 +109,13 @@
 	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) {
 		for (index = 0; index < rowset.cRows; index++) {
 			fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID);
-			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
+			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE);
 			child = (const uint32_t *)find_SPropValue_data(&rowset.aRow[index], PR_FOLDER_CHILD_COUNT);
 
 			for (i = 0; i < count; i++) {
 				printf("|   ");
 			}
-			newname = utf8tolinux(mem_ctx, name);
-			printf("|---+ %-15s\n", newname);
-			MAPIFreeBuffer(newname);
+			printf("|---+ %-15s\n", name);
 			if (*child) {
 				ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
 				if (ret == false) return ret;
@@ -146,7 +135,6 @@
 	struct SPropTagArray	*SPropTagArray;
 	struct SRowSet		rowset;
 	mapi_object_t		obj_htable;
-	char			*newname;
 	const char		*name;
 	const uint64_t		*fid;
 	uint32_t		index;
@@ -156,7 +144,7 @@
 	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
 
 	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
-					  PR_DISPLAY_NAME,
+					  PR_DISPLAY_NAME_UNICODE,
 					  PR_FID);
 	retval = SetColumns(&obj_htable, SPropTagArray);
 	MAPIFreeBuffer(SPropTagArray);
@@ -165,15 +153,13 @@
 	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND) && rowset.cRows) {
 		for (index = 0; index < rowset.cRows; index++) {
 			fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[index], PR_FID);
-			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME);
+			name = (const char *)find_SPropValue_data(&rowset.aRow[index], PR_DISPLAY_NAME_UNICODE);
 
-			newname = utf8tolinux(mem_ctx, name);
-			if (newname && fid && !strcmp(newname, folder)) {
+			if (name && fid && !strcmp(name, folder)) {
 				retval = OpenFolder(obj_container, *fid, obj_child);
 				MAPI_RETVAL_IF(retval, GetLastError(), NULL);
 				return MAPI_E_SUCCESS;
 			}
-			MAPIFreeBuffer(newname);
 		}
 	}
 




More information about the Pkg-samba-maint mailing list