[Pkg-samba-maint] r2698 - in trunk/openchange: . doc doc/doxygen doc/doxygen/pictures doc/examples doc/man doc/man/man1 doc/man/man3 libmapi libmapi/conf libmapi/socket libmapi/tests libmapi/util libmapi++ libmapi++/examples libmapi++/impl libmapi++/tests libmapiadmin libocpf libocpf/examples mapiproxy mapiproxy/documentation mapiproxy/documentation/pictures mapiproxy/libmapiproxy mapiproxy/libmapiserver mapiproxy/libmapistore mapiproxy/libmapistore/backends mapiproxy/libmapistore/tests mapiproxy/modules mapiproxy/servers mapiproxy/servers/default mapiproxy/servers/default/emsmdb mapiproxy/servers/default/nspi mapiproxy/servers/default/rfr pymapi python python/openchange python/openchange/tests script setup setup/AD setup/openchangedb setup/profiles swig swig/perl swig/perl/tests testprogs testprogs/blackbox torture utils utils/backup utils/exchange2ical utils/mapitest utils/mapitest/modules utils/mapitrace utils/mapitrace/lib utils/mapitrace/lib/MAPI

jelmer at alioth.debian.org jelmer at alioth.debian.org
Tue Apr 14 14:39:23 UTC 2009


Author: jelmer
Date: 2009-04-14 14:39:21 +0000 (Tue, 14 Apr 2009)
New Revision: 2698

Added:
   trunk/openchange/.bzrignore
   trunk/openchange/COPYING
   trunk/openchange/ChangeLog
   trunk/openchange/Doxyfile.in
   trunk/openchange/IDL_LICENSE.txt
   trunk/openchange/Mainpage.doxy
   trunk/openchange/Makefile
   trunk/openchange/README
   trunk/openchange/VERSION
   trunk/openchange/autogen.sh
   trunk/openchange/bin/
   trunk/openchange/config.guess
   trunk/openchange/config.mk.in
   trunk/openchange/config.sub
   trunk/openchange/configure.ac
   trunk/openchange/doc/
   trunk/openchange/doc/doxygen/
   trunk/openchange/doc/doxygen/apidocs.css
   trunk/openchange/doc/doxygen/footer.html
   trunk/openchange/doc/doxygen/header.html
   trunk/openchange/doc/doxygen/index.html
   trunk/openchange/doc/doxygen/libmapi-concepts.doxy
   trunk/openchange/doc/doxygen/libmapi-examples.doxy
   trunk/openchange/doc/doxygen/libmapi-mainpage.doxy
   trunk/openchange/doc/doxygen/pictures/
   trunk/openchange/doc/doxygen/pictures/24px-Cc-by_white.svg.png
   trunk/openchange/doc/doxygen/pictures/24px-Cc-sa_white.svg.png
   trunk/openchange/doc/doxygen/pictures/CC_SomeRightsReserved.png
   trunk/openchange/doc/doxygen/pictures/body_top_bg2.jpg
   trunk/openchange/doc/doxygen/pictures/header.jpg
   trunk/openchange/doc/doxygen/pictures/middle_bg.jpg
   trunk/openchange/doc/doxygen/pictures/nav_tab.gif
   trunk/openchange/doc/doxygen/pictures/pixel_grey.gif
   trunk/openchange/doc/examples/
   trunk/openchange/doc/examples/Makefile
   trunk/openchange/doc/examples/fetchappointment.c
   trunk/openchange/doc/examples/fetchmail.c
   trunk/openchange/doc/examples/mapi_sample1.c
   trunk/openchange/doc/howto.txt
   trunk/openchange/doc/man/
   trunk/openchange/doc/man/man1/
   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/mapitest.1
   trunk/openchange/doc/man/man1/openchangeclient.1
   trunk/openchange/doc/man/man1/openchangepfadmin.1
   trunk/openchange/doc/man/man3/
   trunk/openchange/doc/man/man3/mapidump.3
   trunk/openchange/exchange.idl
   trunk/openchange/idl_types.h
   trunk/openchange/install-sh
   trunk/openchange/libmapi++/
   trunk/openchange/libmapi++/Doxyfile.in
   trunk/openchange/libmapi++/attachment.h
   trunk/openchange/libmapi++/clibmapi.h
   trunk/openchange/libmapi++/examples/
   trunk/openchange/libmapi++/examples/foldertree.cpp
   trunk/openchange/libmapi++/examples/messages.cpp
   trunk/openchange/libmapi++/folder.h
   trunk/openchange/libmapi++/impl/
   trunk/openchange/libmapi++/impl/message.ipp
   trunk/openchange/libmapi++/impl/object.ipp
   trunk/openchange/libmapi++/impl/session.ipp
   trunk/openchange/libmapi++/libmapi++-example.doxy
   trunk/openchange/libmapi++/libmapi++-mainpage.doxy
   trunk/openchange/libmapi++/libmapi++.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++/tests/
   trunk/openchange/libmapi++/tests/attach_test.cpp
   trunk/openchange/libmapi++/tests/test.cpp
   trunk/openchange/libmapi.pc.in
   trunk/openchange/libmapi/
   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/
   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/defs_private.h
   trunk/openchange/libmapi/dlinklist.h
   trunk/openchange/libmapi/emsmdb.c
   trunk/openchange/libmapi/emsmdb.h
   trunk/openchange/libmapi/freebusy.c
   trunk/openchange/libmapi/libmapi.h
   trunk/openchange/libmapi/lzfu.c
   trunk/openchange/libmapi/mapi_ctx.h
   trunk/openchange/libmapi/mapi_id_array.c
   trunk/openchange/libmapi/mapi_id_array.h
   trunk/openchange/libmapi/mapi_nameid.c
   trunk/openchange/libmapi/mapi_notification.h
   trunk/openchange/libmapi/mapi_object.c
   trunk/openchange/libmapi/mapi_object.h
   trunk/openchange/libmapi/mapi_profile.h
   trunk/openchange/libmapi/mapi_provider.h
   trunk/openchange/libmapi/mapidefs.h
   trunk/openchange/libmapi/mapidump.c
   trunk/openchange/libmapi/mapidump.h
   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/
   trunk/openchange/libmapi/socket/interface.c
   trunk/openchange/libmapi/socket/netif.c
   trunk/openchange/libmapi/socket/netif.h
   trunk/openchange/libmapi/tests/
   trunk/openchange/libmapi/tests/locale.c
   trunk/openchange/libmapi/tests/locale_codepage.c
   trunk/openchange/libmapi/utf8_convert.l
   trunk/openchange/libmapi/util/
   trunk/openchange/libmapi/util/codepage.c
   trunk/openchange/libmapi/util/lcid.c
   trunk/openchange/libmapi/utils.c
   trunk/openchange/libmapi/x500.c
   trunk/openchange/libmapiadmin.pc.in
   trunk/openchange/libmapiadmin/
   trunk/openchange/libmapiadmin/Doxyfile.in
   trunk/openchange/libmapiadmin/libmapiadmin-mainpage.doxy
   trunk/openchange/libmapiadmin/libmapiadmin.h
   trunk/openchange/libmapiadmin/mapiadmin.c
   trunk/openchange/libmapiadmin/mapiadmin_user.c
   trunk/openchange/libocpf.pc.in
   trunk/openchange/libocpf/
   trunk/openchange/libocpf/Doxyfile.in
   trunk/openchange/libocpf/examples/
   trunk/openchange/libocpf/examples/common_OLEGUID.ocpf
   trunk/openchange/libocpf/examples/sample_appointment.ocpf
   trunk/openchange/libocpf/examples/sample_task.ocpf
   trunk/openchange/libocpf/lex.h
   trunk/openchange/libocpf/lex.l
   trunk/openchange/libocpf/ocpf-documentation.doxy
   trunk/openchange/libocpf/ocpf.h
   trunk/openchange/libocpf/ocpf.y
   trunk/openchange/libocpf/ocpf_api.c
   trunk/openchange/libocpf/ocpf_api.h
   trunk/openchange/libocpf/ocpf_dump.c
   trunk/openchange/libocpf/ocpf_dump.h
   trunk/openchange/libocpf/ocpf_private.h
   trunk/openchange/libocpf/ocpf_public.c
   trunk/openchange/libocpf/ocpf_write.c
   trunk/openchange/mapiproxy/
   trunk/openchange/mapiproxy/Doxyfile.in
   trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy.h
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_proto.h
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_rfr.c
   trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c
   trunk/openchange/mapiproxy/documentation/
   trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy
   trunk/openchange/mapiproxy/documentation/pictures/
   trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_false_nspi.png
   trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true.png
   trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true_custom_nspi.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_emsmdb_graph.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001_fix.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_002.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_hook_life.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_overview.png
   trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_struct.png
   trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_one.png
   trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_two.png
   trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_pack.png
   trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_unpack.png
   trunk/openchange/mapiproxy/documentation/pictures/mpm_stack.png
   trunk/openchange/mapiproxy/libmapiproxy.pc.in
   trunk/openchange/mapiproxy/libmapiproxy/
   trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c
   trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c
   trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.c
   trunk/openchange/mapiproxy/libmapiproxy/entryid.c
   trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
   trunk/openchange/mapiproxy/libmapiproxy/mapi_handles.c
   trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c
   trunk/openchange/mapiproxy/libmapiserver.pc.in
   trunk/openchange/mapiproxy/libmapiserver/
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcnotif.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c
   trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c
   trunk/openchange/mapiproxy/libmapistore.pc.in
   trunk/openchange/mapiproxy/libmapistore/
   trunk/openchange/mapiproxy/libmapistore/backends/
   trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.c
   trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h
   trunk/openchange/mapiproxy/libmapistore/mapistore.h
   trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_errors.h
   trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_private.h
   trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c
   trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c
   trunk/openchange/mapiproxy/libmapistore/tests/
   trunk/openchange/mapiproxy/libmapistore/tests/mapistore_test.c
   trunk/openchange/mapiproxy/modules/
   trunk/openchange/mapiproxy/modules/mpm_cache.c
   trunk/openchange/mapiproxy/modules/mpm_cache.h
   trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c
   trunk/openchange/mapiproxy/modules/mpm_cache_stream.c
   trunk/openchange/mapiproxy/modules/mpm_downgrade.c
   trunk/openchange/mapiproxy/modules/mpm_dummy.c
   trunk/openchange/mapiproxy/modules/mpm_pack.c
   trunk/openchange/mapiproxy/servers/
   trunk/openchange/mapiproxy/servers/default/
   trunk/openchange/mapiproxy/servers/default/emsmdb/
   trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.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/emsmdb/oxcfold.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c
   trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c
   trunk/openchange/mapiproxy/servers/default/nspi/
   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/mapiproxy/servers/default/rfr/
   trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c
   trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.h
   trunk/openchange/missing
   trunk/openchange/ndr_mapi.c
   trunk/openchange/property.idl
   trunk/openchange/pymapi/
   trunk/openchange/pymapi/msg_store.c
   trunk/openchange/pymapi/object.c
   trunk/openchange/pymapi/pymapi.c
   trunk/openchange/pymapi/pymapi.h
   trunk/openchange/pymapi/session.c
   trunk/openchange/python/
   trunk/openchange/python/openchange/
   trunk/openchange/python/openchange/__init__.py
   trunk/openchange/python/openchange/mailbox.py
   trunk/openchange/python/openchange/provision.py
   trunk/openchange/python/openchange/tests/
   trunk/openchange/python/openchange/tests/__init__.py
   trunk/openchange/python/openchange/tests/test_mailbox.py
   trunk/openchange/python/openchange/tests/test_provision.py
   trunk/openchange/script/
   trunk/openchange/script/check_exchange
   trunk/openchange/script/installman.sh
   trunk/openchange/script/installoc.sh
   trunk/openchange/script/installsamba4.sh
   trunk/openchange/script/mapi_object_init.prop
   trunk/openchange/script/mkproto.pl
   trunk/openchange/script/mkrelease.sh
   trunk/openchange/script/mkversion.sh
   trunk/openchange/script/samba4_ver.sh
   trunk/openchange/script/uninstallman.sh
   trunk/openchange/script/uno.dfn
   trunk/openchange/setup/
   trunk/openchange/setup/AD/
   trunk/openchange/setup/AD/oc_provision_configuration.ldif
   trunk/openchange/setup/AD/oc_provision_schema.ldif
   trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif
   trunk/openchange/setup/AD/oc_provision_schema_modify.ldif
   trunk/openchange/setup/AD/prefixMap.txt
   trunk/openchange/setup/AD/provision_schema_basedn_modify.ldif
   trunk/openchange/setup/openchange_newuser
   trunk/openchange/setup/openchange_provision
   trunk/openchange/setup/openchangedb/
   trunk/openchange/setup/openchangedb/oc_provision_openchange_init.ldif
   trunk/openchange/setup/openchangedb/oc_provision_openchange_mailbox.ldif
   trunk/openchange/setup/profiles/
   trunk/openchange/setup/profiles/oc_profiles_init.ldif
   trunk/openchange/setup/profiles/oc_profiles_schema.ldif
   trunk/openchange/swig/
   trunk/openchange/swig/perl/
   trunk/openchange/swig/perl/Makefile
   trunk/openchange/swig/perl/lwmapi.c
   trunk/openchange/swig/perl/mapi.i
   trunk/openchange/swig/perl/tests/
   trunk/openchange/swig/perl/tests/fetchmail.pl
   trunk/openchange/testprogs/
   trunk/openchange/testprogs/blackbox/
   trunk/openchange/testprogs/blackbox/subunit.sh
   trunk/openchange/testprogs/blackbox/test_mapiprofile.sh
   trunk/openchange/torture/
   trunk/openchange/torture/exchange_createuser.c
   trunk/openchange/torture/mapi_bookmark.c
   trunk/openchange/torture/mapi_common.c
   trunk/openchange/torture/mapi_copymail.c
   trunk/openchange/torture/mapi_createuser.c
   trunk/openchange/torture/mapi_criteria.c
   trunk/openchange/torture/mapi_deletemail.c
   trunk/openchange/torture/mapi_fetchappointment.c
   trunk/openchange/torture/mapi_fetchattach.c
   trunk/openchange/torture/mapi_fetchcontacts.c
   trunk/openchange/torture/mapi_fetchmail.c
   trunk/openchange/torture/mapi_fetchtasks.c
   trunk/openchange/torture/mapi_namedprops.c
   trunk/openchange/torture/mapi_newmail.c
   trunk/openchange/torture/mapi_permissions.c
   trunk/openchange/torture/mapi_recipient.c
   trunk/openchange/torture/mapi_restrictions.c
   trunk/openchange/torture/mapi_sendappointment.c
   trunk/openchange/torture/mapi_sendattach.c
   trunk/openchange/torture/mapi_sendcontacts.c
   trunk/openchange/torture/mapi_sendmail.c
   trunk/openchange/torture/mapi_sendmail_html.c
   trunk/openchange/torture/mapi_sendtasks.c
   trunk/openchange/torture/mapi_sorttable.c
   trunk/openchange/torture/mapi_torture.h
   trunk/openchange/torture/nspi_profile.c
   trunk/openchange/torture/nspi_resolvenames.c
   trunk/openchange/torture/openchange.c
   trunk/openchange/utils/
   trunk/openchange/utils/backup/
   trunk/openchange/utils/backup/openchangebackup.c
   trunk/openchange/utils/backup/openchangebackup.h
   trunk/openchange/utils/backup/openchangemapidump.c
   trunk/openchange/utils/exchange2ical/
   trunk/openchange/utils/exchange2ical/exchange2ical.c
   trunk/openchange/utils/exchange2ical/exchange2ical.h
   trunk/openchange/utils/exchange2ical/exchange2ical_component.c
   trunk/openchange/utils/exchange2ical/exchange2ical_property.c
   trunk/openchange/utils/exchange2ical/exchange2ical_utils.c
   trunk/openchange/utils/exchange2mbox.c
   trunk/openchange/utils/mapiprofile.c
   trunk/openchange/utils/mapitest/
   trunk/openchange/utils/mapitest/Doxyfile.in
   trunk/openchange/utils/mapitest/mapitest.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/
   trunk/openchange/utils/mapitest/modules/mapitest.doxy
   trunk/openchange/utils/mapitest/modules/module_errorchecks.c
   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/mapitest/modules/module_oxorule.c
   trunk/openchange/utils/mapitrace/
   trunk/openchange/utils/mapitrace/Makefile.PL
   trunk/openchange/utils/mapitrace/lib/
   trunk/openchange/utils/mapitrace/lib/MAPI/
   trunk/openchange/utils/mapitrace/lib/MAPI/Dump_EcDoRpc.pm
   trunk/openchange/utils/mapitrace/lib/MAPI/EcDoRpc.pm
   trunk/openchange/utils/mapitrace/lib/MAPI/Graph.pm
   trunk/openchange/utils/mapitrace/lib/MAPI/Regression.pm
   trunk/openchange/utils/mapitrace/lib/MAPI/Statistic.pm
   trunk/openchange/utils/mapitrace/mapitrace
   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
   trunk/openchange/utils/openchangepfadmin.h
   trunk/openchange/utils/schemaIDGUID.c
Log:
Merge in upstream source.


Added: trunk/openchange/.bzrignore
===================================================================
--- trunk/openchange/.bzrignore	                        (rev 0)
+++ trunk/openchange/.bzrignore	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,66 @@
+aclocal.m4
+config.h
+config.h.in
+config.log
+config.status
+libmapi.pc
+configure
+gen_ndr
+libmapi/mapicode.c
+libmapi/mapicode.h
+libmapi/mapitags.c
+libmapi/mapitags.h
+libmapi/proto.h
+libmapi/utf8_convert.yy.c
+server/dcesrv_proto.h
+torture/torture_proto.h
+libmapi.so.*
+mapicodes_enum.h
+mapitags_enum.h
+bin/exchange2mbox
+bin/locale_codepage
+bin/mapiprofile
+bin/openchangeclient
+bin/schemaIDGUID
+libmapi/proto_private.h
+providers/providers_proto.h
+tags
+*.pc
+*.so.*
+bin/openchangepfadmin
+libmapiadmin/proto.h
+libmapiadmin/proto_private.h
+bin/openchangemapidump
+*.po
+libmapi/mapi_nameid_private.h
+Doxyfile
+libmapi/version.h
+config.mk
+swig/perl/Makefile
+libocpf/ocpf.tab.c
+libocpf/ocpf.tab.c
+libocpf/lex.yy.c
+bin/mapitest
+libocpf/proto.h
+libocpf/proto_private.h
+libocpf/proto_private.h
+libocpf/ocpf.tab.h
+autom4te.cache
+apidocs
+swig/perl/mapi.pm
+swig/perl/mapi_wrap.c
+swig/perl/swig_mapicodes.h
+swig/perl/swig_mapitags.h
+utils/mapitest/mapitest_proto.h
+utils/mapitest/proto.h
+samba4
+tags
+bin/exchange2ical
+libmapi/mapi_namedid.h
+libmapi/mapi_nameid.h
+bin/libmapixx-attach
+bin/libmapixx-test
+libmapi++/examples/foldertree
+libmapi++/examples/messages
+bin/mapistore_test
+_trial_temp

Added: trunk/openchange/COPYING
===================================================================
--- trunk/openchange/COPYING	                        (rev 0)
+++ trunk/openchange/COPYING	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

Added: trunk/openchange/ChangeLog
===================================================================
--- trunk/openchange/ChangeLog	                        (rev 0)
+++ trunk/openchange/ChangeLog	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,4186 @@
+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/Doxyfile.in
===================================================================
--- trunk/openchange/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1274 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = OpenChange
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =  *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c *_private.h
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed \
+		         -e 's/.*\<libmapi\/proto_private.h\>//'	\
+			 -e 's/.*\<gen_ndr\/ndr_exchange.h\>//'		\
+			 -e 's/.*\<param.h\>//'				\
+			 -e 's/.*\<core\/error.h\>//'			\
+			 -e 's/.*\<credentials.h\>//'			\
+			 -e 's/.*\<ldb.h\>//'				\
+			 -e 's/.*\<ldb_errors.h\>//'			\
+			 -e 's/.*\<libmapi\/dlinklist.h\>//'		\
+			 -e 's/.*\<libmapi\/mapi_nameid.h\>//'		\
+			 -e 's/.*\<libmapi\/mapi_nameid_private.h\>//'	\
+			 -e 's/.*\<libocpf\/proto_private.h\>//'	\
+			 -e 's/.*\<libocpf\/ocpf_api.h\>//'		\
+			 -e 's/.*\<libocpf\/ocpf.tab.h\>//'		\
+			 -e 's/.*\<libgen.h\>//'			\
+			 -e 's/.*\<time.h\>//'				\
+			 -e 's/.*\<sys\/*\>//'				\
+                         -e 's/_PUBLIC_//'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/overview
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/IDL_LICENSE.txt
===================================================================
--- trunk/openchange/IDL_LICENSE.txt	                        (rev 0)
+++ trunk/openchange/IDL_LICENSE.txt	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,9 @@
+The IDL files in this directory are made available by the OpenChange Team
+under the following license:
+
+  Permission to use, copy, modify, and distribute these interface
+  definitions for any purpose is hereby granted without fee.
+
+  This work 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.

Added: trunk/openchange/Mainpage.doxy
===================================================================
--- trunk/openchange/Mainpage.doxy	                        (rev 0)
+++ trunk/openchange/Mainpage.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,43 @@
+/** @mainpage The OpenChange Library API Reference
+
+This is the online reference for developing with the OpenChange client
+libraries.
+
+Among other things, the OpenChange client libraries provide:
+- MAPI client library (<a href="../libmapi/index.html">libmapi</a>)
+- MAPI administration libraries (<a href="../libmapiadmin/index.html">libmapiadmin</a>)
+- OpenChange Property Files (<a href="../libocpf/index.html">libocpf</a>)
+- A regression test framework (<a href="../mapitest/index.html">mapitest</a>)
+- MAPIProxy project (<a href="../mapiproxy/index.html">mapiproxy</a>)
+- C++ bindings for libmapi (<a href="../libmapi++/index.html">libmapi++</a>)
+
+<h2>OpenChange Project Goals</h2>
+
+The OpenChange Project aims to provide a portable Open Source
+implementation of Microsoft Exchange Server and Exchange
+protocols. Exchange is a groupware server designed to work with
+Microsoft Outlook, and providing features such as a messaging server,
+shared calendars, contact databases, public folders, notes and tasks.
+
+The OpenChange project has three goals:
+
+- To provide a library for interoperability with Exchange
+protocols, and to assist implementors to use this to create
+groupware that interoperates with both Exchange and other
+OpenChange-based software.
+
+- To provide an alternative to Microsoft Exchange Server which uses
+native Exchange protocols and provides exactly equivalent
+functionality when viewed from Microsoft Outlook clients.
+
+- To develop a body of knowledge about the most popular groupware
+protocols in use commercially today in order to promote  development
+of a documented and unencumbered standard, with all the  benefits that
+standards bring.
+
+<h2>More information</h2>
+
+Visit the <a href="http://www.openchange.org">OpenChange web site</a> for
+other useful information.
+
+*/

Added: trunk/openchange/Makefile
===================================================================
--- trunk/openchange/Makefile	                        (rev 0)
+++ trunk/openchange/Makefile	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1477 @@
+# Makefile for OpenChange
+# Written by Jelmer Vernooij <jelmer at openchange.org>, 2005.
+
+default: all
+
+# Until we add proper dependencies for all the C files:
+.NOTPARALLEL:
+
+config.mk: config.status config.mk.in
+	./config.status
+
+config.status: configure
+	./configure
+
+configure: configure.ac
+	./autogen.sh
+
+samba:
+	./script/installsamba4.sh all
+
+samba-git: 
+	./script/installsamba4.sh git-all
+
+ifneq ($(MAKECMDGOALS), samba)
+ifneq ($(MAKECMDGOALS), samba-git)
+include config.mk
+endif
+endif
+
+#################################################################
+# top level compilation rules
+#################################################################
+
+all: 		$(OC_IDL)		\
+		$(OC_LIBS)		\
+		$(OC_TOOLS)		\
+		$(OC_TORTURE)		\
+		$(OC_SERVER)		\
+		$(SWIGDIRS-ALL)		\
+		$(PYMAPIALL)
+
+install: 	all 			\
+		installlib 		\
+		installpc 		\
+		installheader 		\
+		$(OC_TOOLS_INSTALL) 	\
+		$(OC_SERVER_INSTALL) 	\
+		$(OC_TORTURE_INSTALL) 	\
+		$(SWIGDIRS-INSTALL) 	\
+		$(PYMAPIINSTALL) \
+		installnagios
+
+installlib:	$(OC_LIBS_INSTALL)
+installpc:	$(OC_LIBS_INSTALLPC)
+installheader:	$(OC_LIBS_INSTALLHEADERS)
+
+uninstall:: 	$(OC_LIBS_UNINSTALL) 	\
+		$(OC_TOOLS_UNINSTALL) 	\
+		$(OC_SERVER_UNINSTALL) 	\
+		$(OC_TORTURE_UNINSTALL) \
+		$(SWIGDIRS-UNINSTALL) \
+		$(PYMAPIUNINSTALL)
+
+distclean:: clean
+	rm -rf autom4te.cache
+	rm -f Doxyfile
+	rm -f libmapi/Doxyfile
+	rm -f libmapiadmin/Doxyfile
+	rm -f libocpf/Doxyfile
+	rm -f libmapi++/Doxyfile
+	rm -f mapiproxy/Doxyfile
+	rm -f config.status config.log
+	rm -f stamp-h1
+	rm -f utils/mapitest/Doxyfile
+	rm -f intltool-extract intltool-merge intltool-update
+	rm -rf apidocs
+	rm -rf gen_ndr
+	rm -f tags
+
+clean::
+	rm -f *~
+	rm -f */*~
+	rm -f */*/*~
+	rm -f doc/examples/mapi_sample1
+	rm -f doc/examples/fetchappointment
+	rm -f doc/examples/fetchmail
+
+re:: clean install
+
+#################################################################
+# Suffixes compilation rules
+#################################################################
+
+.SUFFIXES: .c .o .h .po .idl
+
+.idl.h:
+	@echo "Generating $@"
+	@$(PIDL) --outputdir=gen_ndr --header -- $<
+
+.c.o:
+	@echo "Compiling $<"
+	@$(CC) $(CFLAGS) -c $< -o $@
+
+.c.po:
+	@echo "Compiling $< with -fPIC"
+	@$(CC) $(CFLAGS) -fPIC -c $< -o $@
+
+
+
+#################################################################
+# IDL compilation rules
+#################################################################
+
+idl: gen_ndr gen_ndr/ndr_exchange.h gen_ndr/ndr_property.h
+
+exchange.idl: mapitags_enum.h mapicodes_enum.h
+
+gen_ndr:
+	@echo "Creating the gen_ndr directory"
+	mkdir -p gen_ndr
+
+gen_ndr/ndr_%.h gen_ndr/ndr_%.c: %.idl %.h
+	@echo "Generating $@"
+	@$(PIDL) --outputdir=gen_ndr --ndr-parser -- $<
+
+gen_ndr/ndr_%_c.h gen_ndr/ndr_%_c.c: %.idl %.h
+	@echo "Generating $@"
+	@$(PIDL) --outputdir=gen_ndr --client -- $<
+
+gen_ndr/ndr_%_s.c: %.idl
+	@echo "Generating $@"
+	@$(PIDL) --outputdir=gen_ndr --server -- $<
+
+
+
+#################################################################
+# libmapi compilation rules
+#################################################################
+
+LIBMAPI_SO_VERSION = 0
+
+libmapi:	idl					\
+		libmapi/version.h			\
+		libmapi/proto.h				\
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)	
+
+libmapi-install:	libmapi			\
+			libmapi-installpc	\
+			libmapi-installlib	\
+			libmapi-installheader	\
+			libmapi-installscript
+
+libmapi-uninstall:	libmapi-uninstallpc	\
+			libmapi-uninstalllib	\
+			libmapi-uninstallheader	\
+			libmapi-uninstallscript
+
+libmapi-clean::
+	rm -f libmapi/*.o libmapi/*.po
+	rm -f libmapi/tests/*.o, libmapi/tests/*.po
+	rm -f libmapi/socket/*.o libmapi/socket/*.po
+	rm -f libmapi/util/*.o, libmapi/util/*.po
+	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/mapi_nameid.h libmapi/mapi_nameid_private.h
+	rm -f libmapi/proto.h
+	rm -f libmapi/proto_private.h
+	rm -f mapicodes_enum.h
+	rm -f mapitags_enum.h
+endif
+	rm -f gen_ndr/ndr_exchange*
+	rm -f gen_ndr/exchange.h
+	rm -f gen_ndr/ndr_property*
+	rm -f gen_ndr/property.h
+	rm -f ndr_mapi.o ndr_mapi.po
+	rm -f *~
+	rm -f */*~
+	rm -f */*/*~
+	rm -f libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) \
+		  libmapi.$(SHLIBEXT)
+
+clean:: libmapi-clean
+
+libmapi-distclean::
+	rm -f libmapi.pc
+
+distclean:: libmapi-distclean
+
+libmapi-installpc:
+	@echo "[*] install: libmapi pc files"
+	$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+	$(INSTALL) -m 0644 libmapi.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libmapi-installlib:
+	@echo "[*] install: libmapi library"
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(INSTALL) -m 0755 libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapi.$(SHLIBEXT)
+
+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/
+	$(INSTALL) -m 0644 libmapi/emsmdb.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_ctx.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_provider.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_id_array.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_notification.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_object.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_profile.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapi_nameid.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapidefs.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/version.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/mapicode.h $(DESTDIR)$(includedir)/libmapi/
+	$(INSTALL) -m 0644 libmapi/socket/netif.h $(DESTDIR)$(includedir)/libmapi/socket/
+	$(INSTALL) -m 0644 gen_ndr/exchange.h $(DESTDIR)$(includedir)/gen_ndr/
+	$(INSTALL) -m 0644 gen_ndr/property.h $(DESTDIR)$(includedir)/gen_ndr/
+
+libmapi-installscript:
+	$(INSTALL) -d $(DESTDIR)$(datadir)/setup/profiles
+	$(INSTALL) -m 0644 setup/profiles/oc_profiles* $(DESTDIR)$(datadir)/setup/profiles/
+
+libmapi-uninstallpc:
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapi.pc
+
+libmapi-uninstalllib:
+	rm -f $(DESTDIR)$(libdir)/libmapi.*
+
+libmapi-uninstallheader:
+	rm -rf $(DESTDIR)$(includedir)/libmapi
+	rm -f $(DESTDIR)$(includedir)/gen_ndr/exchange.h
+	rm -f $(DESTDIR)$(includedir)/gen_ndr/property.h
+
+libmapi-uninstallscript:
+	rm -f $(DESTDIR)$(datadir)/setup/profiles/oc_profiles*
+	rm -rf $(DESTDIR)$(datadir)/setup/profiles
+
+libmapi.$(SHLIBEXT).$(PACKAGE_VERSION): 		\
+	libmapi/IABContainer.po				\
+	libmapi/IProfAdmin.po				\
+	libmapi/IMAPIContainer.po			\
+	libmapi/IMAPIFolder.po				\
+	libmapi/IMAPIProp.po				\
+	libmapi/IMAPISession.po				\
+	libmapi/IMAPISupport.po				\
+	libmapi/IStream.po				\
+	libmapi/IMAPITable.po				\
+	libmapi/IMessage.po				\
+	libmapi/IMsgStore.po				\
+	libmapi/IStoreFolder.po				\
+	libmapi/IUnknown.po				\
+	libmapi/IMSProvider.po				\
+	libmapi/IXPLogon.po				\
+	libmapi/FXICS.po				\
+	libmapi/utils.po 				\
+	libmapi/property.po				\
+	libmapi/cdo_mapi.po 				\
+	libmapi/lzfu.po					\
+	libmapi/mapi_object.po				\
+	libmapi/mapi_id_array.po			\
+	libmapi/mapitags.po				\
+	libmapi/mapidump.po				\
+	libmapi/mapicode.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					\
+	gen_ndr/ndr_exchange.po				\
+	gen_ndr/ndr_exchange_c.po			\
+	gen_ndr/ndr_property.po				\
+	libmapi/socket/interface.po			\
+	libmapi/socket/netif.po				\
+	libmapi/utf8_convert.yy.po
+	@echo "Linking $@"
+	@$(CC) $(DSOOPT) -Wl,-soname,libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION) -o $@ $^ $(LIBS)
+
+
+libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION): libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	ln -fs $< $@
+
+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				\
+	libmapi/cdo_mapi.c				\
+	libmapi/simple_mapi.c				\
+	libmapi/mapitags.c				\
+	libmapi/mapicode.c				\
+	libmapi/mapidump.c				\
+	libmapi/mapi_object.c				\
+	libmapi/mapi_id_array.c				\
+	libmapi/mapi_nameid.c				\
+	libmapi/property.c				\
+	libmapi/IABContainer.c				\
+	libmapi/IProfAdmin.c				\
+	libmapi/IMAPIContainer.c			\
+	libmapi/IMAPIFolder.c 				\
+	libmapi/IMAPIProp.c 				\
+	libmapi/IMAPISession.c				\
+	libmapi/IMAPISupport.c				\
+	libmapi/IMAPITable.c 				\
+	libmapi/IMSProvider.c				\
+	libmapi/IMessage.c 				\
+	libmapi/IMsgStore.c 				\
+	libmapi/IStoreFolder.c				\
+	libmapi/IUnknown.c 				\
+	libmapi/IStream.c				\
+	libmapi/IXPLogon.c				\
+	libmapi/FXICS.c					\
+	libmapi/freebusy.c				\
+	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 $@"
+	@./script/mkproto.pl --private=libmapi/proto_private.h --public=libmapi/proto.h $^
+
+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/conf/mparse.pl
+	@./libmapi/conf/build.sh
+
+#################################################################
+# libmapi++ compilation rules
+#################################################################
+
+libmapixx: libmapi libmapixx-tests libmapixx-examples
+
+libmapixx-installpc:
+
+libmapixx-clean: libmapixx-tests-clean
+
+libmapixx-install: libmapixx-installheader
+
+libmapixx-uninstall: libmapixx-uninstallheader
+
+libmapixx-installheader:
+	@echo "[*] install: libmapi++ headers"
+	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapi++
+	$(INSTALL) -m 0644 libmapi++/attachment.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/clibmapi.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/folder.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/libmapi++.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/mapi_exception.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/message.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/message_store.h $(DESTDIR)$(includedir)/libmapi++/
+	$(INSTALL) -m 0644 libmapi++/object.h $(DESTDIR)$(includedir)/libmapi++/
+	$(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-uninstallheader:
+	rm -rf $(DESTDIR)$(includedir)/libmapi++
+
+
+libmapixx-tests:	libmapixx-test		\
+			libmapixx-attach
+
+libmapixx-tests-clean:	libmapixx-test-clean	\
+			libmapixx-attach-clean	
+
+libmapixx-test: bin/libmapixx-test
+
+libmapixx-test-clean:
+	rm -f bin/libmapixx-test
+	rm -f libmapi++/tests/*.o
+
+clean:: libmapixx-tests-clean
+
+bin/libmapixx-test:	libmapi++/tests/test.cpp	\
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking sample application $@"
+	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+
+clean:: libmapixx-test-clean
+
+libmapixx-attach: bin/libmapixx-attach
+
+libmapixx-attach-clean:
+	rm -f bin/libmapixx-attach
+	rm -f libmapi++/tests/*.o
+
+bin/libmapixx-attach: libmapi++/tests/attach_test.cpp	\
+		  libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking sample application $@"
+	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+
+clean:: libmapixx-attach-clean
+
+
+libmapixx-examples: libmapi++/examples/foldertree \
+		  libmapi++/examples/messages
+
+libmapixx-foldertree-clean:
+	rm -f libmapi++/examples/foldertree
+	rm -f libmapi++/examples/*.o
+
+libmapixx-messages-clean:
+	rm -f libmapi++/examples/messages
+	rm -f libmapi++/examples/*.o
+
+libmapi++/examples/foldertree: libmapi++/examples/foldertree.cpp	\
+		  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)
+	@echo "Linking messages example application $@"
+	@$(CXX) $(CXXFLAGS) -o $@ $^ $(LIBS)
+
+clean:: libmapixx-messages-clean
+
+#################################################################
+# libmapiadmin compilation rules
+#################################################################
+
+LIBMAPIADMIN_SO_VERSION = 0
+
+libmapiadmin:	libmapiadmin/proto.h				\
+		libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+libmapiadmin-install:	libmapiadmin-installpc		\
+			libmapiadmin-installlib		\
+			libmapiadmin-installheader
+
+libmapiadmin-uninstall:	libmapiadmin-uninstallpc	\
+			libmapiadmin-uninstalllib	\
+			libmapiadmin-uninstallheader
+
+libmapiadmin-clean::
+	rm -f libmapiadmin/*.o libmapiadmin/*.po
+ifneq ($(SNAPSHOT), no)
+	rm -f libmapiadmin/proto.h
+	rm -f libmapiadmin/proto_private.h
+endif
+	rm -f libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) \
+		  libmapiadmin.$(SHLIBEXT)
+
+clean:: libmapiadmin-clean
+
+libmapiadmin-distclean::
+	rm -f libmapiadmin.pc
+
+distclean:: libmapiadmin-distclean
+
+libmapiadmin-installpc:
+	@echo "[*] install: libmapiadmin pc files"
+	$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+	$(INSTALL) -m 0644 libmapiadmin.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libmapiadmin-installlib:
+	@echo "[*] install: libmapiadmin library"
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(INSTALL) -m 0755 libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiadmin.$(SHLIBEXT)
+
+libmapiadmin-installheader:
+	@echo "[*] install: libmapiadmin headers"
+	$(INSTALL) -d $(DESTDIR)$(includedir)/libmapiadmin 
+	$(INSTALL) -m 0644 libmapiadmin/proto.h $(DESTDIR)$(includedir)/libmapiadmin/
+	$(INSTALL) -m 0644 libmapiadmin/libmapiadmin.h $(DESTDIR)$(includedir)/libmapiadmin/
+
+libmapiadmin-uninstallpc:
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiadmin.pc
+
+libmapiadmin-uninstalllib:
+	rm -f $(DESTDIR)$(libdir)/libmapiadmin.*
+
+libmapiadmin-uninstallheader:
+	rm -rf $(DESTDIR)$(includedir)/libmapiadmin
+
+libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION):	\
+	libmapiadmin/mapiadmin_user.po		\
+	libmapiadmin/mapiadmin.po 		\
+	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) $(DSOOPT) -Wl,-soname,libmapiadmin.$(SHLIBEXT).$(LIBMAPIADMIN_SO_VERSION) -o $@ $^ $(LIBS) $(LIBMAPIADMIN_LIBS) 
+
+libmapiadmin/proto.h libmapiadmin/proto_private.h: 	\
+	libmapiadmin/mapiadmin.c 			\
+	libmapiadmin/mapiadmin_user.c			
+	@echo "Generating $@"
+	@./script/mkproto.pl -private=libmapiadmin/proto_private.h --public=libmapiadmin/proto.h $^
+
+
+
+#################################################################
+# libocpf compilation rules
+#################################################################
+
+LIBOCPF_SO_VERSION = 0
+
+libocpf:	libocpf/proto.h				\
+		libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+libocpf-install:	libocpf-installpc	\
+			libocpf-installlib	\
+			libocpf-installheader
+
+libocpf-uninstall:	libocpf-uninstallpc	\
+			libocpf-uninstalllib	\
+			libocpf-uninstallheader
+
+libocpf-clean::
+	rm -f libocpf/*.o libocpf/*.po
+ifneq ($(SNAPSHOT), no)
+	rm -f libocpf/lex.yy.c
+	rm -f libocpf/ocpf.tab.c libocpf/ocpf.tab.h
+	rm -f libocpf/proto.h
+	rm -f libocpf/proto_private.h
+endif
+	rm -f libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) \
+		  libocpf.$(SHLIBEXT)
+
+clean:: libocpf-clean
+
+libocpf-distclean::
+	rm -f libocpf.pc
+
+distclean:: libocpf-distclean
+
+libocpf-installpc:
+	@echo "[*] install: libocpf pc files"
+	$(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+	$(INSTALL) -m 0644 libocpf.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libocpf-installlib:
+	@echo "[*] install: libocpf library"
+	$(INSTALL) -d $(DESTDIR)$(libdir)
+	$(INSTALL) -m 0755 libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libocpf.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libocpf.$(SHLIBEXT)
+
+libocpf-installheader:
+	@echo "[*] install: libocpf headers"
+	$(INSTALL) -d $(DESTDIR)$(includedir)/libocpf
+	$(INSTALL) -m 0644 libocpf/ocpf.h $(DESTDIR)$(includedir)/libocpf/
+	$(INSTALL) -m 0644 libocpf/proto.h $(DESTDIR)$(includedir)/libocpf/
+
+libocpf-uninstallpc:
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libocpf.pc
+
+libocpf-uninstalllib:
+	rm -f $(DESTDIR)$(libdir)/libocpf.*
+
+libocpf-uninstallheader:
+	rm -rf $(DESTDIR)$(includedir)/libocpf
+
+libocpf.$(SHLIBEXT).$(PACKAGE_VERSION):		\
+	libocpf/ocpf.tab.po			\
+	libocpf/lex.yy.po			\
+	libocpf/ocpf_public.po			\
+	libocpf/ocpf_dump.po			\
+	libocpf/ocpf_api.po			\
+	libocpf/ocpf_write.po			\
+	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) $(DSOOPT) -Wl,-soname,libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION) -o $@ $^ $(LIBS)
+
+libocpf.$(SHLIBEXT).$(LIBOCPF_SO_VERSION): libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)
+	ln -fs $< $@
+
+libocpf/proto.h:	libocpf/ocpf_public.c	\
+			libocpf/ocpf_dump.c	\
+			libocpf/ocpf_api.c	\
+			libocpf/ocpf_write.c
+			@echo "Generating $@"
+			@./script/mkproto.pl --private=libocpf/proto_private.h \
+			--public=libocpf/proto.h $^
+
+libocpf/lex.yy.c:		libocpf/lex.l
+	@echo "Generating $@"
+	@$(FLEX) -t $< > $@
+
+libocpf/ocpf.tab.c:	libocpf/ocpf.y
+	@echo "Generating $@"
+	@$(BISON) -pocpf_yy -d $< -o $@
+
+# Avoid warnings
+libocpf/lex.yy.o: CFLAGS=
+libocpf/ocpf.tab.o: CFLAGS=
+
+
+
+#################################################################
+# torture suite compilation rules
+#################################################################
+
+torture:	torture/torture_proto.h		\
+		torture/openchange.$(SHLIBEXT)
+
+torture-install:
+	@echo "[*] install: openchange torture suite"
+	$(INSTALL) -d $(DESTDIR)$(TORTURE_MODULESDIR)
+	$(INSTALL) -m 0755 torture/openchange.$(SHLIBEXT) $(DESTDIR)$(TORTURE_MODULESDIR)
+
+torture-uninstall:
+	rm -f $(DESTDIR)$(TORTURE_MODULESDIR)/openchange.*
+
+torture-clean::
+	rm -f torture/*.$(SHLIBEXT)
+ifneq ($(SNAPSHOT), no)
+	rm -f torture/torture_proto.h
+endif
+	rm -f torture/*.o torture/*.po
+
+clean:: torture-clean
+
+torture/openchange.$(SHLIBEXT):			\
+	torture/nspi_profile.po			\
+	torture/nspi_resolvenames.po		\
+	torture/mapi_restrictions.po		\
+	torture/mapi_criteria.po		\
+	torture/mapi_copymail.po		\
+	torture/mapi_sorttable.po		\
+	torture/mapi_bookmark.po		\
+	torture/mapi_fetchmail.po		\
+	torture/mapi_sendmail.po		\
+	torture/mapi_sendmail_html.po		\
+	torture/mapi_deletemail.po		\
+	torture/mapi_newmail.po			\
+	torture/mapi_sendattach.po		\
+	torture/mapi_fetchattach.po		\
+	torture/mapi_fetchappointment.po	\
+	torture/mapi_sendappointment.po		\
+	torture/mapi_fetchcontacts.po		\
+	torture/mapi_sendcontacts.po		\
+	torture/mapi_fetchtasks.po		\
+	torture/mapi_sendtasks.po		\
+	torture/mapi_common.po			\
+	torture/mapi_permissions.po		\
+	torture/mapi_createuser.po		\
+	torture/exchange_createuser.po		\
+	torture/mapi_namedprops.po		\
+	torture/mapi_recipient.po		\
+	torture/openchange.po			\
+	libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS)
+
+torture/torture_proto.h: torture/mapi_restrictions.c	\
+	torture/mapi_criteria.c		\
+	torture/mapi_deletemail.c	\
+	torture/mapi_newmail.c		\
+	torture/mapi_fetchmail.c	\
+	torture/mapi_sendattach.c 	\
+	torture/mapi_sorttable.c	\
+	torture/mapi_bookmark.c		\
+	torture/mapi_copymail.c		\
+	torture/mapi_fetchattach.c	\
+	torture/mapi_sendmail.c		\
+	torture/mapi_sendmail_html.c	\
+	torture/nspi_profile.c 		\
+	torture/nspi_resolvenames.c	\
+	torture/mapi_fetchappointment.c	\
+	torture/mapi_sendappointment.c	\
+	torture/mapi_fetchcontacts.c	\
+	torture/mapi_sendcontacts.c	\
+	torture/mapi_fetchtasks.c	\
+	torture/mapi_sendtasks.c	\
+	torture/mapi_common.c		\
+	torture/mapi_permissions.c	\
+	torture/mapi_namedprops.c	\
+	torture/mapi_recipient.c	\
+	torture/mapi_createuser.c	\
+	torture/exchange_createuser.c	\
+	torture/openchange.c
+	@echo "Generating $@"
+	@./script/mkproto.pl --private=torture/torture_proto.h --public=torture/torture_proto.h $^
+
+#################################################################
+# mapiproxy compilation rules
+#################################################################
+LIBMAPIPROXY_SO_VERSION = 0
+LIBMAPISERVER_SO_VERSION = 0
+
+.PHONY: mapiproxy
+
+mapiproxy: 		idl 					\
+			libmapiproxy				\
+			libmapiserver				\
+			libmapistore				\
+			mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT) 	\
+			mapiproxy-modules			\
+			mapiproxy-servers
+
+mapiproxy-install: 	mapiproxy				\
+			mapiproxy-modules-install		\
+			mapiproxy-servers-install		\
+			libmapiproxy-install			\
+			libmapiserver-install			\
+			libmapistore-install
+	$(INSTALL) -d $(DESTDIR)$(SERVER_MODULESDIR)
+	$(INSTALL) -m 0755 mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT) $(DESTDIR)$(SERVER_MODULESDIR)
+
+mapiproxy-uninstall: 	mapiproxy-modules-uninstall		\
+			mapiproxy-servers-uninstall		\
+			libmapiproxy-uninstall			\
+			libmapiserver-uninstall			\
+			libmapistore-uninstall
+	rm -f $(DESTDIR)$(SERVER_MODULESDIR)/dcesrv_mapiproxy.*
+	rm -f $(DESTDIR)$(libdir)/libmapiproxy.*
+	rm -f $(DESTDIR)$(includedir)/libmapiproxy.h
+
+mapiproxy-clean:: 	mapiproxy-modules-clean			\
+			mapiproxy-servers-clean			\
+			libmapiproxy-clean			\
+			libmapiserver-clean			\
+			libmapistore-clean
+	rm -f mapiproxy/*.o mapiproxy/*.po
+	rm -f mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT)
+
+clean:: mapiproxy-clean
+
+
+mapiproxy/dcesrv_mapiproxy.$(SHLIBEXT): 	mapiproxy/dcesrv_mapiproxy.po		\
+						mapiproxy/dcesrv_mapiproxy_nspi.po	\
+						mapiproxy/dcesrv_mapiproxy_rfr.po	\
+						mapiproxy/dcesrv_mapiproxy_unused.po	\
+						ndr_mapi.po				\
+						gen_ndr/ndr_exchange.po				
+
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+mapiproxy/dcesrv_mapiproxy.c: gen_ndr/ndr_exchange_s.c gen_ndr/ndr_exchange.c
+
+
+###############
+# libmapiproxy
+###############
+
+libmapiproxy: mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+libmapiproxy-install:
+	$(INSTALL) -m 0755 mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiproxy.$(SHLIBEXT)
+	$(INSTALL) -m 0644 mapiproxy/libmapiproxy/libmapiproxy.h $(DESTDIR)$(includedir)/
+	$(INSTALL) -m 0644 mapiproxy/libmapiproxy.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libmapiproxy-clean:
+	rm -f mapiproxy/libmapiproxy/*.po mapiproxy/libmapiproxy/*.o
+ifneq ($(SNAPSHOT), no)
+	rm -f mapiproxy/libmapiproxy/openchangedb_property.c
+endif
+	rm -f mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+	rm -f mapiproxy/libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION)
+
+libmapiproxy-uninstall:
+	rm -f $(DESTDIR)$(libdir)/libmapiproxy.*
+	rm -f $(DESTDIR)$(includedir)/libmapiproxy.h
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiproxy.pc
+
+libmapiproxy-distclean:
+	rm -f mapiproxy/libmapiproxy.pc
+
+distclean::libmapiproxy-distclean
+
+mapiproxy/libmapiproxy/openchangedb_property.c: libmapi/conf/mapi-properties libmapi/conf/mparse.pl
+	@./libmapi/conf/mparse.pl --parser=openchangedb_property --outputdir=mapiproxy/libmapiproxy/ \
+				  libmapi/conf/mapi-properties
+
+mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION):	mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.po	\
+							mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.po	\
+							mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.po	\
+							mapiproxy/libmapiproxy/openchangedb.po			\
+							mapiproxy/libmapiproxy/openchangedb_property.po		\
+							mapiproxy/libmapiproxy/mapi_handles.po			\
+							mapiproxy/libmapiproxy/entryid.po			\
+							libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@$(CC) -o $@ $(DSOOPT) -Wl,-soname,libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) $^ -L. $(LIBS)
+
+mapiproxy/libmapiproxy.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION): libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+	ln -fs $< $@
+
+
+#################
+# libmapiserver
+#################
+
+libmapiserver: mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+libmapiserver-install:
+	$(INSTALL) -m 0755 mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapiserver.$(SHLIBEXT)
+	$(INSTALL) -m 0644 mapiproxy/libmapiserver/libmapiserver.h $(DESTDIR)$(includedir)/
+	$(INSTALL) -m 0644 mapiproxy/libmapiserver.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libmapiserver-clean:
+	rm -f mapiproxy/libmapiserver/*.po mapiproxy/libmapiserver/*.o
+	rm -f mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)
+	rm -f mapiproxy/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION)
+
+libmapiserver-uninstall:
+	rm -f $(DESTDIR)$(libdir)/libmapiserver.*
+	rm -f $(DESTDIR)$(includedir)/libmapiserver.h
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapiserver.pc
+
+libmapiserver-distclean:
+	rm -f mapiproxy/libmapiserver.pc
+
+distclean:: libmapiserver-distclean
+
+mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION):	mapiproxy/libmapiserver/libmapiserver_oxcstor.po	\
+							mapiproxy/libmapiserver/libmapiserver_oxcprpt.po	\
+							mapiproxy/libmapiserver/libmapiserver_oxcfold.po	\
+							mapiproxy/libmapiserver/libmapiserver_oxcnotif.po	
+	@$(CC) -o $@ $(DSOOPT) -Wl,-soname,libmapiserver.$(SHLIBEXT).$(LIBMAPIPROXY_SO_VERSION) $^
+
+mapiproxy/libmapiserver.$(SHLIBEXT).$(LIBMAPISERVER_SO_VERSION): libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)
+	ln -fs $< $@
+
+
+################
+# libmapistore
+################
+
+libmapistore: 	mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)	\
+		$(OC_MAPISTORE)						\
+		mapistore_test
+
+libmapistore-install:	$(OC_MAPISTORE_INSTALL)
+	$(INSTALL) -m 0755 mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)
+	ln -sf libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION) $(DESTDIR)$(libdir)/libmapistore.$(SHLIBEXT)
+	$(INSTALL) -d $(DESTDIR)$(includedir)/mapistore
+	$(INSTALL) -m 0644 mapiproxy/libmapistore/mapistore.h $(DESTDIR)$(includedir)/mapistore/
+	$(INSTALL) -m 0644 mapiproxy/libmapistore/mapistore_errors.h $(DESTDIR)$(includedir)/mapistore/
+	$(INSTALL) -m 0644 mapiproxy/libmapiserver.pc $(DESTDIR)$(libdir)/pkgconfig
+
+libmapistore-clean:	$(OC_MAPISTORE_CLEAN)
+	rm -f mapiproxy/libmapistore/*.po mapiproxy/libmapistore/*.o
+	rm -f mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
+	rm -f mapiproxy/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION)
+
+libmapistore-uninstall:	$(OC_MAPISTORE_UNINSTALL)
+	rm -f $(DESTDIR)$(libdir)/libmapistore.*
+	rm -rf $(DESTDIR)$(includedir)/mapistore
+	rm -f $(DESTDIR)$(libdir)/pkgconfig/libmapistore.pc
+
+libmapistore-distclean: libmapistore-clean
+	rm -f mapiproxy/libmapistore.pc
+
+distclean:: libmapistore-distclean
+
+mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION): 	mapiproxy/libmapistore/mapistore_interface.po	\
+							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)
+
+mapiproxy/libmapistore.$(SHLIBEXT).$(LIBMAPISTORE_SO_VERSION): libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+#####################
+# mapistore backends
+#####################
+
+mapistore_sqlite3: mapiproxy/libmapistore/backends/mapistore_sqlite3.$(SHLIBEXT)
+
+mapistore_sqlite3-install:
+	$(INSTALL) -d $(DESTDIR)$(libdir)/mapistore_backends
+	$(INSTALL) -m 0755 mapiproxy/libmapistore/backends/mapistore_sqlite3.$(SHLIBEXT) $(DESTDIR)$(libdir)/mapistore_backends/
+
+mapistore_sqlite3-uninstall:
+	rm -rf $(DESTDIR)$(libdir)/mapistore_backends
+
+mapistore_sqlite3-clean:
+	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.o
+	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.po
+
+clean:: mapistore_sqlite3-clean
+
+mapistore_sqlite3-distclean: mapistore_sqlite3-clean
+	rm -f mapiproxy/libmapistore/backends/mapistore_sqlite3.so
+
+distclean:: mapistore_sqlite3-distclean
+
+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) 	\
+	-Lmapiproxy mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+#######################
+# mapistore test tools
+#######################
+
+mapistore_test: bin/mapistore_test
+
+bin/mapistore_test: 	mapiproxy/libmapistore/tests/mapistore_test.o		\
+			mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+
+mapistore_clean:
+	rm -f mapiproxy/libmapistore/tests/*.o
+	rm -f bin/mapistore_test
+
+clean:: mapistore_clean
+
+####################
+# mapiproxy modules
+####################
+
+mapiproxy-modules:	mapiproxy/modules/mpm_downgrade.$(SHLIBEXT)	\
+			mapiproxy/modules/mpm_pack.$(SHLIBEXT)		\
+			mapiproxy/modules/mpm_cache.$(SHLIBEXT)		\
+			mapiproxy/modules/mpm_dummy.$(SHLIBEXT)		
+
+mapiproxy-modules-install: mapiproxy-modules
+	$(INSTALL) -d $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/
+	$(INSTALL) -m 0755 mapiproxy/modules/mpm_downgrade.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/
+	$(INSTALL) -m 0755 mapiproxy/modules/mpm_pack.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/
+	$(INSTALL) -m 0755 mapiproxy/modules/mpm_cache.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/
+	$(INSTALL) -m 0755 mapiproxy/modules/mpm_dummy.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy/
+
+mapiproxy-modules-uninstall:
+	rm -rf $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy
+
+mapiproxy-modules-clean::
+	rm -f mapiproxy/modules/*.o mapiproxy/modules/*.po
+	rm -f mapiproxy/modules/*.so
+
+clean:: mapiproxy-modules-clean
+
+mapiproxy/modules/mpm_downgrade.$(SHLIBEXT): mapiproxy/modules/mpm_downgrade.po
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+mapiproxy/modules/mpm_pack.$(SHLIBEXT):	mapiproxy/modules/mpm_pack.po	\
+					ndr_mapi.po			\
+					gen_ndr/ndr_exchange.po
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+mapiproxy/modules/mpm_cache.$(SHLIBEXT): mapiproxy/modules/mpm_cache.po		\
+					 mapiproxy/modules/mpm_cache_ldb.po	\
+					 mapiproxy/modules/mpm_cache_stream.po	\
+					 ndr_mapi.po				\
+					 gen_ndr/ndr_exchange.po
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+mapiproxy/modules/mpm_dummy.$(SHLIBEXT): mapiproxy/modules/mpm_dummy.po
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+
+####################
+# mapiproxy servers
+####################
+provision-install: python-install
+	$(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) -d $(DESTDIR)$(datadir)/setup/openchangedb
+	$(INSTALL) -m 0644 setup/openchangedb/oc_provision* $(DESTDIR)$(datadir)/setup/openchangedb/
+
+provision-uninstall: python-uninstall
+	rm -f $(DESTDIR)$(datadir)/setup/AD/oc_provision_configuration.ldif
+	rm -f $(DESTDIR)$(datadir)/setup/AD/oc_provision_schema.ldif
+	rm -f $(DESTDIR)$(datadir)/setup/AD/oc_provision_schema_modify.ldif
+	rm -f $(DESTDIR)$(datadir)/setup/AD/oc_provision_schema_ADSC.ldif
+	rm -f $(DESTDIR)$(datadir)/setup/AD/prefixMap.txt
+	rm -rf $(DESTDIR)$(datadir)/setup/AD
+	rm -rf $(DESTDIR)$(datadir)/setup/openchangedb
+
+mapiproxy-servers:	mapiproxy/servers/exchange_nsp.$(SHLIBEXT)		\
+			mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT)		\
+			mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT)
+
+mapiproxy-servers-install: mapiproxy-servers provision-install
+	$(INSTALL) -d $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/
+	$(INSTALL) -m 0755 mapiproxy/servers/exchange_nsp.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/
+	$(INSTALL) -m 0755 mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/
+	$(INSTALL) -m 0755 mapiproxy/servers/exchange_ds_rfr.$(SHLIBEXT) $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server/
+
+mapiproxy-servers-uninstall: provision-uninstall
+	rm -rf $(DESTDIR)$(modulesdir)/dcerpc_mapiproxy_server
+
+mapiproxy-servers-clean::
+	rm -f mapiproxy/servers/default/nspi/*.o mapiproxy/servers/default/nspi/*.po
+	rm -f mapiproxy/servers/default/emsmdb/*.o mapiproxy/servers/default/emsmdb/*.po
+	rm -f mapiproxy/servers/default/rfr/*.o mapiproxy/servers/default/rfr/*.po
+	rm -f mapiproxy/servers/*.so
+
+clean:: mapiproxy-servers-clean
+
+mapiproxy/servers/exchange_nsp.$(SHLIBEXT):	mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.po	\
+						mapiproxy/servers/default/nspi/emsabp.po		\
+						mapiproxy/servers/default/nspi/emsabp_tdb.po		\
+						mapiproxy/servers/default/nspi/emsabp_property.po	
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+mapiproxy/servers/exchange_emsmdb.$(SHLIBEXT):	mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.po	\
+						mapiproxy/servers/default/emsmdb/emsmdbp.po			\
+						mapiproxy/servers/default/emsmdb/emsmdbp_object.po		\
+						mapiproxy/servers/default/emsmdb/oxcstor.po			\
+						mapiproxy/servers/default/emsmdb/oxcprpt.po			\
+						mapiproxy/servers/default/emsmdb/oxcfold.po			\
+						mapiproxy/servers/default/emsmdb/oxcnotif.po			
+	@echo "Linking $@"
+	@$(CC) -o $@ $(DSOOPT) $^ -L. $(LIBS) -Lmapiproxy mapiproxy/libmapiproxy.$(SHLIBEXT).$(PACKAGE_VERSION) \
+						mapiproxy/libmapiserver.$(SHLIBEXT).$(PACKAGE_VERSION)		\
+						mapiproxy/libmapistore.$(SHLIBEXT).$(PACKAGE_VERSION)
+
+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)
+
+#################################################################
+# Tools compilation rules
+#################################################################
+
+###################
+# openchangeclient
+###################
+
+openchangeclient:	bin/openchangeclient
+
+openchangeclient-install:	openchangeclient
+	$(INSTALL) -d $(DESTDIR)$(bindir) 
+	$(INSTALL) -m 0755 bin/openchangeclient $(DESTDIR)$(bindir)
+
+openchangeclient-uninstall:
+	rm -f $(DESTDIR)$(bindir)/openchangeclient
+
+openchangeclient-clean::
+	rm -f bin/openchangeclient
+	rm -f utils/openchangeclient.o
+	rm -f utils/openchange-tools.o	
+
+clean:: openchangeclient-clean
+
+bin/openchangeclient: 	utils/openchangeclient.o			\
+			utils/openchange-tools.o			\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)		\
+			libocpf.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+
+
+##############
+# mapiprofile
+##############
+
+mapiprofile:		bin/mapiprofile
+
+mapiprofile-install:	mapiprofile
+	$(INSTALL) -d $(DESTDIR)$(bindir) 
+	$(INSTALL) -m 0755 bin/mapiprofile $(DESTDIR)$(bindir)
+
+mapiprofile-uninstall:
+	rm -f $(DESTDIR)$(bindir)/mapiprofile
+
+mapiprofile-clean::
+	rm -f bin/mapiprofile
+	rm -f utils/mapiprofile.o
+
+clean:: mapiprofile-clean
+
+bin/mapiprofile: 	utils/mapiprofile.o 			\
+			utils/openchange-tools.o 		\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+
+
+###################
+#openchangepfadmin
+###################
+
+openchangepfadmin:	bin/openchangepfadmin
+
+openchangepfadmin-install:	openchangepfadmin
+	$(INSTALL) -d $(DESTDIR)$(bindir) 
+	$(INSTALL) -m 0755 bin/openchangepfadmin $(DESTDIR)$(bindir)
+
+openchangepfadmin-uninstall:
+	rm -f $(DESTDIR)$(bindir)/openchangepfadmin
+
+openchangepfadmin-clean::
+	rm -f bin/openchangepfadmin
+	rm -f utils/openchangepfadmin.o
+
+clean:: openchangepfadmin-clean
+
+bin/openchangepfadmin:	utils/openchangepfadmin.o			\
+			utils/openchange-tools.o			\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION) 		\
+			libmapiadmin.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBMAPIADMIN_LIBS) -lpopt			
+
+
+###################
+# exchange2mbox
+###################
+
+exchange2mbox:		bin/exchange2mbox
+
+exchange2mbox-install:	exchange2mbox
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(INSTALL) -m 0755 bin/exchange2mbox $(DESTDIR)$(bindir)
+
+exchange2mbox-uninstall:
+	rm -f $(DESTDIR)$(bindir)/exchange2mbox
+
+exchange2mbox-clean::
+	rm -f bin/exchange2mbox
+	rm -f utils/exchange2mbox.o
+	rm -f utils/openchange-tools.o	
+
+clean:: exchange2mbox-clean
+
+bin/exchange2mbox:	utils/exchange2mbox.o				\
+			utils/openchange-tools.o			\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) -lpopt  $(MAGIC_LIBS)
+
+
+###################
+# exchange2ical
+###################
+
+exchange2ical:		bin/exchange2ical
+
+exchange2ical-install:	exchange2ical
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(INSTALL) -m 0755 bin/exchange2ical $(DESTDIR)$(bindir)
+
+exchange2ical-uninstall:
+	rm -f $(DESTDIR)$(bindir)/exchange2ical
+
+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	
+
+clean:: exchange2ical-clean
+
+bin/exchange2ical:	utils/exchange2ical/exchange2ical.o		\
+			utils/exchange2ical/exchange2ical_component.o	\
+			utils/exchange2ical/exchange2ical_property.o	\
+			utils/exchange2ical/exchange2ical_utils.o	\
+			utils/openchange-tools.o			\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LIBS) $(ICAL_LIBS) -lpopt
+
+
+###################
+# mapitest
+###################
+
+mapitest:	libmapi			\
+		utils/mapitest/proto.h 	\
+		bin/mapitest
+
+mapitest-install:	mapitest
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(INSTALL) -m 0755 bin/mapitest $(DESTDIR)$(bindir)
+
+mapitest-uninstall:
+	rm -f $(DESTDIR)$(bindir)/mapitest
+
+mapitest-clean:
+	rm -f bin/mapitest
+	rm -f utils/mapitest/*.o
+	rm -f utils/mapitest/modules/*.o
+ifneq ($(SNAPSHOT), no)
+	rm -f utils/mapitest/proto.h
+	rm -f utils/mapitest/mapitest_proto.h
+endif
+
+clean:: mapitest-clean
+
+bin/mapitest:	utils/mapitest/mapitest.o			\
+		utils/openchange-tools.o			\
+		utils/mapitest/mapitest_suite.o			\
+		utils/mapitest/mapitest_print.o			\
+		utils/mapitest/mapitest_stat.o			\
+		utils/mapitest/mapitest_common.o		\
+		utils/mapitest/module.o				\
+		utils/mapitest/modules/module_oxcstor.o		\
+		utils/mapitest/modules/module_oxcfold.o		\
+		utils/mapitest/modules/module_oxomsg.o		\
+		utils/mapitest/modules/module_oxcmsg.o		\
+		utils/mapitest/modules/module_oxcprpt.o		\
+		utils/mapitest/modules/module_oxctable.o	\
+		utils/mapitest/modules/module_oxorule.o		\
+		utils/mapitest/modules/module_oxcfxics.o	\
+		utils/mapitest/modules/module_nspi.o		\
+		utils/mapitest/modules/module_noserver.o	\
+		utils/mapitest/modules/module_errorchecks.o	\
+		utils/mapitest/modules/module_lcid.o		\
+		libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)		
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+
+utils/mapitest/proto.h:					\
+	utils/mapitest/mapitest_suite.c			\
+	utils/mapitest/mapitest_print.c			\
+	utils/mapitest/mapitest_stat.c			\
+	utils/mapitest/mapitest_common.c		\
+	utils/mapitest/module.c				\
+	utils/mapitest/modules/module_oxcstor.c		\
+	utils/mapitest/modules/module_oxcfold.c		\
+	utils/mapitest/modules/module_oxomsg.c		\
+	utils/mapitest/modules/module_oxcmsg.c		\
+	utils/mapitest/modules/module_oxcprpt.c		\
+	utils/mapitest/modules/module_oxctable.c	\
+	utils/mapitest/modules/module_oxorule.c		\
+	utils/mapitest/modules/module_oxcfxics.c	\
+	utils/mapitest/modules/module_nspi.c		\
+	utils/mapitest/modules/module_noserver.c	\
+	utils/mapitest/modules/module_errorchecks.c	\
+	utils/mapitest/modules/module_lcid.c
+	@echo "Generating $@"
+	@./script/mkproto.pl --private=utils/mapitest/mapitest_proto.h --public=utils/mapitest/proto.h $^
+
+#####################
+# openchangemapidump
+#####################
+
+openchangemapidump:		bin/openchangemapidump
+
+openchangemapidump-install:	openchangemapidump
+	$(INSTALL) -d $(DESTDIR)$(bindir)
+	$(INSTALL) -m 0755 bin/openchangemapidump $(DESTDIR)$(bindir)
+
+openchangemapidump-uninstall:
+	rm -f bin/openchangemapidump
+	rm -f $(DESTDIR)$(bindir)/openchangemapidump
+
+openchangemapidump-clean::
+	rm -f bin/openchangemapidump
+	rm -f utils/backup/openchangemapidump.o
+	rm -f utils/backup/openchangebackup.o
+
+clean:: openchangemapidump-clean
+
+bin/openchangemapidump:	utils/backup/openchangemapidump.o		\
+			utils/backup/openchangebackup.o			\
+			utils/openchange-tools.o			\
+			libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	@echo "Linking $@"
+	@$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) -lpopt
+
+
+###############
+# schemaIDGUID
+###############
+
+schemaIDGUID:		bin/schemaIDGUID
+
+schemaIDGUID-install:	schemaIDGUID
+	$(INSTALL) -m 0755 bin/schemaIDGUID $(DESTDIR)$(bindir)
+
+schemaIDGUID-uninstall:
+	rm -f $(DESTDIR)$(bindir)/schemaIDGUID
+
+schemaIDGUID-clean::
+	rm -f bin/schemaIDGUID
+	rm -f utils/schemaIDGUID.o
+
+clean:: schemaIDGUID-clean
+
+bin/schemaIDGUID: utils/schemaIDGUID.o
+	@echo "Linking $@"
+	@$(CC) -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
+###################
+
+pythonscriptdir = python
+
+pymapi: $(pythonscriptdir)/mapi.$(SHLIBEXT)
+
+pymapi/%: CFLAGS+=`$(PYTHON_CONFIG) --cflags` -fPIC
+
+$(pythonscriptdir)/mapi.$(SHLIBEXT): $(patsubst %.c,%.o,$(wildcard pymapi/*.c)) libmapi.$(SHLIBEXT).$(PACKAGE_VERSION)
+	$(CC) -o $@ $^ `$(PYTHON_CONFIG) --libs` $(DSOOPT)
+
+pymapi-install::
+	$(INSTALL) -d $(DESTDIR)$(PYCDIR)
+	$(INSTALL) -m 0755 $(pythonscriptdir)/mapi.$(SHLIBEXT) $(DESTDIR)$(PYCDIR)
+
+pymapi-uninstall::
+	rm -f $(DESTDIR)$(PYCDIR)/mapi.$(SHLIBEXT)
+
+PYTHON_MODULES = $(patsubst $(pythonscriptdir)/%,%,$(shell find  $(pythonscriptdir) -name "*.py"))
+
+python-install::
+	@echo "Installing Python modules"
+	@$(foreach MODULE, $(PYTHON_MODULES), \
+		$(INSTALL) -d $(DESTDIR)$(pythondir)/$(dir $(MODULE)); \
+		$(INSTALL) -m 0644 $(pythonscriptdir)/$(MODULE) $(DESTDIR)$(pythondir)/$(dir $(MODULE)); \
+	)
+
+python-uninstall::
+	rm -rf $(DESTDIR)$(pythondir)/openchange
+
+EPYDOC_OPTIONS = --no-private --url http://www.openchange.org/ --no-sourcecode
+
+epydoc::
+	PYTHONPATH=$(pythonscriptdir):$(PYTHONPATH) epydoc $(EPYDOC_OPTIONS) openchange
+
+check-python:
+	PYTHONPATH=$(pythonscriptdir):$(PYTHONPATH) trial openchange
+
+check:: check-python
+
+###################
+# nagios plugin
+###################
+
+nagiosdir = $(libdir)/nagios
+
+installnagios:
+	$(INSTALL) -d $(DESTDIR)$(nagiosdir)
+	$(INSTALL) -m 0755 script/check_exchange $(DESTDIR)$(nagiosdir)
+
+###################
+# libmapi examples
+###################
+examples:
+	cd doc/examples && make && cd ${OLD_PWD}
+
+examples-clean::
+	rm -f doc/examples/mapi_sample1
+	rm -f doc/examples/fetchappointment
+	rm -f doc/examples/fetchmail
+
+clean:: examples-clean
+
+examples-install examples-uninstall:
+
+manpages = \
+		doc/man/man1/exchange2mbox.1				\
+		doc/man/man1/mapiprofile.1				\
+		doc/man/man1/openchangeclient.1				\
+		doc/man/man1/openchangepfadmin.1			\
+		$(wildcard apidocs/man/man3/*)
+
+installman: doxygen
+	@./script/installman.sh $(DESTDIR)$(mandir) $(manpages)
+
+
+uninstallman:
+	@./script/uninstallman.sh $(DESTDIR)$(mandir) $(manpages)
+
+doxygen:	
+	@if test ! -d apidocs ; then						\
+		echo "Doxify API documentation: HTML and man pages";		\
+		mkdir -p apidocs/html;						\
+		mkdir -p apidocs/man;						\
+		$(DOXYGEN) Doxyfile;						\
+		$(DOXYGEN) libmapi/Doxyfile;					\
+		$(DOXYGEN) libmapiadmin/Doxyfile;				\
+		$(DOXYGEN) libocpf/Doxyfile;					\
+		$(DOXYGEN) libmapi++/Doxyfile;					\
+		$(DOXYGEN) mapiproxy/Doxyfile;					\
+		$(DOXYGEN) utils/mapitest/Doxyfile;				\
+		cp -f doc/doxygen/index.html apidocs/html;			\
+		cp -f doc/doxygen/pictures/* apidocs/html/overview;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/libmapi;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/libmapiadmin;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/libmapi++;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/libocpf;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/mapitest;		\
+		cp -f doc/doxygen/pictures/* apidocs/html/mapiproxy;		\
+		cp -f mapiproxy/documentation/pictures/* apidocs/html/mapiproxy;\
+		rm -f apidocs/man/man3/todo.3;					\
+		rm -f apidocs/man/man3/bug.3;					\
+		rm -f apidocs/man/man3/*.c.3;					\
+	fi								
+
+etags:
+	etags `find $(srcdir) -name "*.[ch]"`
+
+ctags:
+	ctags `find $(srcdir) -name "*.[ch]"`
+
+swigperl-all:
+	@echo "Creating Perl bindings ..."
+	@$(MAKE) -C swig/perl all
+
+swigperl-install:
+	@echo "Install Perl bindings ..."
+	@$(MAKE) -C swig/perl install
+
+swigperl-uninstall:
+	@echo "Uninstall Perl bindings ..."
+	@$(MAKE) -C swig/perl uninstall
+
+distclean::
+	@$(MAKE) -C swig/perl distclean
+
+clean::
+	@echo "Cleaning Perl bindings ..."
+	@$(MAKE) -C swig/perl clean
+
+.PRECIOUS: exchange.h gen_ndr/ndr_exchange.h gen_ndr/ndr_exchange.c gen_ndr/ndr_exchange_c.c gen_ndr/ndr_exchange_c.h
+
+test:: check
+
+check:: torture/openchange.$(SHLIBEXT) libmapi.$(SHLIBEXT).$(LIBMAPI_SO_VERSION)
+	# FIXME: Set up server
+	LD_LIBRARY_PATH=`pwd` $(SMBTORTURE) --load-module torture/openchange.$(SHLIBEXT) ncalrpc: OPENCHANGE
+	./bin/mapitest --mapi-calls 
+
+# This should be the last line in the makefile since other distclean rules may 
+# need config.mk
+distclean::
+	rm -f config.mk

Added: trunk/openchange/README
===================================================================
--- trunk/openchange/README	                        (rev 0)
+++ trunk/openchange/README	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,138 @@
+This is the README file for OpenChange
+
+ABOUT OPENCHANGE
+
+The OpenChange Project aims to provide a portable Open Source
+implementation of Microsoft Exchange Server and Exchange
+protocols. Exchange is a groupware server designed to work with
+Microsoft Outlook, and providing features such as a messaging server,
+shared calendars, contact databases, public folders, notes and tasks. 
+
+The OpenChange project has three goals:
+* To provide a library for interoperability with Exchange protocols, and
+to assist implementors to use this to create groupware that
+interoperates with both Exchange and other OpenChange-based software. 
+
+* To provide an alternative to Microsoft Exchange Server which uses
+native Exchange protocols and provides exactly equivalent
+functionality when viewed from Microsoft Outlook clients. 
+
+* To develop a body of knowledge about the most popular groupware
+protocols in use commercially today in order to promote development of
+a documented and unencumbered standard, with all the benefits that
+standards bring. 
+
+
+DOCUMENTATION
+
+There are two sources of documentation - text files in the doc/
+directory, and API documentation generated from the source files using
+doxygen. You can create the API documentation yourself (using "make
+doxygen" at the top level) or you can refer to the copy on the
+OpenChange web site at
+http://apidocs.openchange.org/overview/index.html
+
+doc/howto.txt contains instructions on how to install and set up
+client libraries, client utilities and the server / proxy parts of
+OpenChange.
+doc/man/ contains man(1) pages for several OpenChange utilities. Note
+that man pages for programming (i.e. the parts that would appear in
+man3) are generated by doxygen, and will be found in apidocs/ if you
+generate the documentation yourself.
+doc/doxygen/ provides static content used as part of the doxygen API
+documentation generation process.
+doc/examples/ provides programming examples for libmapi.
+
+
+STRUCTURE
+[TODO: add description of each directory]
+- bin/	This directory is created during the build process. It
+contains the binaries (executable programs) that are compiled during
+the "make" step. The source for most of these is in the utils/
+directory, described below.
+
+- doc/  This directory contains documentation - see description above
+(in DOCUMENTATION) for the various contents of this directory.
+
+- gen_ndr/  This directory contains routines for handling the Network
+Data Representation (NDR) for various Exhange RPC calls. The contents
+of this directory are generated (using Samba's pidl IDL compiler) at
+build time. The main input file is exchange.idl (see top level
+directory).
+
+- 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
+server. For more information, consult the API documentation (either
+build yourself, or online at
+http://apidocs.openchange.org/libmapi/index.html)
+
+- libmapi++/  This directory contains C++ bindings for libmapi. It is
+not a replacement for libmapi, but is intended to provide easier
+access to many libmapi functions for C++ programmers. For more
+information, consult the API documentation (either build yourself, or
+online at http://apidocs.openchange.org/libmapi++/index.html)
+
+- libmapiadmin/  This directory contains client-side library functions
+for administering OpenChange or Exchange servers. For more
+information, consult the API documentation (either build yourself, or
+online at http://apidocs.openchange.org/libmapiadmin/index.html). If
+you are looking for a program you can run, instead of library
+functions to write your own program, "openchangepfadmin" might be of
+interest.
+
+- libocpf/  This directory contains library functions for the
+OpenChange Property Files (OCPF). This allows building of mail
+messages, address book entries, appointments and similar objects from
+text files. For more information, consult the API documentation
+(either build yourself, or online at
+http://apidocs.openchange.org/libocpf/index.html) 
+
+- mapiproxy/ This directory provides an Exchange RPC proxy. You can
+use this to provide transparent proxying, or to change / monitor 
+connections between the client and server. For more information,
+consult the API documentation (either build yourself, or online at
+http://apidocs.openchange.org/mapiproxy/index.html) 
+
+- pymapi/  This directory contains hand-written python bindings for
+libmapi functions. There are also SWIG generated bindings - see the
+swig/ directory below.
+
+- python/  This directory contains python scripts used to set up
+("provision") the server side. They are not required for the client
+side.
+
+- 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.
+
+- script/  This directory contains a range of scripts useful for
+development or use of OpenChange. [TODO: document the scripts -
+perhaps write script/README?] 
+
+- setup/  This directory contains data for setting up ("provisioning")
+the server.
+
+- swig/  This directory contains support for SWIG
+(http://www.swig.org/) bindings generation.
+
+- testprogs/  This directory contains developer test tools
+
+- torture/  This directory contains modules to test openchange
+functionality using the Samba "smbtorture" framework. This is partly
+obsoleted by the standalone "mapitest" suite - see utils/mapitest/ below.
+
+- utils/  This directory contains the source code for a range of
+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/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
+ - utils/mapitrace/
+ - utils/openchangeclient	command line client for Exchange RPC
+ - utils/openchangepfadmin	Public Folders admin tools and 
+				administration of Exchange users (add/del) 
+ - utils/schemaIDGUID
+For more information on these tools, refer to the man(1) pages in doc/man/man1

Added: trunk/openchange/VERSION
===================================================================
--- trunk/openchange/VERSION	                        (rev 0)
+++ trunk/openchange/VERSION	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,29 @@
+########################################################
+# OPENCHANGE Version                                   #
+#                                                      #
+# script/mkversion.sh                                  #
+# will use this file to create                         #
+# libmapi/version.h                                    #
+#                                                      #
+########################################################
+
+########################################################
+# To mark SVN snapshots this should be set to 'yes'    #
+# in the development BRANCH, and set to 'no' only in   #
+# the release BRANCH                                   #
+#                                                      #
+# <MAJOR>.<MINOR>[...]-SVN-build-xxx                   #
+#                                                      #
+# e.g. OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes          #
+#  ->  "0.7-SVN-build-199"                             #
+########################################################
+OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes
+
+
+#############################################################
+# This is for specifying a release nickname                 #
+#                                                           #
+# e.g. OPENCHANGE_VERSION_RELEASE_NICKNAME=Nicky Nickname   #
+#  ->  "0.7 (Nicky Nickname)"                               #
+#############################################################
+OPENCHANGE_VERSION_RELEASE_NICKNAME=Cochrane

Added: trunk/openchange/autogen.sh
===================================================================
--- trunk/openchange/autogen.sh	                        (rev 0)
+++ trunk/openchange/autogen.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# Run this script to build openchange from SVN
+
+## insert all possible names (only works with
+## autoconf 2.x
+TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50 autoheader259 autoheader253"
+TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50 autoconf259 autoconf253"
+TESTACLOCAL="aclocal aclocal19"
+
+AUTOHEADERFOUND="0"
+AUTOCONFFOUND="0"
+ACLOCALFOUND="0"
+
+##
+## Look for autoheader
+##
+for i in $TESTAUTOHEADER; do
+        if which $i > /dev/null 2>&1; then
+                if test `$i --version | head -n 1 | cut -d.  -f 2 | tr -d [:alpha:]` -ge 53; then
+                        AUTOHEADER=$i
+                        AUTOHEADERFOUND="1"
+                        break
+                fi
+        fi
+done
+
+##
+## Look for autoconf
+##
+
+for i in $TESTAUTOCONF; do
+        if which $i > /dev/null 2>&1; then
+                if test `$i --version | head -n 1 | cut -d.  -f 2 | tr -d [:alpha:]` -ge 53; then
+                        AUTOCONF=$i
+                        AUTOCONFFOUND="1"
+                        break
+                fi
+        fi
+done
+
+##
+## Look for aclocal
+##
+for i in $TESTACLOCAL; do
+        if which $i > /dev/null 2>&1; then
+                ACLOCAL=$i              
+                ACLOCALFOUND="1"
+                break
+        fi
+done
+
+
+##
+## do we have it?
+##
+if test "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0"; then
+        echo "$0: need autoconf 2.53 or later to build samba from SVN" >&2
+        exit 1
+fi
+
+if test "$ACLOCALFOUND" = "0"; then
+        echo "$0: aclocal not found" >&2
+        exit 1
+fi
+
+
+rm -rf autom4te*.cache
+rm -f configure include/config.h*
+
+echo "$0: running $ACLOCAL"
+$ACLOCAL || exit 1
+
+echo "$0: running $AUTOHEADER"
+$AUTOHEADER || exit 1
+
+echo "$0: running $AUTOCONF"
+$AUTOCONF || exit 1
+
+
+rm -rf autom4te*.cache
+
+echo "Now run ./configure and make"
+exit 0


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

Added: trunk/openchange/config.guess
===================================================================
--- trunk/openchange/config.guess	                        (rev 0)
+++ trunk/openchange/config.guess	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1464 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-08-03'
+
+# This file 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/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:


Property changes on: trunk/openchange/config.guess
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/config.mk.in
===================================================================
--- trunk/openchange/config.mk.in	                        (rev 0)
+++ trunk/openchange/config.mk.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,109 @@
+# Mode (Release or snapshot?)
+SNAPSHOT=@OPENCHANGE_VERSION_IS_SVN_SNAPSHOT@
+
+# Binary
+CC=@CC@
+CXX=@CXX@
+BISON=@BISON@
+FLEX=@FLEX@
+PIDL=@PIDL@
+PERL=@PERL@
+DOXYGEN=@DOXYGEN@
+INSTALL=@INSTALL@
+PYTHON=@PYTON@
+PYTHON_CONFIG=@PYTHON_CONFIG@
+SMBTORTURE=@SMBTORTURE@
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+libdir=@libdir@
+modulesdir=@modulesdir@
+datarootdir=@datarootdir@
+datadir=@datadir@
+includedir=@includedir@
+mandir=@mandir@
+top_builddir=@builddir@
+pythondir=@pythondir@
+
+sambaprefix=@sambaprefix@
+
+DSOOPT=-shared -fPIC
+CFLAGS=@CFLAGS@ -I. -O3 -Wall -Wmissing-prototypes -Wstrict-prototypes -g3 -Wp,-D_FORTIFY_SOURCE=2	\
+	-fstrict-aliasing -Wstrict-aliasing=3	   		       	   				\
+	   -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\"							\
+	   -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\"				\
+	   -DMAPISTORE_MAPPING_PATH=\"$(prefix)/private/mapistore\"	
+
+# This value should be determined by configure at some point
+SHLIBEXT=so
+PACKAGE_VERSION=@PACKAGE_VERSION@
+
+# Portability hack...
+CFLAGS+=-Duint_t="unsigned int" 
+
+CFLAGS+=@SAMBA_CFLAGS@ @LDB_CFLAGS@ @TALLOC_CFLAGS@
+LIBS+=@SAMBA_LIBS@ @LDB_LIBS@ @TALLOC_LIBS@
+LDFLAGS+=@LDFLAGS@
+
+# Assign CFLAGS to CXXFLAGS
+CXXFLAGS=@CFLAGS@ -I. @SAMBA_CFLAGS@ @LDB_CFLAGS@ @TALLOC_CFLAGS@
+
+# OPENCHANGE LIBRARIES
+OC_IDL=@OC_IDL@
+OC_LIBS=@OC_LIBS@
+OC_LIBS_INSTALL=@OC_LIBS_INSTALL@
+OC_LIBS_UNINSTALL=@OC_LIBS_UNINSTALL@
+OC_LIBS_INSTALLPC=@OC_LIBS_INSTALLPC@
+OC_LIBS_INSTALLHEADER=@OC_LIBS_INSTALLHEADER@
+OC_LIBS_INSTALLLIB=@OC_LIBS_INSTALLLIB@
+LIBMAPIADMIN_LIBS+=@SAMR_LIBS@
+LIBMAPIADMIN_CFLAGS=@SAMR_CFLAGS@
+
+
+# TORTURE
+OC_TORTURE=@OC_TORTURE@
+OC_TORTURE_INSTALL=@OC_TORTURE_INSTALL@
+OC_TORTURE_UNINSTALL=@OC_TORTURE_UNINSTALL@
+SAMBA_MODULESDIR=${sambaprefix}/modules/
+TORTURE_MODULESDIR=${SAMBA_MODULESDIR}torture/
+SERVER_MODULESDIR=${SAMBA_MODULESDIR}dcerpc_server/
+
+# TOOLS
+OC_TOOLS=@OC_TOOLS@
+OC_TOOLS_INSTALL=@OC_TOOLS_INSTALL@
+OC_TOOLS_UNINSTALL=@OC_TOOLS_UNINSTALL@
+MAGIC_LIBS=@MAGIC_LIBS@
+ICAL_CFLAGS=@ICAL_CFLAGS@
+ICAL_LIBS=@ICAL_LIBS@
+
+# SERVER
+OC_SERVER=@OC_SERVER@
+OC_SERVER_INSTALL=@OC_SERVER_INSTALL@
+OC_SERVER_UNINSTALL=@OC_SERVER_UNINSTALL@
+
+# MAPISTORE BACKENDS
+OC_MAPISTORE=@OC_MAPISTORE@
+OC_MAPISTORE_CLEAN=@OC_MAPISTORE_CLEAN@
+OC_MAPISTORE_INSTALL=@OC_MAPISTORE_INSTALL@
+OC_MAPISTORE_UNINSTALL=@OC_MAPISTORE_UNINSTALL@
+
+SQLITE_CFLAGS=@SQLITE_CFLAGS@
+SQLITE_LIBS=@SQLITE_LIBS@
+
+# SWIG
+SWIGDIRS-ALL=@SWIGDIRSALL@
+SWIGDIRS-INSTALL=@SWIGDIRSINSTALL@
+SWIGDIRS-UNINSTALL=@SWIGDIRSUNINSTALL@
+
+SWIG=@SWIG@
+
+PERL5DIR=@PERL5DIR@
+
+# Python
+PYMAPIALL=@PYMAPIALL@
+PYMAPIINSTALL=@PYMAPIINSTALL@
+PYMAPIUNINSTALL=@PYMAPIUNINSTALL@
+
+PYCDIR=@PYCDIR@
+

Added: trunk/openchange/config.sub
===================================================================
--- trunk/openchange/config.sub	                        (rev 0)
+++ trunk/openchange/config.sub	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1577 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-07-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| ms1 \
+	| msp430 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m32c)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| ms1-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	m32c-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:


Property changes on: trunk/openchange/config.sub
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/configure.ac
===================================================================
--- trunk/openchange/configure.ac	                        (rev 0)
+++ trunk/openchange/configure.ac	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,580 @@
+# Simple configuration script for OpenChange
+# Written by Jelmer Vernooij <jelmer at openchange.org>
+
+AC_PREREQ(2.57)
+AC_INIT(openchange, 0.8, [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])
+
+dnl #################################################################
+dnl Check for OS dependent options
+dnl #################################################################
+AC_CANONICAL_HOST
+
+case "${host}" in
+     *freebsd*) BUILD_FOR_FREEBSD=yes ;;
+esac
+
+#
+# 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"
+	PKG_CONFIG_PATH="$1/lib/pkgconfig"
+	export PKG_CONFIG_PATH
+	PKG_CHECK_EXISTS([samba-hostconfig], [found=1], [found=0])
+	PKG_CONFIG_PATH="$old_PKG_CONFIG_PATH"
+	if test $found = 1; then
+		ifelse([$2],[], [echo -n ], [$2])
+		ifelse([$3],[],[],[else
+	[$3]])
+	fi
+])
+
+AC_MSG_CHECKING([for samba 4])
+
+AC_ARG_WITH(samba, 
+[AC_HELP_STRING([--with-samba], [Override location Samba is installed])],
+[ 
+ sambaprefix="$withval"
+],[
+ for p in "$prefix" /usr/local/samba /usr/local /usr
+ do
+	 OC_CHECK_SAMBA_PATH($p, [sambaprefix="$p"])
+ done
+])
+AC_SUBST(sambaprefix)
+OC_CHECK_SAMBA_PATH($sambaprefix,[], AC_MSG_ERROR(Samba 4 not found))
+AC_MSG_RESULT($sambaprefix)
+PKG_CONFIG_PATH="$sambaprefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+PATH="$sambaprefix/bin:$PATH"
+
+#
+# OC_SETVAL([NAME])
+# -----------------
+AC_DEFUN([OC_SETVAL],
+[
+AC_ARG_VAR([NAME], [var name])
+if test x"$enable_$1" = x""; then
+   enable_$1="no"
+fi[]
+])
+
+#
+# OC_CHECK_SAMBA_VERSION([RELEASE],[VERSION], [action-if-found],[action-if-not-found],
+#			       	 	      [action-if-cross-compiling])
+# ------------------------------------------------------------------------------------
+AC_DEFUN([OC_CHECK_SAMBA_VERSION], [
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <samba/version.h>
+int main() { if (!strcmp(SAMBA_VERSION_STRING, "$1") || !strcmp(SAMBA_VERSION_STRING, "$2")) {return 0; } else { return -1;} }
+]])],[$3],[
+	ifelse([$4],[],[AC_MSG_WARN([The Samba4 version installed on your system doesn't meet OpenChange requirements ($1 or $2).])],[$4])],[$5])
+])
+
+#
+# OC_RULE_ADD([NAME], [TYPE])
+# ---------------------------
+AC_DEFUN([OC_RULE_ADD], 
+[ 
+AC_ARG_VAR([NAME], [rule name])
+AC_ARG_VAR([TYPE], [rule type])
+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"
+
+		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"
+	;;
+	SERVER|MAPISTORE)
+		OC_$2+=" $1"
+		OC_$2_CLEAN+="$1-clean"
+		OC_$2_INSTALL+=" $1-install"
+   		OC_$2_UNINSTALL+=" $1-uninstall"
+	;;
+   esac
+
+   AC_SUBST(OC_$2)
+   AC_SUBST(OC_$2_CLEAN)
+   AC_SUBST(OC_$2_INSTALL)
+   AC_SUBST(OC_$2_UNINSTALL)
+
+   enable_$1="yes"
+
+fi[]
+])
+
+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"
+fi
+
+dnl ----------------------------------------------------------------------------
+dnl Check for comparison_fn_t
+dnl ----------------------------------------------------------------------------
+AC_CHECK_TYPE(comparison_fn_t, 
+[AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])])
+
+
+dnl ###########################################################################
+dnl libmapi and required dependencies
+dnl ###########################################################################
+
+dnl ---------------------------------------------------------------------------
+dnl Check for CC
+dnl ---------------------------------------------------------------------------
+AC_PROG_CC
+
+dnl ---------------------------------------------------------------------------
+dnl Check for install
+dnl ---------------------------------------------------------------------------
+AC_PROG_INSTALL
+
+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
+   AC_MSG_WARN([No version of perl was found!])
+   AC_MSG_ERROR([Please install perl http://www.perl.com])
+fi
+AC_SUBST(PERL)
+
+dnl ---------------------------------------------------------------------------
+dnl Check for Pidl
+dnl ---------------------------------------------------------------------------
+AC_PATH_PROG(PIDL, pidl)
+
+if test x"$PIDL" = x""; then
+   	AC_MSG_WARN([No version of pidl was found!])
+	AC_MSG_ERROR([Please install pidl])
+fi
+AC_SUBST(PIDL)
+
+dnl ---------------------------------------------------------------------------
+dnl Check for Python
+dnl ---------------------------------------------------------------------------
+
+AC_PATH_PROG(PYTHON,python)
+AC_PATH_PROG(PYTHON_CONFIG,python-config)
+
+AC_MSG_CHECKING(python library directory)
+pythondir=`$PYTHON -c "from distutils import sysconfig; print sysconfig.get_python_lib(1, 0, '\\${prefix}')"`
+AC_MSG_RESULT($pythondir)
+
+AC_SUBST(pythondir)
+
+dnl ----------------------------------------------------------------------------
+dnl Check for Flex
+dnl Flex version < 2.5.35 is fine but 2.5.4 beta is not. This is the
+dnl default version provided under FreeBSD or RHL5
+dnl ----------------------------------------------------------------------------
+if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then
+   AC_ARG_VAR([FLEX], [Location of the flex program.])
+   AC_CHECK_PROG([FLEX], [flex], [flex])
+
+   if test x"$FLEX" = x""; then
+      	AC_MSG_WARN([No version of flex was found!])
+	AC_MSG_ERROR([Please install flex])
+   else
+	V=`$FLEX --version | awk '{print $NF}'`
+   	W=`echo $V | awk -F. '{if (((($1*100 + $2)*100 + $3) > 20535) || $3 == 4) print "no"}'`
+   	if test "x$W" != x ; then
+	   AC_MSG_WARN([Adjust your FLEX environment variable])
+      	   AC_MSG_ERROR([Flex version 2.5.35 or below is needed. You have $V])
+      	fi
+   fi
+
+   AC_SUBST(FLEX)
+fi
+
+dnl ---------------------------------------------------------------------------
+dnl Samba4 modules
+dnl ---------------------------------------------------------------------------
+PKG_CHECK_MODULES(TALLOC, talloc)
+PKG_CHECK_MODULES(SAMBA, dcerpc ndr samba-hostconfig)
+PKG_CHECK_MODULES(LDB, ldb)
+
+dnl ---------------------------------------------------------------------------
+dnl Check a particular Samba4 git revision
+dnl ---------------------------------------------------------------------------
+
+oc_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags-only-I samba-hostconfig`"
+AC_CHECK_HEADER([samba/version.h],, AC_MSG_ERROR([Could not find Samba4 headers. Re-run ./configure with --with-samba=XXX where
+ XXX is the prefix that Samba4 was installed to.]))
+
+. `dirname $0`/script/samba4_ver.sh
+
+OC_CHECK_SAMBA_VERSION([$SAMBA4_RELEASE],[$SAMBA4_GIT_VER-GIT-$SAMBA4_GIT_REV])
+CPPFLAGS="$oc_save_CPPFLAGS"
+
+dnl ---------------------------------------------------------------------------
+dnl Finally add libmapi to the library list
+dnl ---------------------------------------------------------------------------
+OC_RULE_ADD(libmapi, LIBS)
+
+dnl nasty hack: only compile IDL if we have a library
+dnl libraries require libmapi and libmapi require IDL
+OC_IDL="idl"
+AC_SUBST(OC_IDL)
+
+dnl ###########################################################################
+dnl libmapi++ dependencies
+dnl ###########################################################################
+
+dnl ---------------------------------------------------------------------------
+dnl Check for g++
+dnl ---------------------------------------------------------------------------
+AC_CACHE_CHECK([C++ compiler availability], [ac_cv_libmapixx_gxx_works],
+	       [
+		AC_LANG_PUSH([C++])
+		AC_COMPILE_IFELSE([int main() { return 0; }], 
+				  [ac_cv_libmapixx_gxx_works=yes],
+				  [ac_cv_libmapixx_gxx_works=no])
+		AC_LANG_POP([C++])
+		])
+
+dnl ---------------------------------------------------------------------------
+dnl Check for boost-thread
+dnl ---------------------------------------------------------------------------
+
+AC_ARG_VAR([BOOST_LIB_SUFFIX], [Boost library name suffix])
+
+AC_CACHE_CHECK([for boost_thread$BOOST_LIB_SUFFIX library], [ov_cv_boost_thread],
+	       [
+	        ov_cv_boost_thread=no
+		ov_save_LIBS=$LIBS
+		LIBS="-lboost_thread$BOOST_LIB_SUFFIX $LIBS"
+		AC_LANG_PUSH([C++])
+		AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/thread.hpp>]],
+						[[boost::thread t]])],
+				[ov_cv_boost_thread=yes])
+		AC_LANG_POP([C++])
+		LIBS=$ov_save_LIBS
+	       ])
+
+
+if test x"$ac_cv_libmapixx_gxx_works" = "xyes"; then
+   if test x"$ov_cv_boost_thread" = "xyes"; then
+      AC_PROG_CXX 
+      OC_RULE_ADD(libmapixx, LIBS)
+   fi
+fi
+
+
+dnl ###########################################################################
+dnl libocpf dependencies
+dnl ###########################################################################
+
+dnl ---------------------------------------------------------------------------
+dnl Check for Bison
+dnl ---------------------------------------------------------------------------
+if test x"$OPENCHANGE_VERSION_IS_SVN_SNAPSHOT" = x"yes"; then
+   AC_ARG_VAR([BISON], [Location of the bison program.])
+   AC_PATH_PROG([BISON], [bison], [bison])
+
+   if test x"$BISON" != x""; then
+      OC_RULE_ADD(libocpf, LIBS)
+      AC_SUBST(BISON)
+   fi
+else
+   OC_RULE_ADD(libocpf, LIBS)
+fi
+
+
+
+dnl ###########################################################################
+dnl libmapiadmin dependencies
+dnl ###########################################################################
+PKG_CHECK_EXISTS([ dcerpc_samr ],
+		[
+			enable_libmapiadmin="yes"
+		], [
+			enable_libmapiadmin="no"
+		])
+
+if test x"$enable_libmapiadmin" = x"yes"; then
+   	PKG_CHECK_MODULES(SAMR, dcerpc_samr)
+	OC_RULE_ADD(libmapiadmin, LIBS)
+fi
+
+
+
+dnl ##########################################################################
+dnl tools dependencies
+dnl ##########################################################################
+
+dnl --------------------------------------------------------------------------
+dnl Check for libical                                                        
+dnl --------------------------------------------------------------------------
+PKG_CHECK_MODULES([ICAL], [libical], [have_libical="yes"], [have_libical="no"])
+AC_SUBST(ICAL_CFLAGS)
+AC_SUBST(ICAL_LIBS)
+
+dnl --------------------------------------------------------------------------
+dnl Check for popt
+dnl --------------------------------------------------------------------------
+
+AC_CHECK_LIB([popt], [poptFreeContext], 
+             [
+	       AC_DEFINE(HAVE_LIBPOPT, 1, [Define if you want to use libpopt])
+	       enable_libpopt="yes"
+             ], 
+             [ 
+               AC_MSG_WARN([libpopt is missing - can't build openchange tools]) 
+	       enable_libpopt="no"
+             ])
+
+if test x"$enable_libpopt" = x"yes"; then
+   	if test x"$enable_libmapiadmin" = x"yes"; then
+	   OC_RULE_ADD(openchangepfadmin, TOOLS)
+	   OC_RULE_ADD(mapitest, TOOLS)
+	fi
+
+	if test x"$enable_libocpf" = x"yes"; then
+	   OC_RULE_ADD(openchangeclient, TOOLS)
+	fi
+
+	if test x"$have_libical" = x"yes"; then
+	    OC_RULE_ADD(exchange2ical, TOOLS)
+	fi
+
+	OC_RULE_ADD(mapiprofile, TOOLS)
+	OC_RULE_ADD(openchangemapidump, TOOLS)
+	OC_RULE_ADD(schemaIDGUID, TOOLS)
+	OC_RULE_ADD(locale_codepage, TOOLS)
+fi
+
+dnl --------------------------------------------------------------------------
+dnl Check for libmagic
+dnl --------------------------------------------------------------------------
+AC_CHECK_LIB([magic], [magic_open],
+	     [
+               AC_DEFINE(HAVE_LIBMAGIC, 1, [Define if you want to use libmagic])
+ 	       MAGIC_LIBS="-lmagic -lz"
+	       enable_libmagic="yes"
+             ],
+	       AC_SUBST(MAGIC_LIBS)
+ 	     [
+               AC_MSG_WARN([libmagic is missing - can't build exchange2mbox])
+	       enable_libmagic="no"
+ 	     ])
+
+if test x"$enable_libmagic" = x"yes"; then
+   	AC_CHECK_LIB([z], [gzopen], [], 
+		     [
+		       AC_MSG_ERROR([Z library not found, please install zlib-devel.], [1])
+		     ])
+   	if test x"$enable_libpopt" = x"yes"; then
+		OC_RULE_ADD(exchange2mbox, TOOLS)
+	fi
+fi
+
+
+dnl ##########################################################################
+dnl libmapistore backends dependencies
+dnl ##########################################################################
+
+dnl --------------------------------------------------------------------------
+dnl Check for sqlite3
+dnl --------------------------------------------------------------------------
+PKG_CHECK_MODULES(SQLITE, sqlite3, SQLITEFOUND=yes, [SQLITEFOUND=no])
+AC_SUBST(SQLITE_CFLAGS)
+AC_SUBST(SQLITE_LIBS)
+
+if test x"$SQLITEFOUND" = x"yes"; then
+   OC_RULE_ADD(mapistore_sqlite3, MAPISTORE)
+fi
+
+
+dnl ##########################################################################
+dnl torture dependencies
+dnl ##########################################################################
+AC_PATH_PROG([SMBTORTURE], [smbtorture], no)
+
+if test x"$SMBTORTURE" != x""; then
+   	TORTURE_MODULESDIR=`$PKG_CONFIG --variable=modulesdir torture`
+   	AC_SUBST(TORTURE_MODULESDIR)
+   	OC_RULE_ADD(torture, TORTURE)
+fi
+
+
+dnl ##########################################################################
+dnl mapiproxy server
+dnl ##########################################################################
+if test x$PYTHON != x; then
+	OC_RULE_ADD(mapiproxy, SERVER)
+fi
+
+AC_ARG_WITH(modulesdir, 
+[AS_HELP_STRING([--with-modulesdir], [Modules path to use])],
+[modulesdir="$withval"; ],
+[modulesdir="\${prefix}/modules"; ])
+
+AC_SUBST(modulesdir)
+
+dnl ##########################################################################
+dnl Swig bindings dependencies
+dnl ##########################################################################
+AC_ARG_ENABLE(swig-perl, AC_HELP_STRING([--enable-swig-perl],
+			   [build SWIG interfaces for Perl]),
+			   enable_perlswig="$enableval")
+if test "x${enable_perlswig}" = xyes; then
+   AC_PATH_PROG(SWIG, swig)
+
+   if test -z "$SWIG"
+      then
+	AC_MSG_ERROR(Please install swig)
+   fi
+
+   SWIGDIRSALL+="swigperl-all"
+   SWIGDIRSINSTALL+="swigperl-install"
+   SWIGDIRSUNINSTALL+="swigperl-uninstall"
+fi
+
+PERL5DIR=`$PERL -e 'use Config; my $dir = $Config{sitelib}; print $dir'`
+AC_SUBST(PERL5DIR)
+
+AC_SUBST(SWIGDIRSALL)
+AC_SUBST(SWIGDIRSINSTALL)
+AC_SUBST(SWIGDIRSUNINSTALL)
+
+dnl ##########################################################################
+dnl Python bindings dependencies
+dnl ##########################################################################
+AC_ARG_ENABLE(pymapi, AC_HELP_STRING([--enable-pymapi],
+			   [build Python bindings for libmapi]),
+			   enable_pymapi="$enableval",
+			   enable_pymapi=no)
+if test "x${enable_pymapi}" = xyes; then
+   PYMAPIALL+="pymapi"
+   PYMAPIINSTALL+="pymapi-install"
+   PYMAPIUNINSTALL+="pymapi-uninstall"
+fi
+
+PYCDIR=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1, prefix='\\$(prefix)')"`
+AC_SUBST(PYCDIR)
+
+AC_SUBST(PYMAPIALL)
+AC_SUBST(PYMAPIINSTALL)
+AC_SUBST(PYMAPIUNINSTALL)
+
+dnl ##########################################################################
+dnl Documentation dependencies
+dnl ##########################################################################
+AC_PATH_PROG(DOXYGEN, doxygen)
+if test x"$DOXYGEN" = x""; then
+	AC_MSG_WARN(doxygen)
+	enable_doxygen="no"
+else
+	enable_doxygen="yes"
+	AC_SUBST(DOXYGEN)
+fi
+
+
+
+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])
+AC_OUTPUT
+
+
+dnl ##########################################################################
+dnl Print configuration info
+dnl ##########################################################################
+
+OC_SETVAL(libmapi)
+OC_SETVAL(libmapiadmin)
+OC_SETVAL(libocpf)
+OC_SETVAL(libmapixx)
+
+OC_SETVAL(openchangeclient)
+OC_SETVAL(mapiprofile)
+OC_SETVAL(openchangepfadmin)
+OC_SETVAL(exchange2mbox)
+OC_SETVAL(exchange2ical)
+OC_SETVAL(mapitest)
+OC_SETVAL(openchangemapidump)
+OC_SETVAL(schemaIDGUID)
+OC_SETVAL(locale_codepage)
+OC_SETVAL(mapiproxy)
+
+OC_SETVAL(torture)
+OC_SETVAL(doxygen)
+OC_SETVAL(perlswig)
+
+AC_MSG_RESULT([
+
+===============================================================
+OpenChange Configuration (Please review)
+
+	   * Install:
+	     - prefix:			$prefix
+
+	   * OpenChange MAPI library:	$enable_libmapi
+
+	   * OpenChange Libraries:
+	     - libmapi++:		$enable_libmapixx
+	     - libmapiadmin:		$enable_libmapiadmin
+	     - libocpf:			$enable_libocpf
+
+	   * OpenChange Server:
+	     - mapiproxy:		$enable_mapiproxy
+
+	   * OpenChange mapistore backends:
+	     - sqlite3:			$enable_mapistore_sqlite3
+
+	   * OpenChange Tools:
+	     - openchangeclient:	$enable_openchangeclient
+	     - mapiprofile:		$enable_mapiprofile
+	     - openchangepfadmin:	$enable_openchangepfadmin
+	     - exchange2mbox:		$enable_exchange2mbox
+	     - exchange2ical:		$enable_exchange2ical
+	     - mapitest:		$enable_mapitest
+	     - openchangemapidump:	$enable_openchangemapidump
+	     - schemaIDGUID:		$enable_schemaIDGUID
+	     - locale_codepage:		$enable_locale_codepage
+
+	   * OpenChange Torture Suite:	$enable_torture
+
+	   * OpenChange Documentation:	$enable_doxygen
+
+	   * OpenChange Bindings:
+	     - Perl:			$enable_perlswig
+	     - Python:			$enable_pymapi
+
+===============================================================
+
+])
+

Added: trunk/openchange/doc/doxygen/apidocs.css
===================================================================
--- trunk/openchange/doc/doxygen/apidocs.css	                        (rev 0)
+++ trunk/openchange/doc/doxygen/apidocs.css	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,758 @@
+/*
+** WEBSITE
+**
+*/
+
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+       font-size: 90%;
+}
+H1 {
+	text-align: center;
+       font-size: 160%;
+}
+H2 {
+	font-size: 19px;
+	font-weight: bold;
+	color: #3E93D5;
+}
+H3 {
+       font-size: 100%;
+}
+
+P {
+      text-align: justify;
+}
+
+LI {
+      li-style-type: square;
+      li-style-position: outside;
+      display: list-item;
+}
+
+CAPTION { font-weight: bold }
+DIV.qindex {
+	width: 100%;
+	background-color: #e8eef2;
+	border: 1px solid #84b0c7;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+DIV.nav {
+	width: 100%;
+	background-color: #e8eef2;
+	border: 1px solid #84b0c7;
+	text-align: center;
+	margin: 2px;
+	padding: 2px;
+	line-height: 140%;
+}
+DIV.navtab {
+       background-color: #e8eef2;
+       border: 1px solid #84b0c7;
+       text-align: center;
+       margin: 2px;
+       margin-right: 15px;
+       padding: 2px;
+}
+TD.navtab {
+       font-size: 70%;
+}
+A.qindex {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D;
+}
+A.qindex:visited {
+       text-decoration: none;
+       font-weight: bold;
+       color: #1A419D
+}
+A.qindex:hover {
+	text-decoration: none;
+	background-color: #ddddff;
+}
+A.qindexHL {
+	text-decoration: none;
+	font-weight: bold;
+	background-color: #6666cc;
+	color: #ffffff;
+	border: 1px double #9295C2;
+}
+A.qindexHL:hover {
+	text-decoration: none;
+	background-color: #6666cc;
+	color: #ffffff;
+}
+A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
+A.el { text-decoration: none; font-weight: bold }
+A.elRef { font-weight: bold }
+A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
+A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
+A.codeRef:link { font-weight: normal; color: #0000FF}
+A.codeRef:visited { font-weight: normal; color: #0000FF}
+A:hover { text-decoration: none; background-color: #f2f2ff }
+DL.el { margin-left: -1cm }
+.fragment {
+       font-family: monospace, fixed;
+       font-size: 95%;
+}
+PRE.fragment {
+	border: 1px solid #CCCCCC;
+	background-color: #f5f5f5;
+	font-size: 11px;
+	margin-top: 4px;
+	margin-bottom: 4px;
+	margin-left: 2px;
+	margin-right: 8px;
+	padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 4px;
+	padding-bottom: 4px;
+}
+DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
+
+DIV.groupHeader {
+       margin-left: 16px;
+       margin-top: 12px;
+       margin-bottom: 6px;
+       font-weight: bold;
+}
+DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
+BODY {
+	background: white;
+	color: black;
+	margin-right: 20px;
+	margin-left: 20px;
+}
+TD.indexkey {
+	background-color: #e8eef2;
+	font-weight: bold;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+	background-color: #e8eef2;
+	font-style: italic;
+	padding-right  : 10px;
+	padding-top    : 2px;
+	padding-left   : 10px;
+	padding-bottom : 2px;
+	margin-left    : 0px;
+	margin-right   : 0px;
+	margin-top     : 2px;
+	margin-bottom  : 2px;
+	border: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0; 
+}
+P.formulaDsp { text-align: center; }
+IMG.formulaDsp { }
+IMG.formulaInl { vertical-align: middle; }
+SPAN.keyword       { color: #008000 }
+SPAN.keywordtype   { color: #604020 }
+SPAN.keywordflow   { color: #e08000 }
+SPAN.comment       { color: #800000 }
+SPAN.preprocessor  { color: #806020 }
+SPAN.stringliteral { color: #002080 }
+SPAN.charliteral   { color: #008080 }
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.memItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplParams {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+       color: #606060;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.search     { color: #003399;
+              font-weight: bold;
+}
+FORM.search {
+              margin-bottom: 0px;
+              margin-top: 0px;
+}
+INPUT.search { font-size: 75%;
+               color: #000080;
+               font-weight: normal;
+               background-color: #e8eef2;
+}
+TD.tiny      { font-size: 75%;
+}
+a {
+	color: #1A41A8;
+}
+a:visited {
+	color: #2A3798;
+}
+.dirtab { padding: 4px;
+          border-collapse: collapse;
+          border: 1px solid #84b0c7;
+}
+TH.dirtab { background: #e8eef2;
+            font-weight: bold;
+}
+HR { height: 1px;
+     border: none;
+     border-top: 1px solid black;
+     margin-bottom: 50px;
+}
+
+/* Style for detailed member documentation */
+.memtemplate {
+  font-size: 80%;
+  color: #606060;
+  font-weight: normal;
+} 
+.memnav { 
+  background-color: #e8eef2;
+  border: 1px solid #84b0c7;
+  text-align: center;
+  margin: 2px;
+  margin-right: 15px;
+  padding: 2px;
+}
+.memitem {
+  padding: 4px;
+  background-color: white;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #ccc;
+  -moz-border-radius: 8px 8px 8px 8px;
+  margin-bottom: 30px;
+}
+.memname {
+  white-space: nowrap;
+  font-weight: bold;
+  font-size: 12px;
+  margin: 10px 10px 10px 10px;
+}
+
+.memname EM {
+	 color: #45417e;
+}
+
+.memdoc{
+  padding-left: 10px;
+  padding-right: 10px;
+}
+
+.memdoc EM, TD {
+	font-size: 12px;
+}
+
+.memproto {
+  background-color: #e9e9f4;
+  width: 100%;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #ccc;
+  font-weight: bold;
+  -moz-border-radius: 8px 8px 8px 8px;
+}
+.paramkey {
+  text-align: right;
+}
+.paramtype {
+  white-space: nowrap;
+}
+.paramname {
+  color: #602020;
+  font-style: italic;
+  white-space: nowrap;
+}
+/* End Styling for detailed member documentation */
+
+/* for the tree view */
+.ftvtree {
+	font-family: sans-serif;
+	margin:0.5em;
+}
+.directory { font-size: 9pt; font-weight: bold; }
+.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; }
+.directory > h3 { margin-top: 0; }
+.directory p { margin: 0px; white-space: nowrap; }
+.directory div { display: none; margin: 0px; }
+.directory img { vertical-align: -30%; }
+
+
+#website {
+	width: 820px;
+	height: 100%;
+	margin-left: auto;
+	margin-right: auto;
+	text-align: left;
+
+
+	/* IE hack */
+	* position: absolute;
+	* left: 50%;
+	* margin-left: -410px;
+}
+
+/*
+** HEADER
+**
+*/
+
+.header {
+	height: 200px;
+	background: url(header.jpg) no-repeat top center;
+}
+
+body {
+	background: #fff url(body_top_bg2.jpg) top left repeat-x;
+	font-family: Arial, Trebuchet MS, Tahoma, Verdana, Helvetica, sans-serif;
+	font-size: 11px;
+	line-height: 17px;
+	color: #444;
+	color: #3a3a3a;
+	fdpadding-top: 15px;
+	text-align: center;
+	background-color: #fbfbfb;
+}
+
+h1 {
+	font: 24px bold Trebuchet MS, Arial;
+	color: #FFF;
+	padding: 0;
+	margin: 0;
+}
+
+/*
+** MIDDLE SIDE
+**
+*/
+
+#middle_side {
+	display: block;
+	height: 100%;
+	width: 800px;
+	margin-top: 7px;
+	backsground: url(middle_bg.jpg) top left repeat-x;
+	background-color: #fbfbfb;
+}
+
+/* left and right side */
+
+#left_side {
+	background-color: #fff;
+	clear: both;
+	margin-bottom: 10px;
+	border-bottom: 1px solid #eee;
+	border-left: 1px solid #eee;
+	border-right: 1px solid #eee;
+	-moz-border-radius: 0 0 8px 8px;
+	height: 29px;
+}
+
+
+/*
+** MENU HORIZONTAL
+**
+*/
+
+/************ Global Navigation *************/
+
+DIV.tabs {
+   float            : left;
+   width            : 100%;
+   background       : url("tab_b.gif") repeat-x bottom;
+   margin-top	    : 10px;
+   margin-bottom    : 4px;
+}
+
+DIV.tabs  ul {
+   margin           : 0px;
+   padding-left     : 10px;
+   list-style       : none;
+}
+
+DIV.tabs  li {
+   display          : inline;
+   margin           : 0px;
+   padding          : 0px;
+}
+
+DIV.tabs A {
+   float            : left;
+   background       : url("tab_r.gif") no-repeat right top;
+   border-bottom    : 1px solid #84B0C7;
+   font-size        : x-small;
+   font-weight      : bold;
+   text-decoration  : none;
+}
+
+DIV.tabs A:link, .tabs A:visited,
+DIV.tabs A:active, .tabs A:hover
+{
+       color: #1A419D;
+}
+
+
+DIV.tabs SPAN
+{
+   float            : left;
+   display          : block;
+   background       : url("tab_l.gif") no-repeat left top;
+   padding          : 5px 10px;
+   white-space      : nowrap;
+}
+
+DIV.tabs TD
+{
+   font-size        : x-small;
+   font-weight      : bold;
+   text-decoration  : none;
+}
+
+
+
+/* Commented Backslash Hack hides rule from IE5-Mac \*/
+DIV.tabs SPAN {float : none;}
+/* End IE5-Mac hack */
+
+DIV.tabs A:hover SPAN
+{
+   background-position: 0% -150px;
+}
+
+DIV.tabs LI.current A
+{
+   background-position: 100% -150px;
+   border-width     : 0px;
+}
+
+DIV.tabs LI.current SPAN
+{
+   background-position: 0% -150px;
+   padding-bottom   : 6px;
+}
+
+
+DIV.nav
+{
+   background       : none;
+   border           : none;
+   border-bottom    : 1px solid #84B0C7;
+}
+
+
+#right_side_home {
+	font-family: "Lucida Grande", Arial, Verdana, sans-serif;
+	background-color: white;
+	padding: 0px 20px;
+	border: 1px solid #ebebeb;
+	border: 1px solid #ddd;
+	-moz-border-radius: 10px 10px;
+
+	width: 750px;
+
+
+	* width: 800px;
+	* margin-left: 0px;
+	padding-bottom: 10px;
+}
+
+#right_side_home td {
+		 line-height: 17px;
+		 margin: 0 0 5px 0;
+		 padding: 10px 0 15px 7px
+		 display: table-cell;
+		 border-spacing: 2px 2px;
+		 vertical-align: middle;
+		 text-align: left;
+		 border-bottom: 1px solid #EEEEEE;
+}
+
+#right_side_home td h2, a.anchor {
+		 font-size: 19px;
+		 font-weight: bold;
+		 color: #3E93D5;
+}
+
+#right_side_home td.indexkey {
+		 border-bottom: none;
+}
+
+#right_side_home li {
+		 list-style-position: inside;
+		 valign: middle;
+}
+
+
+TD.indexkey {
+	background-color: #e8eef2;
+	font-size	: 12px;
+	font-weight	: bold;
+	padding-right   : 10px;
+	padding-top     : 2px;
+	padding-left   	: 10px;
+	padding-bottom 	: 2px;
+	margin-left    	: 0px;
+	margin-right   	: 0px;
+	margin-top     	: 2px;
+	margin-bottom  	: 2px;
+	border		: 1px solid #CCCCCC;
+}
+TD.indexvalue {
+	background-color: #e8eef2;
+	font-style	: italic;
+	font-size	: 12px;
+	padding-right  	: 10px;
+	padding-top    	: 2px;
+	padding-left   	: 10px;
+	padding-bottom 	: 2px;
+	margin-left    	: 0px;
+	margin-right   	: 0px;
+	margin-top     	: 2px;
+	margin-bottom  	: 2px;
+	border		: 1px solid #CCCCCC;
+}
+TR.memlist {
+   background-color: #f0f0f0; 
+}
+
+.mdescLeft {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.mdescRight {
+       padding: 0px 8px 4px 8px;
+	font-size: 80%;
+	font-style: italic;
+	background-color: #FAFAFA;
+	border-top: 1px none #E0E0E0;
+	border-right: 1px none #E0E0E0;
+	border-bottom: 1px none #E0E0E0;
+	border-left: 1px none #E0E0E0;
+	margin: 0px;
+}
+.memItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemLeft {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplItemRight {
+	padding: 1px 8px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: none;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+.memTemplParams {
+	padding: 1px 0px 0px 8px;
+	margin: 4px;
+	border-top-width: 1px;
+	border-right-width: 1px;
+	border-bottom-width: 1px;
+	border-left-width: 1px;
+	border-top-color: #E0E0E0;
+	border-right-color: #E0E0E0;
+	border-bottom-color: #E0E0E0;
+	border-left-color: #E0E0E0;
+	border-top-style: solid;
+	border-right-style: none;
+	border-bottom-style: none;
+	border-left-style: none;
+       color: #606060;
+	background-color: #FAFAFA;
+	font-size: 80%;
+}
+
+code {
+     display: block;
+     width: 100%;
+     border: 1px solid #ccc;
+     background-color: #e8edf3;
+     padding-top: 10px;
+     padding-bottom: 10px;
+     padding-left: 5px;
+     padding-right: 5px;
+     margin-bottom: 10px;
+     margin-top: 10px;
+}
+

Added: trunk/openchange/doc/doxygen/footer.html
===================================================================
--- trunk/openchange/doc/doxygen/footer.html	                        (rev 0)
+++ trunk/openchange/doc/doxygen/footer.html	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,18 @@
+</div>
+<br/>
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#f8f8f8; border:2px solid #e0e0e0; padding:5px;">
+<tr>
+<td> 
+  <img alt="Creative Commons License" src="CC_SomeRightsReserved.png" width="90" height="30" border="0" /><br />
+  <img alt="Creative Commons Attribution icon" src="24px-Cc-by_white.svg.png" width="24" height="24" border="0" />
+  <img alt="Creative Commons Share Alike icon" src="24px-Cc-sa_white.svg.png" width="24" height="24" border="0" />
+</td>
+<td> <i><strong class="selflink">This content</strong> is licensed under the Creative Commons<br />
+Attribution ShareAlike License v. 3.0:<br />
+<a href="http://creativecommons.org/licenses/by-sa/3.0/" class="external free" title="http://creativecommons.org/licenses/by-sa/3.0/" rel="nofollow">http://creativecommons.org/licenses/by-sa/3.0/</a></i>
+</td></tr></table>
+<br/>
+</div>
+</div>
+</body>
+</html>

Added: trunk/openchange/doc/doxygen/header.html
===================================================================
--- trunk/openchange/doc/doxygen/header.html	                        (rev 0)
+++ trunk/openchange/doc/doxygen/header.html	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,11 @@
+<html>
+  <head>
+    <title>$projectname $projectnumber API Documentation</title>
+    <link href="doxygen.css" rel="stylesheet" type="text/css"/>
+    <link href="apidocs.css" rel="stylesheet" type="text/css"/>
+  </head>
+  <body>
+    <div id="website">
+    <div class="header"></div>
+      <div id="middle_side">
+	<div id="right_side_home">

Added: trunk/openchange/doc/doxygen/index.html
===================================================================
--- trunk/openchange/doc/doxygen/index.html	                        (rev 0)
+++ trunk/openchange/doc/doxygen/index.html	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,10 @@
+<html xmlns="http://www.w3.org/1999/xhtml">    
+  <head>      
+    <title>OpenChange API Documentation</title>      
+    <meta http-equiv="refresh" content="0;URL='overview/index.html'" />    
+  </head>    
+  <body> 
+    <p>Redirecting you to the OpenChange <a href="overview/index.html">API documentation 
+      overview</a>.</p> 
+  </body>  
+</html> 

Added: trunk/openchange/doc/doxygen/libmapi-concepts.doxy
===================================================================
--- trunk/openchange/doc/doxygen/libmapi-concepts.doxy	                        (rev 0)
+++ trunk/openchange/doc/doxygen/libmapi-concepts.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,55 @@
+/**
+\page mapiconcepts MAPI Concepts
+
+<h2>MAPI objects</h2>
+
+Almost any MAPI data you access, read or edit is associated with an
+object. No matter whether you intend to browse mailbox hierarchy, open
+folders, create tables or access items (messages, appointments,
+contacts, tasks, notes), you will have to initialize and use MAPI
+objects: <em>object understanding and manipulation is
+fundamental</em>.
+
+- When developing MAPI clients with Microsoft framework, instantiated
+objects inherit from parent classes. As a matter of fact, developers
+know which methods they can apply to objects and we  suppose it makes
+their life easier.
+- In OpenChange, objects are opaque. They are generic data structures
+which content is set and accessed through MAPI public
+functions. Therefore, Linux MAPI developers must know what they are
+doing. 
+
+An example of MAPI object manipulation is shown below:
+\code
+        mapi_object     obj_store;
+
+        [...]
+
+        mapi_object_init(&obj_store);
+        retval = OpenMsgStore(&obj_store);
+        if (retval != MAPI_E_SUCCESS) {
+                mapi_errstr("OpenMsgStore", GetLastError());
+                exit (1);
+        }
+        mapi_object_release(&obj_store);
+\endcode
+
+<h3>MAPI Handles</h3>
+
+Beyond memory management considerations, understanding MAPI handles
+role in object manipulation provides a better understanding why
+mapi_object_release() matters.
+
+Handles are temporary identifiers returned by Exchange when you access
+or create objects on the server. They are used to make reference to a
+particular object all along its session lifetime. They are stored in
+unsigned integers, are unique for each object but temporary along MAPI
+session. Handles are the only links between objects accessed on the
+client side and efficiently stored on the server side.
+
+Although OpenChange MAPI makes handles manipulation transparent for
+developers, mapi_object_release() frees both the allocated memory
+for the object on client side, but also releases the object on the
+server.
+
+*/

Added: trunk/openchange/doc/doxygen/libmapi-examples.doxy
===================================================================
--- trunk/openchange/doc/doxygen/libmapi-examples.doxy	                        (rev 0)
+++ trunk/openchange/doc/doxygen/libmapi-examples.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,110 @@
+/** \example mapi_sample1.c
+
+This example shows a very basic MAPI program, including setup, login,
+and teardown.
+
+The first MAPI library function called is MAPIInitialize(). As its
+name suggests, this function initializes MAPI library: It creates the
+MAPI global context, opens the profile database store (database path
+passed as function parameter) and initialize Samba4 transport
+layer. This function must be called prior any other MAPI
+library operations.
+
+Once MAPI is initialized, we need to create a connection to Exchange and
+open MAPI sessions with the user credentials. This is the purpose of
+MapiLogonEx() which needs to be executed prior doing any effective
+code. This function takes a pointer on a mapi_session structure,
+the profile username and an optional password in case you decided to
+store it outside the profile. In the example above, we retrieve the
+default profile name from the database using GetDefaultProfile()
+Note that MapiLogonEx() opens connections to both the EMSMDB and
+EMSABP store providers. If you intend to interact with a single
+provider, use MapiLogonProvider() instead.
+
+Finally we call MAPIUninitialize() prior to leaving the
+function. This opaque function will clean up the memory allocated
+during the session and stored within the global MAPI context.
+
+*/
+
+/** \example fetchmail.c
+
+This example shows how to fetch mail from the server.
+
+We initialize MAPI library with the profiles database path, retrieve
+the default profile name and open connections to both the Exchange
+message store provider (EMSMDB) and Exchange Address Book provider
+(EMSABP).
+
+\section ex-fetchmail-openstore Open the message store
+
+Now we have
+opened a connection to the Exchange message store provider, we can
+open the user mailbox store with OpenMsgStore() This function
+will return a set of pre-defined folder unique IDs (stored on double
+values) and a \em pointer to the upper object we can access in MAPI
+hierarchy.
+
+\section ex-fetchmail-openinbox Opening the Inbox folder
+
+We now open the Inbox folder. Since OpenMsgStore() returns a set
+of \em common folders identifiers we store in the message store
+object (obj_store), we can retrieve them using the convenient
+GetDefaultFolder() function. This function doesn't generate any
+network traffic, but returns the folder identifier associated with the
+constant passed as argument (here olFolderInbox).
+
+We could have used MAPI tables and GetHierarchyTable() function to
+find Inbox folder identifier. We would have had to retrieve the
+Top Information Store hierarchy table, customize the view with 
+PR_FID (Folder ID MAPI property) and PR_DISPLAY_NAME, find the 
+IPM_SUBTREE folder identifier, open it, retrieve the Hierarchy Table,
+call SetColumns() with PR_FID and finally browse table rows until
+we found the Inbox folder.folders to store emails within 
+IPM_SUBTREE folder hierarchy.
+
+\section ex-fetchmail-retrievecontentstable Retrieve contents table
+
+Once the Inbox folder is opened, we can call GetContentsTable() to
+create the view needed to list all the children objects. In the
+current example we suppose we will only retrieve IPM.Post objects
+(emails).
+
+\section ex-fetchmail-customview Customizing the MAPI view
+
+We now customize the MAPI view and set the columns with the property
+tags we want to access: PR_FID (Folder Identifier) and
+PR_MID (Message identifier). MAPI uses unique and permanent
+identifiers to classify objects. These identifiers are double values
+(8 bytes) and never change until you move the object to another
+location.
+
+We now enter the last step of the fetching process:
+
+- Call QueryPosition() to retrieve the current cursor position in the
+  contents table. The function returns the approximate fractional
+  position with a Numerator and Denominator. Denominator is the total
+  number of rows in the table.
+- Recursively call QueryRows() with the TBL_ADVANCE flag to fetch table rows.
+- Iterate through QueryRows results
+- Retrieve columns values for each row with the convenient find_SPropValue_data()
+- Open the message given its folder and message ids.
+- Call GetPropsAll() rather than GetProps() to retrieve all properties associated with a given object
+- Call one of OpenChange mapidump API function to display nice messages dump on standard output.
+
+We finally release mapi objects and clean up the MAPI library before returning
+*/
+
+/** \example fetchappointment.c
+
+This example shows how to fetch an appointment from the server.
+
+This is very similar to the fetchmail.c example, except two minor changes:
+- We change the default folder constant from olFolderInbox to
+olFolderContact so any further operations are performed on a child of
+the calendar folder.
+- We use mapidump_appointment() rather than mapidump_message() to dump
+appointments on standard output. 
+
+*/
+

Added: trunk/openchange/doc/doxygen/libmapi-mainpage.doxy
===================================================================
--- trunk/openchange/doc/doxygen/libmapi-mainpage.doxy	                        (rev 0)
+++ trunk/openchange/doc/doxygen/libmapi-mainpage.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,79 @@
+/**
+\mainpage Opening Exchange to a wider world
+
+<h2>OpenChange Project Goals</h2>
+
+The OpenChange Project aims to provide a portable Open Source
+implementation of Microsoft Exchange Server and Exchange
+protocols. Exchange is a groupware server designed to work with
+Microsoft Outlook, and providing features such as a messaging server,
+shared calendars, contact databases, public folders, notes and tasks.
+
+The OpenChange project has three goals:
+
+- To provide a library for interoperability with Exchange
+protocols, and to assist implementors to use this to create
+groupware that interoperates with both Exchange and other
+OpenChange-based software.
+
+- To provide an alternative to Microsoft Exchange Server which uses
+native Exchange protocols and provides exactly equivalent
+functionality when viewed from Microsoft Outlook clients.
+
+- To develop a body of knowledge about the most popular groupware
+protocols in use commercially today in order to promote  development
+of a documented and unencumbered standard, with all the  benefits that
+standards bring.
+
+<h2>MAPI Overview</h2>
+
+MAPI is the glue between Exchange and Outlook, but a common
+misconception is to consider it as a network protocol. MAPI, an
+acronym for Messaging Application Programming Interface, refers to a
+proprietary set of function call interfaces developed by Microsoft
+before Microsoft Exchange existed. By purchasing licenses to
+Microsoft's proprietary and Windows-only MAPI libraries, anyone can
+create message services that communicate using these functions. A mail
+server implemented in this way is what Microsoft calls a MAPI Service
+Provider. Any protocol could be used as a transport for these MAPI
+communications. 
+
+When Microsoft Exchange 5.5 was developed in 1997, the decision was
+taken to create a proprietary transport protocol for MAPI which
+closely matches the MAPI calling interface. This protocol is called
+ExchangeRPC and used in Outlook-Exchange communications. ExchangeRPC
+is the only transport OpenChange supports, and in practice is the only
+transport of interest today. Most of the world is being forced to use
+Microsoft Exchange servers, so that defines the transport that
+matters.
+
+When OpenChange team members first looked at the network network
+traffic these generated by calling MAPI functions on Windows operating
+systems, we noticed blobs of data first either compressed or
+obfuscated, then encapsulated by an RPC transport protocol function
+(EMSMDB) and finally pushed on the wire. Transporting
+memory-image blobs on the wire is not good protocol design, however
+for a number of reasons the result now works quite reliably.
+
+<h2>Looking at a MAPI Conversation</h2>
+
+A high-level view of a MAPI conversation follows. We also introduce
+important terminology:
+- MAPI applications call MAPI providers, using the API to pass data
+(eg a mail message body) or MAPI conversation requests and responses
+(eg 'search for this address').
+- MAPI providers pack the client or server MAPI information in a
+blob. There are only two really important providers, one for data
+destined for what is somewhat strangely termed the Message Store
+(although it handles more than just messages), and the other for data
+to be sent to the Address Book.  These are called the EMSMDB and
+EMSABP providers, respectively.
+- ExchangeRPC protocol is used to transport the MAPI information over
+the wire, encapsulating inside it one of two MAPI-specific protocols:
+the EMSMDB Message Store Protocol, or the NSPI Addressbook Protocol.
+- The store provider on the server side associated with the protocol
+used (either EMSMDB or EMSABP) extracts the MAPI blob from RPC
+protocol functions, analyzes its content and performs operations
+embedded within it.
+
+*/

Added: trunk/openchange/doc/doxygen/pictures/24px-Cc-by_white.svg.png
===================================================================
--- trunk/openchange/doc/doxygen/pictures/24px-Cc-by_white.svg.png	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/24px-Cc-by_white.svg.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,30 @@
+‰PNG
+
+   
+IHDR         °çá»   bKGDÿÿÿÿÿÿ	X÷Ü   	pHYs   H   H FÉk>  
+ IDATXýXmP”U¾vˆeY	pW$gQH–%ãËc*$åÃIkFmiØ‘ttrê‡C	öa3	Œc†D$ e¬±X,«@³ Â.Èîõþy›uÓ÷·÷úóÌœçÜϹîëºçÜç<þxHØNÛNÛN½+zWô® .–_,¿X|»æÛ5ß®Q†(C`4F#p×ý®û]w at qRqRqðÿÎÿ;ÿcaÇÂŽIÅIÅIÅ@˜$L&Ämâ6qÛòÀ‡Ä-í-í--ùVë[­oµ’<. …
+¡B¨øS RT(*’’IŽ$‡”æHs¤9¤S’S’S‰ð>°Ï÷ˆôˆôˆ$Óôiú4=Ù2Ú2Ú2JZ•V¥Uù`^‚û9À3<Ã3À7ýßôÓl?Ø~°¸ªºªºªœ‡œ‡œ‡€
+6Øp x&õ™ÔgR0—0—0ÀMá¦pS B©P*”–õ–õ–õ@²GÙ£šª›ª›ª¦mMÛš¶#êõˆðj÷j÷jöeïËÞ—
+äÎäÎäÎ Ò^i¯´÷að£ýȳégÓϦ“K{–ö,í±+¦êRu©ºÈŠÎŠÎŠNòöÔí©ÛSë£sñsñsñd{^{^{™u%ëJÖÒÅÛÅÛÅ›IER‘”ÔìÕìÕì%ÇSÇSÇS~gAuuu¤|µ|µ|5)øJð•à+rGËŽ–-äÀ±cÇþs‚å)ËS–§ÈÒ-¥[J·ž»=w{î&µ‚ZA-™÷BÞy/³£³£³£‹$psäæÈÍR•¨JT%ÚßñýŽïw|OšÌ&³Éü¿'þWX­ÖFòÔ“§ž<õ$é6â6â6Bºæ»æ»æ“ÕÕÕ÷&°Ÿû¹Ÿ<”p(áP‚xxQxQxyëÀ­·üóÄÿŠùçœÿ‘Ô®Ô®Ô®´óŠx.⹈çÈÁÎÁÎÁN7ŽÜ8rã¹æÙ5Ï®y–tŠwŠwŠ'+++ÿÿÄÿŠã€qÀH¿üzðë¤(H$
+"‹4Eš"
+)
+ø0àÀ:³ñÌÆ3··7à é é 	pNwNwN¦º¦º¦º€ZS­©Ö\K¹–r-èÎíÎíΆg†g†g OgOgOgÀ˜bL1¦ õâzq½XÒ·¤oI SÊ”2%033TÿQýGõ€h§h§h'àëëkßdÜÜÝÜÝ܁‰sç&Î
+õ
+õ
+õÀ¸iÜ4n°uÕÖU[WÙ-*4š©õ^^^r¹Ãr‡å¤S•S•SéêêJºMºMºM’»rwåîÊ%ûûûIE¤"RIîÙ¼góžÍäÜƹsÉý'öŸØ‚”'Êå‰dÛ–¶-m[îï„N£Óè4¤ÇÛo{¼MŠä"¹HN
+{]z]z] Ñ:Ñ:Ñ:@¥T)UÊE¶Û!q¸k¾k¾k2e™²LÐÛÛ¤½Ÿö~ÚûÀ¥ÉK“—&ÿVÿVÿV c.c.c¨­­Ê®•]+»œK>—|.ˆÔDj"5@[t[t[4 _ª_ª_ºpýÕ۝W;>Y>Y>Y€õwëïÖ߈§ÄSâ)R'‰“Ä‘Í7›o6ß\¨€Ál0̤¼SÞ)ï$ƒR‚R‚RÈ—3_Î|9“ô³øYü,dҍ¤I7H‹ŸÅÏâGöÕôÕôՐAùAùAù¤Ä 1HdÈùó!çɲÀ²À²@R\".—Å?ÿTüÓÂõïîîÈ(×(×(W{Åç:æ:æ: ¡£ÐQèˆÒDi¢´E:ž  Aª U
+L©§ÔSj`$a$a$pLvLvL†¶mÚVVV~‰~‰~‰À®_wýºëWÀrÄrÄrÈPf(3”ÀóåÏ—?_|ôÉGŸ|ô	·!nC܆E–o4šQ¨(Tj*ŠÅŠb`V2+™• o‹·Å{±–
+‚€5Ôj
+Ò­éÖt+P¡þBý ðzáõÂë@÷+ݯt¿èôú{x`c`c`#à~Úý´ûi À`°K>_òù’ϵ«ÚUí
+È5r\³È!2Ï–g˦ççÃïy}9úrôe»%%×K®—\_¤„ú}†>R!UHRò1ŸÇ|ó!ãZãZãZIe´2ZM.»³ìβ;d{{{¿=¾á†7Þ =.x\ð¸@Ö)ë”uJ²¥­¥­¥\öȲG–=B~œúqêÇ‹z²{²{²Iß}¾û|÷ÝSBª¯U_«¾¶'ÔTßTßTÌý6÷ÛÜoöqéyéyéyàÅÒK_,ÔoªßT¿	xj=µžZ F#‘'kOÖž¬B2B2B2ìñò+ò+ò+ÀK›^ÚôÒ&@Þ!ïw 2³Ì,3¿Düñ ($
+ÉBt't't'€Á̓›7+›V6­lÐÜÜL>ŠGñ(Hï×¼_ó~¼úóÕŸ¯þ|5¬a
+iK±¥ØRH[€-À@Ú²mÙ¶l’{¸‡{þ¦#íænî&mkmkmkIÆ1Žq$ýéOÒ*°
+¬Òö¥íKÛ—ö°™’™’™2ùpòáäÃvås
+r
+r
+H˜½Ì^f/r[Ö¶¬mYö	Y]Y]Y]¤ùóæþávû7¨\W¹®r)žψgHŸ­>[}¶’º]‰®äžÃ\K]K]KéuÉë’×%Rü©øSñ§di|i|i<iµYmVÛÿ¸^§×éuä;ŸØùÄN»°Ú.m—¶‹´…ÚBm¡÷$`½m½m½M8:qt‚6
+…¤çaÏÞ‡ÉSI§’N%‘ó5ó5ó5ÿñîÐîÐîPòé/žþâé/ìÄcŽÆ9J;;;Úç/¸LzMzMz‘šãšãšã¤0Q˜(L$eU²*YY0\0\0LÖÖÖ’ãÇþ{Â3Ûg¶Ïl'+'*'*'È ³AgƒÎÚ‰›‚MÁ&²#³#³#saü}ïÄã±ã±ã±dÞÞ¼½y{I©³ÔYêL
+
+‚28-8-8|GöŽì©»¬»¬»LŽ½7öÞØ{ä´ÿ´ÿ´?9]5]5]ENEOEOE“†W
+¯^%ËÊÊÈäMÉ›’7‘’Ï$ŸI>#FQ`$c¼b¼b¼ÈŽ‹;.Þ_€^êg3f3f3Èʵ•k+×’êUêUêU¤Ãr‡åËIÇq'=4
+¹~lýØú12*+*+*‹ŒÍÍÍ'Ueª2Uéû®ï»¾ï’!!!v¥W„­[FjõZ½VO'''<ØÁ‡þ+ñ'†††È¢²¢²¢22\®ב2™ƒÌNèAOßbßbßb2Ç%Ç%Ç…ÔéuzžœŸŸx>ÿ^5¡–ü+^   :tEXtComment  Created with Inkscape (http://www.inkscape.org/) ã+ld    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/24px-Cc-sa_white.svg.png
===================================================================
--- trunk/openchange/doc/doxygen/pictures/24px-Cc-sa_white.svg.png	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/24px-Cc-sa_white.svg.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,25 @@
+‰PNG
+
+   
+IHDR         °çá»   bKGDÿÿÿÿÿÿ	X÷Ü   	pHYs   H   H FÉk>  
+ IDATXÕX}LÓW>¿
+´–.Ôb±‚"Cèê(lS„9ɐuN&n Ź¹Œ,+&+™“à&3[a`Ë$™ãs‰3Ö¨L(ŠX¸Åñá¬EÄ4ElK¡åyÿy÷–¼µ/¾çŸ›ÜsŸsžûœÓ{·þmô”¶ðÃÂ?¬Y3²†èBý…úõD—7\ÞpyÑpâpâp"‘Ñh4DóÏÌ?3ÿQPmPmP-QØoa¿…ýFw"îDÜ	¢ŒÊŒÊŒJ¢8n7ŽKäwÃï†ß§eCDxJ3›ŠMÅÀgW?»úÙU ‚‰`"€Ä
+bý# À>Ê>Ê>
+p¸Ü€WÀ+à Ë3–g,Ï èú†¾q¯Ø°%`=== è&tº	ÀéŠtE.Í‹ñVœÁœ!ºxç❋wˆ>5|jøÔ@Ô#ë‘õȈ|Ç|Ç|Lj^,z±èÅ"¢m»·íÞ¶›(Žljãùùù±x,‹G4;;K499IÔÞÚÞÚÞJÔ¾§}Oû"s‚9Áœ@$4
+BQa~a~a>Ñ!Û!Û!o„7Âyš
+¬Çz¬ßi|§ñ`ÕЪ¡UCnÅdý²~Y?ÐÔ×Ô×ÔLÍLÍLÍ<mÝ6—2—2—T•A(®+®+®œ@N '`óØ<6PVV,»-»-»=ãxl@Û§íÓö¢pQ¸(`~a~a~ru¹º\0zbôÄè‰ÿŸðR6ûòì˳/ÕiÕiÕiÀÊV~°ò€9Çœcڝªª€cÂ1á˜xÂîšïšïšYº,]–îV<÷ZîµÜkÀCûCûC»wÖ	ë„u0D¢Q@]i]i])Pý¸úqõc áZõ†kÀ-í-í--0ÏÌ3óŒgW›«ÍÕœÞtzÓéM€¿ÙßìoVYqdÅ ©µ©µ©uñ>ÂGø8¶ãØŽc;ÜÄãËãËãËS‘©ÈTäxÏ®ž]=»€Wv^Ùy´
+Z­ SÏÔ3õ‹~Ü&¶‰mÄ_‰¿
+;v(05›šMÍžqÝÎng7P¼¶xmñZwœ—^éõ—^îõÝë»×Ð`é`é`)°áµ
+¯mx
+Xž²<ey
+ÐÕÕåøõS×O]?<7ñÜÄsîÿߢ·è-€ÙÆlc¶$%)Iù(€TEª"U˜œ&§Éé™gÔ8j5’ƒ’ƒ’ƒ {#{#{#P®,W–+ª¸Uq«â@ÝÔMÝÀæªÍU›«€©´©´©4Ï€¶mÛ>äeò2y™'ñA„ B ”ØJl%6 nUݪºU€*Z­ŠÄÄÄ<qšM˜œœôÌ[–_–_–ï^Ÿ°.a]Â:€2C3C3CÝŽ£ö£ö£Oèu—Ñetn<¸ñ ç‰óÄyn'‹“ÅÉCCC¼W®ádž~¸9ÜnŽ¿ºpuáêBàfðÍà›Áž8½R¯Ô+€/¾ø`‹Ø"¶`pF8#"v4;šM$‹”EÊ"=[‹Ä"±Hˆ*j*j*jˆîß¾ûþm·Ÿébº˜."û#û#û#ïgêåÔË©—‰¤Bºèö¹Ÿt?é~Q¥ÇÒcñÄ…û†û†û+‚Á
+"×××"ò›ñ›ñ›¸Û¹Û¹ÛŽ»w;îzWðêÙ«g¯žÂËÂ˵P>“Ïä3€å[Ë·–o½ãq·qØkÝkÝkõl¥ÏÕŸ«?W{Â?~<$®H\‘¸Â½Þg®w®w®—ˆ³Œ³Œ³ŒˆÍÎfgQuQ—§¯È_‘¿"'Ò˜5f™Hë¯õ×úûëØ_Çþ"âïçïçïÿß.ëi=­'ò©õ©õ©õtϧϧϧ{Î3LÓAÄ–²¥l)éHG:"VPePeP%‘ƒëà:¸D³³³ÞóOØ'ìv¢Õ©«SW§åìËÙ—³È,7ËÍr"G…£ÂQá?—7—7—G4ùóäÏ“?{ú\WÀõœ_P-¨TDÖxk¼5~‘ckçÖݝî’TýQõGÕÞ;à|Öù¬óY@ÀÉ€“'Þ:Þ:Þ:@œ&N§cccÞñÝ‚nA· ý$úIô“;/š?ÍŸtƒºAÝN¡¡ü¡ü¡| ¤0¤0¤pQë}RôIÑ'¯³¾ÎúpŒ9ÆO 2Z3Z3ZÄŒ9s㇓w%ïJ޴ŶŶÅwDwDwDÀÅ÷/¾ñ}`Ëw[¾Ûò'îÍóožó<`}×ú®õ]ϼgfÏÌž™XZ––¥Ö¶¯m_ÛP‡¤CÒ!$ ~ø!ÐógÏŸ=zW²V]«®Uœ:N§n¡(Š¢(À?Ê?Ê?
+Í	Í	Íxž…gñ$ê
+u…º€®³]g»Îzæ±UÙªlU€¼D^"/Yto¨Ôj€ìB»Ð.ö(ö(ö(ÜýŠ~E?`ï²wÙ»<;„¡ChÞм¡y±D,ë	7ò¬V+Ø”»)wS.pI}I}Ií]¨æèæèæhÀÏægó³Á™Á™Á™€¾J_¥¯Zô1§Óê´:- ¼"¼"¼ø}ï÷½ß÷@uJuJu
+àZp-¸<8wþîü0ì7ì7ìJ5¥šR
+ùwæß™ÛÓ·§oOÞî|»óíNà”ñ”ñ”ý–ý€~@Äì‹Ù³Ï- at qqq?° ].HmÀ5åšrMǧOŸXm¬6V°²deÉÊàtÆéŒÓ€óWç¯Î_½'FZÐ8ßs¾ç|˜+Ÿ+Ÿ+\®W€ILbÒ;ü¦ô¦ô¦ØÜ°¹asƒ›xÒñ¤ãIǁñeãËÆ—¹×{¼			¥F©Qj V:+•ð[ø-ü@=®W÷ÎÝ;wïÜÒ„–2[Ž-Ç–4O7O7O76nlt—<”<”<zózózó<ñ^ßÄ–dK²%PVVx¾<_ž/À\b.1— I¶$[’
+|Éÿ’ÿ%Ðwê;õÀdÅdÅd`
+³†Yà k‹µÅÚÌlÙ:³>0|`ø P¯®W׫ù«òWå¯Ü:n·`ŒŒ‘1IÂ$a’è½Ð{¡÷‚w–|Ô;ö:ö:öÍÏ7?ßü<šš
+øˆ}Ä>b€4¤!
+ P(ØÉØÉØI Q‘¨HT ÉG’$d5²Y
+r2ädÈIÀçŸ|^p+½&nMÜš8 x x x ß1¾c|ÇÒ|ê%þ±±gÇž{(¯)¯)¯âõñúx=àÃ÷áûð—>…þC*C*C*N§€èôúÀ™âLq¦<=ŸYΧюéÈ   :tEXtComment  Created with Inkscape (http://www.inkscape.org/) ã+ld    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/CC_SomeRightsReserved.png
===================================================================
--- trunk/openchange/doc/doxygen/pictures/CC_SomeRightsReserved.png	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/CC_SomeRightsReserved.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,29 @@
+‰PNG
+
+   
+IHDR   Z      ¬a	x   	pHYs     šœ   tIMEÕÌIð   bKGD ÿ ÿ ÿ ½§“  ·IDATx^í™iŒUEÇû¾{ßÚÝ6ë"²Š‚@ !`˜DÇ¡Ä	"Œ2	×%Æ(ê—D£ñƒ1¨â’Œ@Pƒ¢HezXš¦é†¶~¯ßrç÷ïÜêyV¼1í„VòçÔz«þuêÔ¹÷9%¿Nr@$Bd\ºP¤Ç¤KˆÒ•HD€’È|² Èh‘,Ò›=
+lœ)Ò›Íøí´2$Ù"ír«,n¤…˜Õ?À+B¸4d¤à `d‘ž—Þ†vL‘_‰h×&By#Äl
+,‹OHIÚyû¤Ø°N‡¤g¡èä ÒùnÑ‹0g­Kë!íi6IÁ¶dËŠ…‚bÉFÝ?Ÿ-ÚŠ°áÙ–eÈO&“‰gŸ}vä–-[¦œ8qâŽ\.7çÌ™3Ó÷ìÙ3áý÷ß¿büøñÝdÉňÅb©Ç{lÐ÷ßÿ‡ãǏϠÏÜæææ¿8p`ÎòåË+§L™ÒËz–
+{®ƒö½´Ú?Å­cݦ[e‰â²áÇw]¶lÙ´¾}ûBfxrçfÞ_|±»bÅŠ!ƒ
+*ÿ}]xÍÒ’V™OŸï	¤­{–.¸Xrì“O>ù“!yûöí
+7ß|óêT*õwÊÖ<óÌ3ûNž<™S]±%Óg˜!yóæÍM7ÞxãÚÒÒÒ¥lÀâW^yeÝéÓ§3ª3Ï	q5nHÞÎW‹ŽXVœ
+½ÄŒ/¾øâè|p¢Ø·o_ãСC¿J§Ó­‘ˆÁ€Ê>ûì³—^ziµÚÍŸ?¿âÕW_í!}çΝ§GŽ¹9“ÉüÄZ9%.}*{öì¹ð,–kK»¬p>Z´‰s£[å6\ÉÊÊÊ¡f€—_~ù_±#“½{÷:|ÈlÒ­·ÞÚÁôyþùç Ù³ýð¶mÛҐ¼È
+ýG2$ïXh—äµ?Ñá°7£OŸ>ÝÍ øéc¶»Q+êp±ú˜é³råÊûb³78¶1Ë@Îï8ڱɷõb²ñÑqÓøÈ‘#9Ûê‹`ÜI²¢¢¢mîÇŽioŠÉ
+ß\#C²†óÐu„è>ˆ„µÃU´˜L÷îÝcöÆXäy Ååè›>;wöl²Î‘<'l
+íî:|ßïÐ^ƒmܸÑûâ‹/R555‰£G&!#ÉÍŸjiiI€$~4‘ÍfS<3U(ù|>!YWW÷Ã%—\ÒScÜvÛm=Þyçã´ñ€"À´a¤<²y×®]±Ñ£G»êsÓM7¥/^|š0γD"qd©)D£Ñ‚ëº>(ñ<Ï!ïÁD€KÄâ^pÁ^×®]½þýûGG»æšk²í壎hÿ—ì&t¯ºêªDÇŽSç/‰ü1ÁDB„Cr²“È/ñï¾û®Ú=oÞ¼Á«V­Ú€•»l‚ ’ýnݺ9o½õVçIˆË}ùå—ˆ.UŸ‡z¨ÓºuëWsvIž€ï/ýõ×õÒò7òˆ|P"‚ãñx+ɉDB$srª¢½{÷Ž:êtåI¿”§VKqöÆç>8dF°4Y³‡èä©S§â”'xÃK at r\0dƒ¸ÈfÑ©×^{m
+. \ãa_¸pa͆
+2eee¥×]w]§Ù³gwÁÚ´‘GÔF$}øᇝ{õêå)_UUuúÍ7߬ٺuë:uÊOœ8±ãÔ©SB^‹ÿ+äf »b3œ¡:@†x=
+Ùiü~¦C‡é.]º¤ÙØQN3ýE´c‘z.ûtÑã•	'ôÜwÒœC‡űæ8¯Ã²è˜ˆ†ä¸¬ZRD$Çò²êaX—ûî»od—…ÎÜ÷Kn¸á†ƒÈV]ÀêܧŸ~ºë…^;[Ÿ»îºk‘!¤A‹ò\ÂÑ­`#ÓllVa61­S`Nz8ܧžzêrë±Ñ%amŠÛâE`)$¤°ž$H±¨V“ÿMqEJÒYdî¯]»¶™§Øƒÿ›P¨¯¯ÏàN¾ñÆGñë9Ú°´zvÍš5M¸™,㔀ˆéÓØØxŠ7Ìڏ?þx#d·@bIyy¹ƒŒX¯ "Pç"=ê$]¤GY4„#Ût›3ÆG;ç°3þ9„>>ĉ´$DuAZ×!b£"–%G%!$J[å¥{HwQ©
+ô­KQÒEF°´¶èEV
+òëׯo¤_=$çØì2+ g±È,® Ɔ—°yÅ £
+e¾Ñ 6/Ê<cl¤@— ±d»Ü¤zCô/ö=öƒt{ËBQuëÇXlD°#b£ê!
+¹Q]Ò3ä’—[sÐK(ó‘>I?%&)’€hî£ëtt´^~ä}‘Œlõ딹ä[A>á’Q ’uZZ@–òlȧÒPÂmiÝ1”àp_ä‡í¤Êb<‘*²Ñ•$[‰HÑ’Ê»"2%
+Éå!URd;"8€X³’¤A„ä—ä{$‘/QˆDIr³Áüäzb¤2«r…ƒg#ÖÒC91á]…UîôIaÖl„N^£+ŽÕÊÛˆ’Fò’&/˜ÐN1´¤±nG©Øª€acÝH§ØºE0R¹²æ"Œ/=t?´¡`.ÄšM:«±àDæΝ;ž[ÎsÏ=7’©O¿~ýî ³ˆoûh#Øåy›6mêÅGšÞ¯{T¦~Lêµ½þúë')o ±^N})Ÿ9ï ޝüî»ï*ÔJ¦HcÇŽ­ä¢Ià³Ëˆ›¯ tÅÇû¡„V1.¢èôéÓ/G÷„Ûo¿}0Ò%Vî?cÆŒA?üpß%K–t&Bé‡/¯Ï&JP[éJ֍¼ûþùç=xNœ‹-~íµ×þž—¡±<çwšÃK/½4Œ²Ê÷Þ{oëÓ<g]yå•So¹å–?Bt¹Öéó/ºè¢?ÃË:ùÄú3ùbÐý÷ß?fòäÉ•jp0Kñ2Ÿñf_}õÕS<ØCå:ŠKi2„cˤóðš>úèÞξ¥s
+eKu¤¦M›¶öJW;AþLõÒ
+L×°Œpn¹üŸ1WCBšèá«Ã‡¯¡,W]]ý-ñmý#<r€xÓ§Ÿ~ºƒ(ai;õy¾/Wñ¦ùoélø!Ð÷1ßüêÕ«÷s	îU9¡°[í1ˆ*µã…f'ÄgwìرEãë™|‚]Ïs×ñæú
+cdùçf
+¡èª¦¦¦•š'ó]¡y›uh}µœqšUÆî[°`ÁHÞùM{ý¦Œïè›Yã~éžv€jæCùer˜€¿ë¤I“T™ÇŠºj78R~CCƒv«Dºú˜c«úŸs/:®A¼ëзÖì³IerêÆÉ(…¨Ž/¼ðÂêÆ
+SûDàŠÅŒ®°‹:Sîña?ËßTwÞyç)Êü zl›i© TØYPe’ļT_àûvcêÇ	9B}^ƒ³¶ò mÁ¬ÃèƦ´®™“™Á:ó7Yù£>zTܨêŠ]ª)ã›ù)Þ./“.‹Þüõ×_ïâm*Ë—³²œÊ£ó Ü|°wÑ¢E²¦¶zŽHžÎ°ÓÊÛàRÛ*ÿ©yŽì¼*^`ªd‘¼Ììfü<ñî>\×q^:²lÈA¬þ ãØ"H¯­­=Ì‹Pý
+’K—.=¦·?Œ¢^yÕ¤Z¾›R‘Ìiiâ
+µ«Ý¯2æšÁ5œàÌ.>­V3FÒªpaÛ5Oꛃµl1ëÓéxüñÇkUÆÿ’Uãƍ;‰;Ép¯l	ã@ÙŠèý úÉ'Ÿlš5kÖIÞós¼Å€”ê=zäT/BL;£•WÊ[¨D*ǹŽ;@ãÖæRúa&œƒ˜zȯg¬ßEØ€£ÒqeÇ8ҍÒ% I—ظ33gÎLKW½ú©þ»‰gæÉ7˜ñ±ò:=bk™GíO<q‚5Ÿ‚´ƒšɬŬO›yˆq²Í~ÚíÇ r|ljV½Í]ÆZÈ€¤·º\òÀ8É2þiÎa᝿riåUï,wa¹Žð¤(`ĈI6P_÷:rüä
+”ñ¨ÀeTqï½÷fƒ<eúqA%m=8þ	Í—>%ƒŽñ}CãÙQQ	mEõLŽzÏÌ«LÏ4m!ÚçBup›)½ä ´­Å¬¿ÃÊÇá.è<f̘<—œÏ¥ù³|˜²·ß~;Î=W0®Ãçvô9¦>7±ÏÅáCŒÏDýÝ»wûJøÈVië,ºµíœ9s|;Ùí¹©}.Ÿ”aŒ>dû,ÆçHZ}Btk¾çöL{®öv}ø8Òq¡¡˜²!C†ø&Lðq]¾DÿÊé7üFôÿÿj|w‚%&    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/body_top_bg2.jpg
===================================================================
--- trunk/openchange/doc/doxygen/pictures/body_top_bg2.jpg	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/body_top_bg2.jpg	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,3 @@
+ÿØÿà JFIF   d d  ÿì Ducky     d  ÿî Adobe dÀ   ÿÛ „ ÿÀ  –  ÿÄ h              
+                        að¡q‘QáR’¢            ð!‘1aQÿÚ   ? Ô¢±Õœ|W¼	í|ua³Dbe­‚hŒ*ø
+VÁ&ÅrV¹´,¸^Â-~TbÁÐéÊ—=©xj䮤*ÿ Rb²r %7L‘ñÜŠ¶5ø¦èªÞV¶ ÿÙ
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/header.jpg
===================================================================
--- trunk/openchange/doc/doxygen/pictures/header.jpg	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/header.jpg	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,612 @@
+ÿØÿà JFIF   d d  ÿì Ducky     d  ÿî Adobe dÀ   ÿÛ „ ÿÀ  Í4 ÿÄ û            	
+            	  	
+		  a!Qqð1A‘¡¢d	±"Ô%U•ÕV–Ö”WÑñ#EÁá2DT·BR3C$uµ&g(8x’S£³4…6¦hbc¤´Å†G§) 
+
+	 !1AQq"“ÓT”ÔUa2‘¡Ò#³´u6±BRVÁÑb²3$v'7ðár&ñ‚’¢CS%Âsƒ£4Dct¤5ef(ÿÚ   ? ýAîÊåSñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pìSpvPŽŠnÊñMÁÙB8v)¸;(GÅ7eáئàì¡;Ü”#‡b›ƒ²„pì__gÓâ£êE~•²O\VݪÏãžà…·#÷Á?Nž•cÏ´Ôô™Û£¾!àÞÖ²x¬.c;s÷<%Íåå+ÝÁ’¾ºckO¦‹£Êcq0}ç)sµµi®W¶6׳Sȍpo×'üßÆWí¬?þ«[7ð¿™áÜï¨]ù¥‚øócûëëvþqkúß„ÿ ›øÇñå­õ¥?á2ÿ ùßP»óHøócûçëpyůëvþoc/Ç–¿Ö”¿†Ëÿ ç=BëÍ#ã͏ïœW­Áçýn¿ÍÜeøî×úҏá‡2¿Ã¹ÏPºóIüy²=óŠõ¸<â×õ·7qŸã»_ëJ?†Êÿ ç=BëÍ#㽑ïœW­ÁçýlÂÿ ÍÌiøê×úÒ—ðÇ™?áÜç¨]y¤|w²=óŠõ¸<â×õ¯ÿ 6ñ§ã«cë:?†<Êÿ ç=BëÍ#㽑ïœW­Áç¿­XcùµÛYÑü1æOø{9ê^iì|â½n8§ëNþlãoÇ6ÏÖt¹“þÎz×šGÇ{#ß8¯[ƒÎ-Z0×óg~8¶~³£øȅðösÔn¼Ò>:Ù>ùÅzÜqkúφÿ ›ßñųõ/áŸ2?ÃÙ¿QºóHøëdûçëpyÅ?Y°à÷²¾8üom}gGðË™áìߨÝy¤þ:Ù>ùÅzÔqkú͇šøãñ½µõ•Ã>d‡³~£uæ‘ñÖÉ÷Î+Ö óŠ~²áßæ¶9ümm}eGðϘÿ áìߨÝy¤|u²}óŠõ¨<â×õ“5q×ãkoë*_ÃNcÿ ‡ó~£uæ‘ñÎÊ÷Æ+Ö ó‹_Ö<?üÔÇ_m¿¬¨þsü?›õ¯4ŽvW¾1~µœSõ‹ÿ Êxïñ­·õ•ÃNc‡ó~£uæ‘ñÎÊ÷Æ/Ö ó‹_ÖCüÓǍ-Ϭhþóü?›õ¯4ŽvW¾1~µœZþ°b/æ–<üin}cKøkÌ_ðþkÔn¼Òì¯|býj8§êþ"þhãßÆvçÖ4
+¹‹þÍz×šGÇ;/ß¿ZƒÎ-W±óGþ3·~±£ømÌ_pf½FëÍ#㍗ïŒ_­Aç¿«¸“ùŸ¿[¿XÑü6æ/¸3^£uæ‘ñÆË÷Æ/Ö óŠ~®b_æ~?üenýcKømÌOpf½FëÍ#㍗ïŒ_­Aç¿«˜›ùÿ ÛßXQü7æ'¸3^¥uæ‘ñÆË÷Æ/Ö ó‹_Õ¼OüÍ°?ÛßXQü7æ¸3^¥sæ‘ñÆË÷Æ/Ö óŠ~­bæmƒøÂÞú—ðã˜~àÍz•ÏšOã}™ï|_­Aç¿«8§ù™`þ/·þ°£øqÌ?pf½JçÍ#ã}™ï|_­Aç¿«§ù—a~/·þ°£øqÌ?pf}JçÍ#ã}™ï|_­AçýWÅ_Ì«ñ}¿õ…ÃŽa{‡3êW>iìÏ{âýj8µýVÅÌ›ñtÃéy…îÏ©\ù´|o³=ï‹õ¨<⟪¸°{Ù&Äü]ðú?‡<Â÷gÔ®|Ú>6Ù¾÷ÆzÔqkú©‹™/â؇Ñü9æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_ÕL[üDZÀü>á×0}Ùõ+Ÿ6ŸÆÛ7ÞøÏZƒÎ)ú§‹¿˜ö7âȇÑü:æ¸s>¥sæÑñ¶Í÷¾3Ö ó‹_Õ,_üƱ¿A|:—ðï˜âÌz•Ï›GÆÛ7ÞøÏZƒÎ-Tq€÷²-Ž?þë‚øuþ`{‹1êW>mìß{ã=j8§ê†1þbYŠà¾Gðï˜âÌz•Ï›GÆ»;ÞøÏZƒÎ-Sñ—óÈüUðê?‡{ÿ ÜYR¹óhø×g{ßëPyÅ?Sñ—óÉüUðê_ÃÍÿ î,Ç©\ù´þ5ÙÞöÆzÌqkúŒÿ ˜VWâ˜?‡Qü<ßþâÌzÏ›GÆ»;ÞØÏYƒÎ-Sq ÷²•ø¦á´w÷¸³§sæÑñ®Î÷¶3Ö`óŠ~¦c_æ
+—ø¢á´w÷¸³§sæÑñ¦Î÷¶3Öaó‹_Ô¼müÀ²ÿ B|6áîþ÷cÔî|Ú>4ÙþöÆzÌ>qOÔ¬müÀ³?Â|6—ð÷{/êw>mlÿ {c=fËZþ¤ã¿öoâx_†Ñü>ß¾ãËúÏ›GÆ›?ÞØÏY‡òÔýIǬßÄп
+£ø}¿}Ç—õ;Ÿ66½±¾³å­R1ÏßÛ;ñ4/Ã(þoßqåýNçÍ£ãMŸïlo¬Ãùk_Ô|s÷öÎüK
+ðÊ_Ãýûî<¿©Üù´þ3ÙþöÆúÌ?–§ê6:ûùgþ%†øeÃýùî<¿©Üy´|g´=íõ˜-kúŽþýÙÿ ‰a¾Gðÿ ~{“/êwmí{c}fËSõýû´?Cü2€7ß¹2þ§qæÑñžÐ÷¶7Öaüµ¯ê&<ûõh~$‡øe/€7ß¹2Þ§qæÑñžÐ÷®7Öaüµ?Pñïß«Gñ?Ã)ü¾ýÉ—õ;6Œö‡½q¾³å­Pñ÷ß›GñGÂé|¾ýÉ–õ;6Œ¶‡½q¾³å©ú…¾üZ_ˆâ>GÀ;ïÜ™oS¸óiüe´}ëõ˜-kúƒþüZ_ˆ¢>GÀ;ëÜ™oS¸ói|e´}ëõ˜-OÔ÷ÞÓüEðº_ ï¯re½Rãͧñ–Ñ÷®7Öaüµ¯ê÷ÚÓüCðº>ß>åËz¥Ç›GÆ[GÞ¸ßY‡òÔû`ýöµ?Äü.€·×¹2Þ©qæÑñ–Ñ÷®7Öaüµ¯Ûëï­©ø‚'át|¾}Ë–õK6Œv½q¾³å©öúÂûëjþ ‰øUoŸrå½RãÍ£ã£ï\o¬Ãùk_·¶ßKWñW¨ø|û—-ê—mízã}fËSíå‡÷ÒÖú~+áT¾ßåÊú¥Ç›GÆ;KÞ¸ïY‡òÖ¿o,?¾–·Óñ_
+£à=ñî\¯ª\y´|c´½ëŽõ˜-O·v'ß;_éø¯…Qð&ø÷.WÕ.<Ú>1Ú^õÇzÌ?–µûwbýòµþŸ‹øUïrå}RãͧñŽÒ÷®;Öaüµ>ÝX¿|­§¢þGÀ{ãܹ_T¸óhøÇi{×ë0þZŸn¬o¾6ÇÓÑ
+£àMñî\¯ª\y´|a´½ëŽõ˜-köæÆûãl}=ðª>ÞþåÊú¥Ç›GÆOÞ˜ïY‡òÔûqcýð¶~ŒøM/7¿¹²¾©qæÑñ†Ò÷¦;Öaüµ¯Û‹ï…³ôìgÂhø{û›+ê—mm?zc½fËSíÅ‘÷ÂÙúv3á4|½ýÍ•õK6Œ6Ÿ½1Þ³å©öÞÈûßm}9ðš>ÞÞæÊú¥Ç›GÆOÞ˜ïY‡òÔûodýﶾœŒøMïose}RãÍ£ã
+§ïLw¬Ãùk_¶ÖOÞëkéÈÏ„Ñð.÷÷6WÕ.<Ú>/Ú~ôÇzÄ?–§Ûk+ïu·ôÜoÂhø{{›+ê—mm?zc½fËZýµ²¾÷[MÆü&w·¹²¾©qæÑñ~Ó÷¦;Ö!üµ>ÚÙ_{m¿¦ã~Kàmíîl¯ª\y´þ/Ú~ôÇzÄ?–§Û[/ïm¹ôÜoÂhø{{›)ê—m/Œ6Ÿ½1Þ±å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=RãÍ£ã
+§ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿	£àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4|
+½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=RãÍ£ã
+§ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;Öaüµ>ÚY{mϦã~GÀÛÛÜÙOT¸óhøÃiûÓë0þZŸm,¿½¶çÓq¿	£àmíîl§ª\y´|a´ýéŽõ˜-O¶–_ÞÛsé¸ß„Ñð6ö÷6SÕ.<Ú>0Ú~ôÇzÌ?–§ÛK/ïm¹ôÜoÂhø{{›)ê—mm?zc½fËSí¥—÷¶Üún7á4|
+½½Í”õK6Œ6Ÿ½1Þ³å©öÒËûÛn}7ðš>ÞÞæÊz¥Ç›GÆOÞ˜ïY‡òÔûieýí·>›øMoose=RãÍ£ã
+§ïLw¬Ãùj}´²þöÛŸMÆü&··¹²ž©qæÑñ†Ó÷¦;ÖaüµÈ[.Õâ)8há'(,™Ed"©,’¥¦ªJLEP‚S ˆ¡ZÜðMk;í®ctw1¼µìp-s\ÓG5Í4-sH ‚P¬ô3Eqn-Þ×Àö‡5Í!ÍsH¨s\	AÄ/£³éñWÔ¹+ô©Ùôø¨ú‘_¥bï¼JÆàXññ‰¶•Èeƒ‹\D[G2NJ&CC6*ä1ORöêÜ 6¾ñÈîKÞsS,û«×>
+§hð'•¿jGÐ8A<‹H/u†–ð«‚ònió6Û`ãÛ«Y.á¸i10ý–7£½xtÖ¡£†§Æ€¯oL…xäi¥®Òᑸ$Ö1÷T|¹Ì‹DÎmïFhV±í?䤉˜sk_§[khm͝n'mYÃidÐ*Ðò8j‘ÿ jGž·<—Õð¶sqf·-ó²9ˉn.[ƒýV7ì±£©­ .(
+uV|µb*”ë©ÓDꔪmÓÜþŠ’;SªPS¸)P&
+PSn½=ú’ÔU()ÕRZª©ANº)Õ)UÛã¤GjuJ
+wM`¥*›u÷jKSªPSnÞ*’ÔꔨÓN…UL
+íñÒ¢uJU:½ÊšR‚}‹SªR©·ÇPZR‚•ORuLUzüƒJ©Õ)TÛ§Oz•N©ANà¨-L ¦ÝjUU)Tê÷*t”ÁL
+XRN½‰J¦Þ¡¥¤'T §UAjuJ
+uÔ§T¥So½SBª©AOë褝{Mºûµ%¡:¥*›t©-N©AJ‚ÔꔪmñÒ¡N©ANò…MªR©×ÑH´&
+R©¶ µ:¥*KU”Û¯MMN©ANò…*'T §^ЩҝR‚›jKSªPS¸*S)TÛ®Á©¥ª@S¤<´“ª`S¯¢•uH
+m©-N©@üõ©‚ªsPÔ–§T §pRâR‚›u¥@RU%©Õ(yõ©-Nªà~ª’ÔꔚŠQ:¤ŸNš<)Õ()J€§T€}µ%©×ëH)Õ 9ô©-N© ãÓSDU 9ôé¥Ç­:¤ÒàSW…-)Ô¤=Iju€~z)ñWs
+I¨ª@?8x©S±5p?0ÿ M.=iÔ¤ÑÀ£‚¸)Q:•p5M¨ëWÒÒŸ\SBŠö«„<4¨ª¸<5:SVs
+.!UÀÂT'^Õp?pQNÄS±\
+J‰ÔŽ•®´¨Š…`0ôÒ¢t
+À`è¥E4ZÒIkB¡
+P…(B”!J¥R„)B¡
+P…(B”!J¥R„,®Áw¹f"Éc	“8±K^ð$Óþ@è§_›ûç÷Û1ûVïôò/»¶‡îž/öu·èX²?³îÒµo¶/À§gÝ¥…~pxš»e®Üõ•K¹2ÇŒ½ni57fÞ*Ù”u‚D¦ сL}4ÞPÆ0òˆ×ì?%0V.U` Ç°5³ãmî^zÝ-ÌMžGÒ|g+ÐÐ@ó{š[¼¶ÿ ÊËxíF+é hêÀ÷DÀ;<ViÒI=%th)Ï^£Jt-©
+¦Þª^ê”î
+šŠ¥*›u÷jKSªPSn•%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T ¥Nšt'T¥SoŽ¦©Õ()Ò¨
+uJ
+uôT–§T ¦Ú‚ÕUJ
+TéìN©Š¦Ýi'T¥SnžP© )Õ()Ü%©‚”ªm¨-N©J§UM
+ R•N¿ ÒE
+b©·ÇS¤ê”ê©-UT¥S® µ:¥*›¢¤‚R‚ÁJ‰ƒØ˜ªm×È5%©Õ)Tê©-N©ANz‚ÕUJUvøêhSªR©ÒP¥Dê˜ëè©-N©J¦Ú’Ôê”î
+‚Ôê”Û¯O~¦…:¥6ˆt÷©QUR‚ÁRZR•Mµ%©Õ()ÕÑPZ˜)AN÷jhBuJU6éÓJ:¥)iìN©J¦Ú‚Ôêêè©-N©N÷jhBuHU6éÓÞ¥áN©AN१±:¥*œÃÝÍPZRÁRZR‚›uéîÖ§MªPSª—ê”ë© N© áHµ:ýiNº‚ÔꐷNïIjª¥÷M)Њ¤*œÃÕG…:¥Ò =	Õ ˜jKS¯j@?=IjuìWó•%©Õ(ŸÉSNÄÕÀüÃã¥áN©@ô¨
+ÀáÝÉHµ:Ÿ
+ at 8ÿ ]Iju
+àpðÔéN© ãàjHNªà~~JT#¡	 üÃKUÀôPpH
+TUR®zš" «ùêt§ÅXá¥DU\!·¦¦5p8xy)P¦®Ì:Ò©	Ô…p8ÑÁ€ôQìWë¥DêGJ¶´¨AVÞšTJ‹]à¥B•
+µ$”¡
+P…(B”!J¥R„)B¡
+P…(B”!J²W‡õ,ˆéß‘yÿ ¯=~ooŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bËžË`÷uV®¶À§e°{º¨Gà_˜è}3~dl«ÃÅwK‡~¿hùXðÇn~ÁÇþ©
+üÊߧÿ =f¿k^~±"êàSh‡¹[ÙjÕj”ëÚ%¨ªR©¶ µURœô¨SªPSo»Zšv§T §WE-5N©AN¾Š’Ôê”ÛÝîT§T ¥MèN©J¦ßv´©ÚR‚!ÑKMSªPS¯¢ µ0RMµ%©Õ()QCԝS»ué¥DꔪmÓÊ‹AN©ANà©-T
+R©¶ µ:¥*U4)‚”è%Mªb©·¨iÕ:ö¥;‚¤µ:¥*›u¨-UT¥SnžåM
+uJU?¬*h˜)Š¦Ýz{ô‹SªPSª µ:¥*KSªR«·ÇSBR‚]4	Õ0)Ð4‹SªR©¶ µUR‚ÁRZR•MºôÔÑ:¥*›D<¡J:¦?¬*KS)TÛPZR]%ªL
+tjhSªR©·ÇJ:¥*KSªR©·Z‚Ôê”êè©-N©AN¾Ššê”Ûã¥@R‚œô‹SªPSnµ©Õ )Òªª”ë÷iP¢©J¦Þ¡¥Dê”ç©Óؘ)AMµ%©Õ )ÕÑPZ¨¥Sn¾íM(R›t¥áN©AJTHÛHµ:¥óÔ¦
+@?0鲤µ:¥9ü•4)¤*œÃÕþ*^ꐥ§±:¤ó
+"ÔëڐÏQ¥:¤óUIojuHçòR¡êM ˜{º)xSª@?=*Њ¤í¤BuíHš’ÔÁìW‡EM
+uH}jKBuW‡E*Є€na¥^ÔëÚ®¢€ô'àW Ò¢u=jàaŽ¤„T+ùêt§Å\˜iQWMM¥p8tR¡V¥^ÔêUÀôpGp0QDqêV¥DëÚ¬Ì4¨Ÿ­½ÏJ‰QX•¡ZÒIJ¥R„)B¡
+P…(B”!J¥YGÃjz¤üyß»ÿ ׿7·Ïï¶cö­ßéä_wmÝ<_ìëoбeçb;|•«­‰NÄvù(Bü³ç£nçLÐí2ÎFá0ûOʶÿ Ë
+·ûú¤+ó#üõšý­yúÄ‹ªÁJÞèµ:ýINª\zÓJ
+t’•*Û§MIjª¥óÔ¦
+B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”î
+‚ÔÁHU6Ô–§T ¥M
+uL
+mצ•;SªPSnžåNš§T §pT–¦
+R©¶ µURNªšê˜èTN©AMºtÔéªuíJ
+wIjuJ
+mÖ µ:¥*U4)Õ()ܸ&
+b©·ÇHµ:¤:ªUU0)×PZR•]¾>õ*ꔪXTÐ'TÅSn¾íIjuJ
+mÒ¤µ:¥*SªR©·]ƒJŠª”é(TÒ©Õ0)×ÑRZR•Mµ%©Õ()ÕÑQ¥:¥:È4¨R•M½CR at N½©ANà¤ZR•MºÔ§T¥SnžåAjª¦:ú)'T ¦ßMuJ
+uR-N©ANº‚ÔꔪsžçôT–§T §pT¦bR©·Çߥ@R‚U%©Õ()×PZª©
+§0éÝâ©-N©ANà¥Å:¥*›|u4ªPSª‘jª¥6ëPZRU%©Õ((=54¢uH
+mÓ¦—…:¥óÒ =ª@?0Ô–ªªP?=N”ꐧ桨-N©Nz\SªPSn½Þ:\:АKObuHÛRZ~¤€~z’ÔêÌ:ôÔ–§T€~~JT#¡4…?0ëK{RéR½¯b@?0÷tT{UÀýu%©×±\ú
+"ª@8ôÔiNªàpè飈OÀ4¸u¢½ªàz(Ÿ ¦‰×µ\4ˆ@§R¸<<•:S©Væ’;Sª¸|<´´¦®})P„+†•{Sª¸Žà¬
+(Ž#¡_ZTOWjÔ˜iQ>[{ž•¢¶ 4’¢Ö’JP…(B”!J¥R„)BYðÒ–¨<;ï\ùU0ø«ó{|þûf?jÝþžE÷vÐýÒÅþζý`ö;<•«T-‹þÝ*v;<”T#þÝ+ò•ŸÍ»žshkÞ˹$4—”Í~Öò¨Êý·ûú¤+óü÷šý­yúÄ‹©€ýU¾­N©@ýu%©Õ )·J‚Ôꐚ'T ¦Ý;¼TxSJçÿ MRuH
+mê’Ôê”çä©-N©
+¦ÝjSªû™6y éQí\½xàà›v¬ÐUË•Ô0èTÑAUNo  ×ÒÇfYÜÖBÑRç ¤ž[ùÀ\ãÐOàYKcðožïTÐr[IKyŠú®n5>/W³0”@bRªø©Ã@2e
+5¯7ÌókcaÜcuÛg¿Õ‹ÇãÙ«ƒz»|+mÆì}Ë“ðÛ=±ž5p§¯Â<+¸à2è†dçn„ƒEÛ ©XGª)¦.I¯½Qs	”1¬TÄ ¼¢<•ªÅÎìMäÝÕ•»ŠHÔáS@]Ð:*ÐOJÊÍ°o,ÁûãÈ¡¡£M:iÓÆ´<;*¶ÙÚ±)ÿ çƒÒ¡È.b„©ïhôÆn7Cx{ýí9DC½]«~k™Èÿ tiû2Ÿý=«„í á;ª[H‚ºÆàá®àˆrá«Y¦.\ šJKº
+²b²~Žå#%5KCrD
+` Ö¶+`cîãl¯ŠFÆâE{(iÄ#¾#¤®ÆÔž²F—Ž®Úñ ‘кVn͹mÓÆQª‘0HGEÐäå×}=t^PïVÝi—ÇޏÌH5£À¬Î6ö׌Œ%½£ˆ\dëò
+dhB©MºtÒ-N½©AJ‚Õ@¥*›u©-N©J§UM
+uL
+uÒ N©J¦ßIjuJ
+uT–§T §]AjuJU6éîTЧUÚ¸kßÛ!@ã\{Y†uSˆ(º‚Þ6&9¸’S÷TôH¸Ô5:§C‰¦E9mcwîÌ&ÈÀO¸óòì  UïyàÈão
+Oyà 8¹Å­pÎíͽ”Ý9x°¸vk¼”õš5iï=MhâOzˆÖ»—†ogg1QŒø¯ÉÒWîF~Å'«Ú±on&†äû@ûfÃ2sñQ«†".å¤IÈ”D‚AÔ…ùœÝçŸ3ndŸ—0ã¶ûZٞ؜ziãKroxà\Èb%WIú5ü¹åNÆ…‘o[¹/sh&6:FýXà!íiè–@Ò)Ð>7{,ø·]K/ dIÜQ“Ý$¸Á@Ê>ºAÓåÐ)tôxlŒåó[°¦L¦TÌã%Sz	”ÇÌ„8î¹—üÃr茖òµ¶ÊàZGxö² ?ÿ Õ¬0ž€,.Ž´q* ØüšÞ€Ùm©æÇåÈ:]!$ô'.véŽPúTðy¡Ä>¿¸gÉ1ÖAj¨dFFÛ¸˜‚ƒ	v@¨±ÑBZ)U CDÅ7
+”ÑfËJmJ$9þ¢å÷0°ÆÁ37„qkÓ,N§y”©cÀémxñ^Þ"†­¼6n_ee‹Ê4MQÈß±++@æ“Äv9§‹OŠÒÅWn½5½P­N©J§W”)Pê˜ëè©-N©
+¦ßAjuL
+TéUT¥W¯È54N©J¦Ý:{Ô¨ªPS¸*KSªb©·Z‚ÔꐪuTé)Õ0+Éà%Mz=í á×pÛgá«´ÓW×ùçK4iy•¥Pc¢­Çˆz*j¦@o¢²Šk¦º€‡5|ÏÉ.iîmñ—ËÙn7Àè,û¾ëDa‡Æ|­5 šðcWºsO``¶¦7u…l¢[}æ·—±‘N8¸¯9ÐpUS*…C ×ÒbŽÃÏB¾S®‘j*”ªsžçôTé)Õ0)ýaI0{•Mºûµ:BuJ
+uT–§T §]AjuHU6øêtªª`S«hRER•Mºû´¨ª@Sn•%ªª”¨-N©AM¾:)Õ()Ïã
+”ÁìJU6ëîÒ N©ANªE©Õ )×PZR‚›t÷?¢¤µ:¤9ùv…M
+uJU6õ
+/
+uJ
+sÒÓ؝Rù†¤µ:¤÷AjuJ
+>½5:Sª@Sª—ҁúépER–”ꐶ¤µ:ýJàpè©-N©@ãÏ­AjuWõyiP§T qç×ËK‚jàz4ö'^Ä€na©!íHç©-M\
+Ì:TRÇÃËS¥5p8séÓKˆN© ãGpëWÒ¢~p7pR!:ö«Ç¦¤µp8R¡N¥\>©#µ:«ù§Jjà`ðÒ⬢½©×µ\ÝÞ¢ÀÛ|tQB¶´¨ž¥`0ÔÑ>[{ž•¢×]hIkI%(B”!J¥Y‰Ã"Zµt:wݸý!¼5ù½¾}³µnÿ X‘}Ý´?tñ³­¿BŘ½vµª­NÇ»Z¿%œB˜Ÿów´Ì90<W¬ØWí*›ÿ +¶ßìꐯÌ-üóÞoö½çë.£o”Z•G (¸õ§T §]*êÚ!îR-N© ý}©Õ mIjuúÒ‚œõ4=IÕ)TÛKšÍ¸,ÉœMÉ¢ù™
+jcÔvR7¤ƒU#žÄÁéMmæB)šUÚaïL}â7Hâ1÷½àù3¹Ã·9qla”ýë<æÕ–í R½•Üt4ôBâ8N+Ñv?.3[Òq$_˜ÅãLàxÓ¤FÞÈí¨h<	¯úÆ<$`Îà›’
+Þj¼â¢Õ£›‚h©J\²K¸U4@@æ 2(²ý’%"]  F¾ÜœÕÞ¼Á½q½¸sl†§£«!` Ÿ®€t¸—Þ+ê¬7/6®Òµos_thä£äq$•'¡  ¹}Ë?EHݲ`}4
+5
+t!OÈ!ÑXœuÍÓƒ¤q¯ÖJÉß^[[4Ð €Œ¹2í:ï“f%#"ÂÌHwGMS¼Q§ÆŒØ§ÿ Q2"Ôë¢*ÚœNA
+ 4¯IÛx±?~sžKûÈÙAQ¤;CœxƒW à áCÒ¼ßqÞýêcbэ‚7¸’.-Ö>QRxÔt.¸ÁÔ`9p¬rU¶ªö/»BRòŽ¥3cx¥þ€¾ÁtW}ÔM‘À;…[Bþ׬ý+L=Áµïß##™Ä
+Wé T•Ã%0z«uœ1lªNY±lGGP§Uºí[z:E1A¹;!U°
+aÐ ÄÝY[qq]ops^ò@¨TõšÐÖ¾õÃmËZHkšæ´H$)NÒà6tT»uÐ(£¤À@éiÛ4PL'2J”Šö§HU
+DtÝ0ˆw‚³Ö™››g‡>ˆõô8vŠŠOè\ca˜‹ êêðý…bÍׄ;~áó3e%¸²ÌôìÚÉ•2†Lœ€T]ƒ©Š:r ›”¼¡èÍé÷hÃåÖûZÑÕâYôöÓéâ:ºV§}¶ÅËÜÖQ“õ§ÛðýKæ¡¥íÉâæY,Åësn¨ŠÀÈ S¦r	“P‡(€Š"^‘ÈYå-ÅÍ“Ãã=#è#¤-òÊæÂcËK_øm¥Sª»ÄÕªPS¯¢¦:¥6ø颩ANª‚ÕUJ
+uÔ§T¥Sn”¨Sª`Sú¦0R‚›u÷i§Uï²ù„!ᓉŽ*åcŠòJÜgv¤˜(,6Æ/²P¾d2T¥¦œì”ˆ&¨Q:ŒSäÔ¡¯Â¿Íýæâßø\A!m¤‚'štw×sºÝ®pë1±•o`‘Üx•õw!í-°ÛC/½ef«†wéîíâ8Ø÷:‡´°v/ÎmËv^yÊÿ ¹ò
+ñ0îjáºæžMLÉ:Pç3‡oDŠcfÙ=Ô›¢MA2HR€}7€ÀÚYØÁˆÆF!Æ[FØã`àZ)õ“Òç.q.$’Jð¼¾Zâæê\óÌ—ó¼½î=$Ÿè € €.Ml-ò>bAìTÜCÖ’‘R±Î–g!'ºnØ¿bñ¹ÓpÕë7ID”!Šr bˆl·vÖæÙöÓµ¯†F¹® µÍp!Í ð ƒB
+ÁÙ¸‚fÏ‹$cƒšA¡‚è Š‚:草PâCÙ}‰¸ŸœI±¯Ë[BFj]š w/¤n„pýþÙºiãx雼È=ôtôìŲ`<„øƒ–lŸ–œþÈìkg8bî¬k	'ÅýîÜšô¹ÕšN§µõ>ùt[ã”6[®pӍÅÔh¿îóØ×IGPti‹¯ø<à“ñ¹jôŸ“²îtç®I^ËM‘~߶­™F.eŸ:Žzvñ‰ŠVúnKÛ® "‰Ì
+œ¤Ž÷Ìþyo=“̶müD1]⍴E¶ýÝd’YXàƇ¶¯§{ éhÔàAÔj[•;gtlgfr2Éo¼µÑŒŽ7´¸–š7ìjq $P(­f\ÞÇ®øŒÂÑ°y	I)Gmm˜|Å55|FÛ“So\›Š¹nÖÉǬñÚ…!Vun3Ž(˜}ÒjjÆå2ßÍ?ýÕ5æ<@Àe}Œq[>HØÑW0àMtù:'‚ïXc¹y|Üv׆gnß$ÍcÜMá( “®·k;h8¬Aã[†ü%eVV¹dœNØדS–Àñ""ùvlÜ‘´œ¿bšMTœ€U ²ˆ”©,ƒ„V$*
+)ûw'y­mÌý¾ë¹£m¾rÙâ;ˆÚIn¢*Ù#©'»P8’×5í«ƒCå|Êåôû0-£{¦ÅNÒø^áãP9 [	"€‡5ÔÒ3^ßá#†°Ì`ã®beåÃw‘3BbÈG²Ì×AUZðA½¾â2nRàbÐå3õÌõœk%Næ0¦ª¾9›ç/0÷þë¸Ûšd1c-	^ÊÖ8:ŽÓÞVPøÙœ‰¢9&ú©¬ô¼_,önÐÛðçy˜éd¾¸E«öÒ£VŠFZ÷HÑöÝ­‘°5&Žv㋱W³ƒŽÖ'¾pžX‡Šs0Ê"æy5"õÓDTI°É:‰œ»o(yèvΦUÒŽ”jõ 9Na)?ÊÄe¹Ï~U]Ñß²ÍmÉ$s¢dl š-’(-ßÈK¥‰ñš=~Êå70-ä²ÚͺÆf˜Â懹ï$tUÌ’YšöEC$cÅA<:p7á"¯ÅͷÞ[báºÍò¶eÞÊ9éÛ*ªh$åB:Œ~RýE$á²ÀPíT¦ÓßWÐ;›µÜªºß»RF—ýÀO	{A ’ލM$µÍ¯:—Žà¶{›Ì}£¸àß½÷R†šT MZîÇpsM8´ƒÖ½!Íü;{:øC¹Ô›Î7Ï4Òàd̶fŒ›”{qºi);–IHYy±håúG#uWxÁ‘{#¦Qp®¥OæýµÍŽyóÛ­¥½Ä/qžýñ±±Ôš²&6FICH.
+ŽI
+A:ÅÞÙœåç*6Uñ»Ï¾âhdhî­÷Òž4Ž,sBꆒö0Pôqۆá~÷⃲Ï[/±›IçÓvÔ¤ÂøšÔ‹Nภf#î‰Yçì¦Fß\ŽX®ÉâV0•1)Äæ2Y]½Í¾gìÎ`ZìÞh¾»KçÆÖLÆDÂÞõÝÜr1в&º>ðÈÙ#®Pt3<ºØ{›gÜnm„Ù­®m÷:7:GjîÛ­ì{e|ŽÑã1Ìyi45%¸YÁw’¼[_îa’V
+ǵڳ–¾nVȦáÓ6VU(Øh¤•Õ›3UÁªIYcN̨©îÙ楏,öã2"6Üfnœæ[BI
+sš|#w¦êŽqsu·Ê¹yËû½óšuž³2Ý¡ÓÈHÖ0ßGi'ƒC\â
+]™ÕËì…ÃWš˜¢ä¶/ËÞfAX’ø†œ½åb!ä[j“Óɺ‡½­ÖÏÔb࢚¿ź!V)ŠÑ ð¬~SùÜXѸ­o¬l­¦`’+gÅl×½§‹CCíåsC‡ßLÓJEW¬^cù…½8k‹[«©ãv‰'l“9­pàK‹&Œ:‡î¢p­EEñµÂ±áì\ň®U®ì”
+È°RN¥ æ%üÌZ×!“lÙ²2ðif‰{b‚'"¢aÜQOGäç8o·­ÅÖÖݐ6ÛwØêÖ[#XáÉa$²XÞ@‘ é:mZÝ'™|µµÚðÛç¶ô®ŸmÝÓIqsæ—´j jcÙRÃMB„:¦„ú›Ç$áî÷ǘG#ñ=’ÝØ8Ÿ·|ñìdYŒ”Íó;sCÛ‰CÛ‘«7Aü¢‚bB.u[±j£ÅRÔÄQ¹QbüË}É»0ùÌž/eZ6ç; 
+s¾Ä,òHàK[ýqG=Á€ð!䆟£7¾näñV7û¦àÁ‰´a%­ûR¹íf–4€]ýSPÖ—ÐZ#0¾1öjñŽÎî°8ˆ½1ÎA‚<Ó7Ò·r²Å*현ëx»†íº æbI¼n“´w›¹ pP(§¾Uë9®`së–2Úå·eÅžC,¡Žcc€2´'»/ŠdcËC‹㶭5¡ióÌ^ÏåûŽã·a¹²ËG ç>RêT
+a²K+Ð⇊î<¨#ÍÜ]‚®|ÄppÞ.›F\ñ÷½Éh\²eIWlⳓžU$ñI7i¹ÛÆH®ɾMð0}5œæ>'Ëçó 5ÒX›H¦Š:†¹îœ0E<t’é@:F£C¦‹Âq;'#’Þ-ÙÅÁ—BæH¤}	kDZ»ÇŽŠÑ¬%£†£AQUè&agì¾á2wô·%Zy7-d–ÌT¸•ƒššRB1gÍ|Ý)C0½±Í´ƒ‡
+&° Ü«(’j aåùÛ¹¿˜ŽaZüG…½Æâ°²¹ÝÓ_z\âÒY®ÞêbºžZ	œ´e°<˜Ù·ܹK[܆R0;Ç6GÕ¤€@v™­ã‚
+	 Šñ_HáÛ…|×Ã
+ÛÄÏKÍÁ!L¿¹­I‰	‡ˆ‘µªÅ	{®2Q½ÆþbR.z:ßpYN‹ÕÚ® £Ú”é÷v·69¶7í¶Ææy‚å—®ccŒŽWDö˜›¤7F×´ñ¯ŠCº»ƒ—{+?´'Ý›½Ö­sŸÜ÷
+F¤k„Ž{šðìòÒ8Sˆ#§½žXñ-ußñY¼³Æõ³+òÊÅ(GNåÑQYDSPU ¢…ðòÖ÷ÏŽbÇßm§ÂÙ®n^Ç÷ŒZÍB€‘N=kQåÊÃnüå¦q²:( k›¡å†¥Ô5#§‚íÛ‚;Ù‰ÃLÂøÏ/K]yŸ#G¼2sëmÍÌH›Iø+º¬@’ع-ÆiyGut="MêJà¯fqìKçñîÏæ}B3»cî˜|›XY#at“6œLÐÌã«¥®Ód§PñŽäý»ÉÝ¥)Äç¾ó’ʵԑÌ2Fköi‘¬j‘àƒZp^9xgÅøŽËÆùëJ9{‰2c¨öh´Yó©Vl?¥ÅjÉÂHH¥”ˆšŠdäNG§:È,Bøö»‰í˜æÞàÜÙKÍ›½ØÆî;&¹Áá­a~‡÷r²F·óaìs›C
+sIñFš»Ìþ]a°V»›j¹Ç	t@Ð\^­šãsê¿CÚPòKM8øÔw
+)c»£\<Kq:êÝÃé*Á“eܱR}§ ÒFMëÖi)#ñPHêųv ½†&áJ·'5¹·œÄî9}Ëè™>ìŸN·¸µLcZâ¯Gçù?7t$’Î>^òç‘ÃM¼·”Ž‹nëKKLš
+ç8í¼Fµž;ßP åvœÇ²»<ÜŒñ¥ × akªJa»v~~Np‘w#Ñp‘Å$êjî¾"š¥.&Ò+²Æ8Pâ"…TɔڅösùŠÙ¶ÎÍe'°ËØ2"dŠ8âÕ¡«éï%'A• q--’×É]Ï;qvÞco ‘ï’’ðm_,ÍÝPÇ H¥} wpÝ•,{/#(Õ…Ãbâvœ¼¢’‹é®	˜Íô–T‰™4»
+ÐøøkÐ9Ì<îûÀÝßn7D븯;¶h``ÑݱÜ@<N§+Mæ¾ËÄíµ½¦²6ÚKmnÖâó«[ÛÀžªÁd„'ü7ðÓˆ ²¿’ÒÎgn²&h|kòQªèª«R½B!¼|Ä”ë6Ç)Ÿ.g#™¨pDNa(®‡˜ææýß[ž}·Ê6C:Ô‘%äcƒ¨t÷•”>6D⍢7Ë èZÝ¿ˍ¡´ð1fùŽé$½¸%³Å*+¢‘–½Ïí¸½‘°5&ŽwÛŒñϳëŒÆSvŸÊ^x(ÄŹ—gq:—~ñËDTI¸È8‹™º.Ø™¸–îI„“g‰Êcn—¿ŠÊs¼±ºŠÿ y¾Ï/·ä1΍±°jtµñÃãy é2Dö=û
+Ê½ùo%žØmÎ72Æ4=Ïq#¢¥¯–V½ ‘PÉñÓÀ/0o[js_V<º›•Ëg̼„–nCï¢+µ>‰ºj ”¢»íÌEÐS@íP¦Ó–¾ªÛÙìvæÃÛæñŽÕes^Úð –¸u9¦­pêp#©|û™ÃÞà²Sb¯Û¦ê	NŠŽ±Ú(ZzÁl`¦ÚÌ–¬]R‚œõ%©Õ()·ÇQ¥:ö¥:B’uJU:éP'T€¦Ú’Ôꔩ-N©J¦Þ¡¨-N½©N%*ÁìJU6ëJƒ­:¤ÒҝRÇŸü5©×êHŽŠ’Ôê”×SDꐊ\zÓª@S®•éª¯Ö”5¨¨W‡EIjª¤MN”U :)qN© ýt¸&iN¥ ˜ÃRZŠ¸ž§J¤€na©#µWóù*tö&¥Ät§Up?=Á )iOR¸•¨ëWMN”ü
+à`šUX!ÞD'Up?8xªt¦® ÷tR⮢½©×µ\E;AÔ¬ÛJˆ©
+ÚÒ¢u
+Àaé¥Dè
+¶ðtR¢TZÒIkBJP…š¼/¥«%ÇNû•‡Æq¯ÍÝóûí˜ý«wúyÝÛC÷Oû:Ûô,Y•Øì%jËbS±Ø>J¿"E›wˆLî^AÓ2äðñ^ó•ûmʁ^Ví¯Øÿ Õ!_˜;üÿ çÌßí{ÏÖ$]:}+}-Z•RÇ¦¤µ:«ÃŸü%©Ô¥¦ˆª@Sª—…4 §_»Jƒ©:¤íÓ`÷iRZV}p'ÁܧײÒÓÈ®ÏYÎP5Èü¦;aœúBË'E(™.Ñí^*MN‹} ºBxo;9³mËl3ml‹_¹®Ú{–ô÷lè38uÐðŒwO}?–{ãzd4˜{r†´ÖãÄF
+	¥^EHoG
+ýOÚöE³í˜èf­áã3lÕ„dB	ƢѓtÀ­Ù7* 'A"9@‚0ˆˆ˜F¿2²yœŽw%%õã-ËÞ\çÈKËœOð$ý<P_qãñVx‹&ZÛ€ÈÚÐX@ ph Ãô®•ÉR™mÙ26oÌòÎÑ(n¬¼œ˜,Î(«€êº†kG*ûýGUÓ7€+rÛØ·ºÍ×Ré&~†ž ÆQϧPÔâÆðþˇjÕ³™Xb¼À†²&kpë/}ZÀGI£Cÿ ¬Ò°Ç%ܳnÓ21Ò±=ªÄIwÒë‘è"©€‡8™ER€a0ê¥{ÙÆØDðû¸åš€ÈÅ\HãØkà^G¹2ykÚEc¦8I£žç^. 
+óÿ (Ý	­rN¾É¬u’¹&ޝÛwMQh“.™"£[î.ýu”Mªc¨¡¸Q( W¿m«ëo
+¾)ú#·´p:µW¼Ô4P¸öñ5â¼Ö÷\×ËutÇÈ纮0=”#WWàà†œ´KÙ踟ï`3¦poܧïùDp»dÞ †ºŽœºÖjò×--Ö±i`ÁÒ5½ 9ÞÑoÜÚ>wÿ …ßåqY¶Ü1•Ní’IdM!8©Í®ø€¬fG\ᨓRh™€6W}˜Ü–÷‹8ÍGK$‡€8¯ŠNšÐ[pxtU®ÿ %h¹	2|ù
+‹†Ï $S1;6ÇRHñŽVLM¡Š²R̘$s¦ è	Bò렍aß·¬	-’9¢ãSâê ÿ êýwºmÙ8}`E£Ì„I¢Ý\q²úìݐ©K²ìǹ0ªŸ`C9ng
+©ÄNQÓPä÷_û”[²FØÊÉcpã¸8pã@hïĹMûæ{
+ÃÇ´ý¡Ðxý	ò}|Çr
+LfØ”O(Bo71Duôg €ª¡˜,n›C
+å/½ÔµÖÁenðwBXxÛ»í0žŸiÄ~?É’³·ÊÀbž‚Aö\:ùâüKß³{õÄ|ƒu¼j ¦»u‹¸¡
+ Aï”ä1G¼bˆr
+{¥…í¾JÕ·VƱ»ñ°¼²öÎkƒo8£‡AíD/œê®ÑjëU()×Q¥:¥*›¢•;SªPS¸)P'T ¦Ýz{õ%©Õ()ÕRZR‚u{ª÷¯ÙâÑ,ÙÀ/ü>D™²—‹är<\{E쀆É8ÑË>AÁÌ©@¡ö–Ðj;©P
+u÷ÚüüȶM³Î]¿¼gÔ1Õ¹.¥xÚܹÓ4pÿ åHÃÛãpê_[òL³9Ë<ÆÚ‹I¾×0螶'?üÆ?èñWçfÄh´y2|ÕvRÜ.Ñë7h¨ÝÛGm”2.9n±Hª¬A)ÈpÀ !¨WÙûxÅ-³fˆ‡FáPAx‚àAAæ\À’9Ìr״Ђ(A ƒÐGEe‚~A­ˆµaj½Ã⥠`¯bõ¥.Â:äÈ
+XL££]ê›Ôeî\¨læá’ÈDÉ8a	ઐû¢‘ɸmÈ?Ÿ8‹¶oæƒ!ŸÆ%…£æ«ÛöK!µÀõ‡<´‚:A¨à¾ÃÉ[»mòÓ|.îzC¥œÝ–‘ÔZÀA Š+®1rË°Ë35š†”›O|†›q\‘f$¡@@wN™Ä¦ð€ˆ%wwHÕüÍãôxÿ V™upœ‹¾#ÿ œÿ Óļ&³­”ݲ(mý7ŠmDSwÀ@C”š¾ÅÆâÙ45“Bù²úùÑËFp¢ý5ûDÈÒköÌZõ;ɼ㏢îWoÑ2¾.¸S±~ÖíŒ$]B®ªd3„ùNB€è:WÁ¢ž|]Îõn ‘XÛ“iñkœECÑÀWIì%}qÌh¢¿‡kœˆ«ä½ƒYpãG÷]åGÓýaô.Sí0K€ÙKóEñ…‘rÝ©6ÖÒ‘weDج¥œA­þdèÊ?]V6eƈJ.ò94Õ(¬C(¤"@ÉË®hZbo?‡ö¶ZÉrÑ3¦-ÖÖx­ã4g@$p"®w¡‘æ]¾Ã¸È[|a=ÜS²Ûqn’ïðþ1- ñè
+à±ÝþÈ^²E©—1ÞdÎ-î«AÃLJ’†¹]±pœŒcØyrMÇmtÍät‚©œ€¡@Ú€€€
+z~æÆÿ 0[³>/Ä}ÃZ¥ñ‡.kÚæ“rêæ‚
+ÑpwܝÛÙx²øë숼„’ÝLyiÔÒÒŠ‚	¨\<3Î(ÏÞÖü;‘ð¼Ë‰ÛRåb¡&ýÔ½¼à×$”#¤Ög2Ý£¥Ìœdk0*À˜ÄС¨F²X=Áµ?—ì¾ÞÜ1ˆî¢†rÖ‡¶A¡ò5â…„ã9ü+ZÔõ®•ÎW¸9ÃŽÌáž_o$‘T–¹‡[X暇 OŠÆ”¥RèÏlC5$xî’ne	cðï€Íé„ < &0HÖoùq·3òþŽ¾Oþ°X¾uÊ"Þ»¯îÑAYí쮈J/„þ.ېwˆ»YUAå&ñ±¼±;£ÉïŠPç ­+ù‘´m¦ÿ Ûa.kOÿ Ôµm’¸7C6]ÐïÐ9|>ÉiGÐüqauÛÂb^Q.¯ã]62‚ûÒ qRrvà©(U P”t±’î˜Nch:€içémï16å…ÿ ,ˆ8³GÝi“§‡µ ×… ]ÞPƒk³3Wvœ/Cä Žš²Þ¬ü&ŸI_Ÿ»NK…Êï_ª¢¦UCœçPÂsÆ0˜Æ1¨˜Æ0ê"<µö>6Ä]÷ý•óMõ×p4·¥väܦF‘†´Þ_פ¥è£jI]í¨Ï@ID|_éò±l½
+LD»4‹ÙÂÐB¸Û´qVye,­mã¿}uJØØÙ¨ÕÚžjEMOÒ©Û‹!sdÛ©æ}›i¦7=ō§F’Z(:(8ìo¶ù¹Åœ!·ÝÞ`1m» DD»Ã§6£_.±w»ƒ<ÞºÅúI×Óé~Œ>%ÝT“ýH—KûíÔc8Ÿrô£ª‡Äwzb#Ìy›HÃå-zó-bÛ~YE(ûG% ÿ òæZ#®Ý6ú’>¡c/úñ.«šÆ¹+4{I³¾5Æ2Î`®lÍ’VáIëèä-Ø6’O×™–xò8Åv›d Qp²„D=òY
+»¹ð›K“69ÃgÇEŽ·¤E­y–G5¡Œk]âÔº†§ì€^x4®žk”Ü\Í»Æažb½’öjÈšÀI{‰oƒíÒVReLìÔáÊèqÄ~XËÙ¿0¦Vn.¸¸‡ÎÌf«,͹Ð+ÂÆ‘bÌ«Q!ÊÙÜ뇤DH" A Ÿá÷G:wÍ°Èìü~7¶Ü\!t€P€ã]:«®†£S-ÚÂkÖ
+Ü2XWíIÍ–ä¼¾ÈfÀëXMA R´¦ž:]3œ:¨³G‡Ù~dø,â¹Ï	öíßmY¨Z¹H—[Åg‹¾^ç.'2‚á©žÎÏœ|TfåÐ o”Þ÷Â>[½­÷Õ·1°mß“ÚÏ’ïmŒf Dzè4Ž?V£ÐxSŠß¶´ÛN}•–;F+ˆ¬»¹ÃĤ’_ÜtŠ½ü4Ó¬q¯†žÃÇÊ<½3ha0’Æ€ÓQ×ûý@ÿ zŸó9!~×ÄWÓ$ý^Ȇgò4ôf®¼\,¦/«½G*œà7,àŽñ„DDej"""""5ôvß²ûŬZº;¦ª‰æn»›‰4ô÷Žþ’½ÈâíG{$¸lTLvW.4d™À¤&˜CßZ§¢e!Dl®š›wQ—¶”
+´þb³‘EÀ5·ë/…Çð’Oô/{Ürºã’¸©$âI„~Êâr^1ÞšÞöGpôÚÜt¢,nìI¢·Ð©»<­¨þè–nçt€BÝHAðŠ© ˆˆ÷ñ›I.ÿ ˜,ÕÅà­Är_ÒelL#ÿ Ááÿ „•ÞÝlm¿'1pÛBöZê êÒ8ÿ „/ð]¨Ý{ç=Xw•ÞÑT{ûÅŸ7ø+ëL¶9ŽÛ7Ò;í}Îcÿ å¹|뎽ss¶‘·£ïQýö¯_½¥ãd=¡Çͤƒ’m£æwÈeSø­Þe‘o 'H c(ODTú” DÁÉ_'rV[›~Xn›:ýé‚åÌ¡§ŽÛ0[Ç«8¯¡ù£oÜ,4û»ŒßøMÉüUYíOéçFqi2­¯4…ªý͝e4•^hÇ“
+#$ùc²´n&³¶)¦¨v¤?bŠZ“MÑ+”—<ɵÅÝümc-«î%tÅ¡úšÏ¼eaÒ‰«Ç¥mƃcÜd-þ-žî9Ù	îÛqn’ïðãQ Ç 7‚Å,5uû(pFAµò­ƒ—s;{žÓ]Úñǐ‰¸2pœ„kÈ—Í$£`5QËGlª™È Ž÷ €€W¤n,w=÷FlWŠ6€¥ñ‡.ii7ÐA¡ZN÷”˜¬Yl}î@]ÂM55妭- $OZÂÞ2óÖ6Î\UÜYH8•´ç-ËE³™'1p‹»šˆˆJ%ÙÖe,Ù«½äZ³A >àÄL4×JõžJás›[jEƒÎ´2ê9¥!¡Íx
+{Ë…IIq¥zJó®idñ[ƒpÉ–Ä»U»âŒ–’æ·I¨p€ tu.´M]JQäå ½Öœ*¼’©ÁMºt÷©Sµ:¥;‚–”ꐪm©-N©ANà¨-N©AMºô÷êhBuJU:½Ê^ê”î
+T¡:¤*›jKSªPSž µ:¥6øûµ©-N©N~J\SªR©·_v¦:¤…"Ôê”ë©-N© áÑRZRǦ¢”èN©MºtÑáN©@ô¨BuHz’Ôê5%©×± 9ô©-N© ãÓSNÄêútÒãÖŠ¤.4€p¤ZO… yêKS¨W‡†§J|UÀÜÃRB*Î*TìM\Ì4¸õ§T€z8pW…"©Wm©¢ujà~zZS⮩¡EUÀÂjhª¸<4´¦®Ì4¸„T…`8ÑÁ:Žµp?pQDS±\
+J‰ÔŽ•®´¨Š‚¬šTN[x)QM
+Ξ’ޏTy×T|f~noŸßlÇí[¿ÓȾîÚºx¿ÙÖß¡bÌþÃg+V[†Ï P…øòâDÛ¼EgÀïfœ¦+æt+öã•þVí¯øú¤+òû˜ÿ >fëï{ÏÖ$]2
+sÖýÅj5ìHæ(ð§áH륧±:¤ó›¤µ:¤óù*Sª@>Þïr¤µ:ýk|·â\sQp1ÉŠ¯e^ É¹wL`®p&ù€ #¸™DLm< 5׺¸ŽÒÝ÷SEK€
+®{x]q3`í8Óþÿ ©~½¸c¶m<€l{R%©A`fÔæj‰H‹éiyUP;éG‚)˜ÅŽÕ/h±À@‰
+]wJZü§æmþSzoÛì•Ë¿4á¨ñk#`!¬oê´4t¸’zI_kòÎêô!‚6Öáò¸5ƒq$ç“@]C@ Sä̾ò,î—q:„CxöÏdSh†úG~f(è"(]¦gæD†ß16ð€—Nÿ ÚÚ1]†²(4’9¬.<C5$ðÒÓ§Q5]ÝÉ»¦¶–’ܲݍ5
+ ê“H&h:Ü5PUÚXMx8ùƒ{eË¥IøÔý
+àU¼ó‡+=”3†ê>r²„A²Z‹xÖ¨¨‚@& •c2” yké¼&ÏÅlÎ2Û‰mÚÐØèàÀI5{ˆ'ñEI¯Bð»ýÁw5ç}od<e}$•Õ uQ¬S€­àw\»WN•nÎ’ï[1UÁD¹TäP¥n±;Q8oæ(j j5™ÄYËBY¦îat€:ià5”à +4Ž¸þ!´tÒ½]$ƒÜËuZ3*Îá“~­× w‘¬áÁ$›%èF€"åò&3%*‡:€ pÝ€W°cÙui9†ÐÃ÷C×׍IuH”à°óG ¶£‹ªI§ <<W¾³%¢Ì¶¼TK‡ÎTCW„J@±fE@÷ÉtÙ¾ »TšQ Žƒß¬¦êúàÜË+Zàzi¨Ó^$ô­cÌз€c©ÿ Œó¬~ýJl¹ƒ³‚Ðà˜&£¹é t$c‰Ê‹† ‚JèŽï¿HÅÔu VÄìeÑ„´ÏFô?¦§ñ¨˜þßù€]Õbç™B̤Ú)¢æb?3ŽpåòjǸpO$ªnÓW|Ì¢E€Äº™‡ZÓ³8&¾xd–WK(ap§Pa§¶£G’²¼i0F£Œ¸ÄMD¶i‹a íEmÿ EX0Gɸ@Š"¡DCÑÌd»@LDàrÄÂPäÞõv]·¦’
+5ƒ©­¯‡‡ôð\
+»¤”Ó ôŠv”7Ðs›¢©\E¨4b²çQ7Éh¾úIH-Ø•²­‡· LNnŽ &(ïÖ¯u´®-åu^jÑÑÛP;xh~£Áf#È°W…:ÇôýK­ò]„¤ËTdÐUœß£*œ{ÀM0‹¹£ÇIÌs¢(`UÓd5ÞOBˆ“A”@@r[hË‹´úG8´“©Ž=dvW¯ÃÇ¡c³7!¶ÿ ·h%¦Ÿj#ð‘uÙTÛÔ5èÞ t$:¶…*U0SMºûµ%©Õ )·J‚Ôꔩ¥:ªR«·ÇJ©Õ()ÕÑJ€§U“|'ñYup–äHf‹\Ä“Oˆ²œG Ø·¸¢¥XÑU
+¢
+§¡\”2XÅä0]]|—œ<³°ænÖv&r"ÉBîòÚjTÇ  õ˜ä+Ú>‡ \ƯBå¾ø»ØÙᑈ,¤&Š´ÖÊÖ£¨=‡Æað·ƒ\åéÍñ‚}Ÿ|vÎHæŒÄu·„rMÒ'•¾lëŒ!˜ªöy]Õ_ÊLcÙùËfU„Ë•Œb=‹xâ-ÒÚ®PYS(ªß+í~`s’¬nÙÜøI²¸H˜dŒ¿ÅgCZˈ㕎`Y¬l!-h
+o¾ç¶.yœóœÁe#Çå%ñ¤cÃx»¤—B÷ÆàãÐç±åŽ>7ŒI.ú¬n¸áMã<«Äo–J=ºdåáìÆ*¡õû1:ÈKBvﺯpEt@ÄA""Øç
+ÕÓQ1ŽSp󧛼ǵ~ÜØ›zëà²K‡¹ík¸Løà†Þ Ð¸—<,s]B±ønXòëeNÜÖìÌ[ß>È@hipâ+_,“PŠ€4´žp^RûB¸ã–ã{*C#n°‘€Ä6½ic@?:a ùËó ·dúmŽ«rJÊ¢I¤N©¶LSçXêz7(yW/±N‚W6|ýÑk®%h:@mtE4:RKˆî$ hn—Ì]ÿ .ñÈ	£k¢Ä[‚!cˆÔkö¤}8ju  Ñ@I.'Øþ-Ì?5즻í|ù>½§‰¦nKª&î¹›8]¢öñdnË}¬4ÂnjøŒuÄ«EDë"«RupQC´
+ðŽqKŸÆsþÞãkÄ'ÎÃi⌀CôÃ!{%µÕx !Ü|BE붏}Ê	¡ÏHbÄÉq+^ðH,¬Œ
+u at 4£ôž ·ûCMWGbÿ fß6
+ÊÊû¾8Î÷¦‚]ŒÉ´˜¶#]\°È,ÅÊK£xHÄ·Žv‰®»AYGd"u
+d÷‹¿æzÝà߁Ámœ¾î™† òÙØžEØÎå¯/oÖ¿KXhçíVß“›^ß*ܶ[;e.݉ÂBÐX×HÐjçw¥¡§€qmK…CCIa?´ßXÎ*3ÅšÏ?yúk…SxÚɸ‹ˆç—<“Èçs—s6Ë$Ýã&<+$b•`M¯l%LVɳrW•÷;3oÌÌës™";*#¡Á’	kG½ÒiWiÁ¡ÇÍ
+ùæËÆìSœ1V@ˆŸBÒ÷’¤ €@ñZ7Uu£mãÂoµg
+XæXÊþâ{£Ú4}8´\rK=lÙ¥ÀŒ#i×ñ,¯.êYšO=³ä¥#WE=MÙ‘Auä'nïÞAn»›¬MŒÙ]“tî†8è–k,kŒ3D	f·0Ç &‚¤hôoÍÜù¸ñû¦Òí#Æ è-Dò´5Áì q :øîໃnfÍüFñ#‰2ª6ÜdÉmË	»;rZ6QÛ¶.cÌämG2÷<å(FNŒ-š¢Ð‰´rb®e³)Ë—ÜÜÉæ2웵v>!tÏg{rçH×4Nô2&BÍCÆ{žKÛVDvdlítwéËYÞÚîîÖ88E{²é+¨|V†€×QÄð¨Á¼1±®BöÙyµ¬Ÿ…±²¹5høÓý´-›J؇V.%WjH¸÷o’hW/TÞìý-ÁÀ`Ý0úÎghe1|“¾Û}ÎW<,ð$šY¥|šÜ©Ik+¡¢ …ç˜ÍÇaÍ\뙆 Ý´†’ÈãŠ6³H.#KM58ôjqâQ{Q/Ë'!ñ¹%qãûÆÖ¾­ÓØV3"OY×MÏ
+wº#¶…”„vù‰œ¶1€Lß ˆo W_ùyÄåpÛ*,ŵť躘˜æñ<áBXð×Põqê\ÜäÈØd÷D—XÙḵ6ñ øÞÙP
+F¦’*:ÅVsû<ræ+°8iâ~ýɘúɘŸg$X›¾ó·-¹)³)aJ3L±fd™:’1ݨTƒ±!õPÀ_ò‡JÕ?˜Ý·¸rûão^âl/n¬ác{É!‚YûÃ]㹍sYâññˆáÇ¡l•Íá±ÛW3k‘»¶·¹•ÇC$•Œsÿ 2áâµÎÜxp‡Ë2`8`¼.Kc%‚b\ m¦åAG¡hOÆÒ1·†	$²î¡Wg ³y"C-ÙöJ”§ì;3çyÓÊëíû·áÉ`€;‡^XÂt÷Ѻ…ñ‡ x-Œ¸Òº›Q«PÄòÃ~ZíĶYbFð49ÏvöÔ5äq%¤8µôãM'ŽšÅ‘ömp×s^oïŒ9Æ,‡Ä—<›™´m󿵧\Z̝©énb!&ÞQí^0fe›tÝ ÝfH”‰¬eÎCÚfÞçöóÛ˜Á‰ÜjúãpBÀÍ`K‘ÀP:FàOâÒàóRÐÀ@6c”g5|r8|å¤8y\]§Äy`<KXá+Aˆ€-Q®›öñÂÔ]§xqá²&͹dš÷vX€†€;‰ ·¡ÝÀ°‚¹Œcuî§ò'[ã	GÈ(-TX©TÆX©m¼˜Åsæï·Îýžî'ßwÍ”’K¥ì•Òwyµ”Ã[Z]PÐ]®s;!³Æ.Óií­ÞÛ]íÓÍOîØXÖw­h29Õ×#ÁÒ]¦„ÕÀrÿ kþ]ÅY"ÁáU†;ɘúýsušy—yÛ—KÈ@se¢ÜeÛAÉ>^4,ÕR¶)7Ì™€5ŽšO 6îàÂçóRæ¬o,ã™Ñh3Ã$Aô’btÐê	¥hí[O83X|¦2îÚåñ‰5ˆ¥d…µd`jqÓRM:bàþË;öÈǹùiûþòµlhÆ7;›¼n‹f _8”¶TA˜IM<dÏÒ–M¹ÌD÷÷ÌR@ kÕ?˜ì6_7Ëh¬ð¶·7—ƒ#‹ ‰ò¼4G0.-®vH©¥"½+@ä¦O‹ß\äî ¶¶6R·\¯lmÔ_SÈ4$
+ÔÐö-£
+ñ=Ž°Çµ6åYY–¶ô¿²U´êò¶Ü#pŵ‚¹çyuǸ‰QÒRðÈ?ŽluŽÔËY™C¢UNR¦}'-°³{§’[~Ö'Çž¶µ¶•°Èn/‰„:'€Xò×84:ƒXhqh%ÃhÇnì^ßæ¥ÖbâF¿=Äñ™XCÚ#ªÙmu49­$¶§I% ÈÌýìøÃœAæ;«;X¼hbHû7"Ë9»¦XËÉÛó*Á9~B;•<l“µƒgì{Q:„AɨЂ	Cî‰ÇMÚ<ÛÜ[O	oµó;o#-ý”BhlŒÖâ´9®‰Å®¥su‡!¢´[.ãåÖpå&Ïc3vQÙÝ<ÈýEÒ]ÅÚ\$h#¤€í%£'¥d:¹xáë„Ž"°Ö.â/OM¸³2JSÒ×5õmÂÈ_·Ä¾6Yšc#È´F^0ȃfmÑ2Å»uܦOsÙs;uïÜFåÜk«kNúß»Ž8d{`—=óÃIkë©ïït;IÐÆ…±`nv&ÞÚ9'÷=ÔÚÞùÓ4®†Ÿši 9´ÒÖ÷z…E59Õ+ýŒy7c[¯-?È×ý“ãä,ÈFÑïo{ª
+ÔhùÊ3Š*«vng_°EÊé$;Æ!Æ)yD4¯Tþa°9¼æÚÅǃ²»¼’;¹„É)kL`á\Z	à	 ªóþLåñXœåûò·VöÌ}»L²20âR^EHB«Ëø)/vÝ+ ªk ½Á0²+¤rªŠÉ+ à骒„"‰¨A)€DP¯¤vÃËXšðC„m" øˆç\q#šAi{©N¾'ŠõÇ‹L£%ý˜X'Ää;RþŠºl‡¶DuÛ öïŒA«KØ®—¶›H+4ÉÆv(e(T&ºo¿3à¶þzÓù€Íf.¬nãÄJÙ´Nødl/« ¦‰KCZQÆ´4è+ÜòÙŒMÇ'±xÛ{«gäctZâl¬26‚Zê`qsiQZJŽÕÍxU̸‰Ž—ࣈ‹Ý†<ŸnFÑ0í¬Sw¬ØÉ„õ¦ö2bLíâ~Ø“Ñ¡ã–Y¹ä#À‰¤eëŠX^dí
+ײwû9Ÿ´m_wa/<lÅ®-Ñ(sW÷r·Ç àÉ*]J3VSdn=½ºv{¶ã¸mµÜ~,Oq
+hv¸Ë\ê7\nñK	ì «©É0×|8ðãwZ7^fâBÂÉ«¥wBFc¼gzÝÝwKÙv¬m³ÈÇ#90ýÓd¤\"u)Åî‹—b€Šw3üàß;Ço\ඞêÁ¦ÖG]]L]Ha&PÇØÖ¸´85Ä™*#]Þ®#–ÛSlæ`Ën,¬Ž[Äd”¸ˆ·8€â	m¡{ôÔ—öÏȹâ‡¸bº­_4Ä­_3rÅ5›9o}Üê·]#—”Š¢²@bˆr€†´¿–˜ãŸl_ÛÊ¢}ù‚1‚ÐGŸ<Þø³Ö“FH{mt‚%yxC]÷G>Óü=bÛÙ;%ÀàÞ$l$Ϋ7s
+Æ°MIM[7ŸN!¼Ûئ7ms(Ñ7`ųääã–@‚cd8ºÕ€ÞüÝ78«)r{6åßÔÔ|@If²Æ¸Å4`–ksrh*@fÀ2ûWšø È]Ga¹àÖ ñ¨ô‡‰#}5iax]Çpÿ Ü"p…*¦fâˆ\Y“’·c¥ËoÙ5·å#¤Ý:dၜ
+°æVã‘»¤ˆÍÑ…»dš\‰V2ƒÙ”ÅÊî>aï¾bÙ·llÌ%ýƒ¥{;Û‡:F¹ êw‘²ÔxÎ/%í«CF¢C	³6–˹9íÏ•´»µÚ!
+cƒ‰WAsÝ#¨|V†€×QÄðªò+äÛ[2çÛ!Ú6\=…mMH »iÂFEIJˆ„‹bÖ*8ª³‡nÞ<²O[²/0‹¥”ÐÆ.ƒ_JlÛwkˆ¼¸’òþ&ög¹Î/‘Î.uÉv–“¥•ã¤
+€W†ïÄy¬¼ù+hYmg#†ˆšÐÖ4¶¡ 
+D
+N§õ‰¡_I¡J
++Òx-¼S•M´‹Sª@S«¢ µ0R‚SBªPSn=ÚR¢uJ
+sÒÓ؝R‚›jSªPS«¢¤µ:¥:êhSªPSn4¼)Õ()S§±:¤*›jKSªP?pT–ª!TÛ¯MM(Š¥:B—UJ
+uôTÐU m"Ôëõ¤õÔ§T€}ºwxªKSªP??’¦‡©:¤9†
+uJ¥@zª@?0Ô–§^Ô€z‚ÔëؐÌ:l©-N© üþJTìM ˜{¿ÃKRùéP„+Ãž‘ju) ãRZGR¸<5:Sª@8óëRZUÀüü”¨GB¹†•{S¯j¸ŠŽ	 ÁJŠªUÀÚxjHEB¸ž§J|UÀÀ=á¥DUX!¶¦5p8tR¡M\n´ªBu*àq£‚8+‚Š"ŠÀ4¨Hé^€p¨–ôY‡Nú‡-~lï¯ß|Ïí[¿Ö$_víÝ<_ìëoбfŸa³ÍÕ–ÅE;
+žhЊ/Ưæ â?ˆ÷´Í¹X<WÜõ~Þòœʽ³ÿ ã¿S…~]ó Ó~fÿ kÞ~±"é`8ôÖü@Z•UÀáÑRZ˜) ãàš'^Ô€§=.)øù†—Wµ ŸÉKJk&xi€YõØI”WEš8I‹1QóV+vŠË¸;_JP‚ás¦™[”‰•C‰œ…Ô·uÌPã$Šf¹Ñ–hÇ<v
+ZA ^I-iâ¶m¿jù®GMtŽ=g‰é< §jý¯y¶²lH£¿UšIÛñ³·%Æ»GF| ¾ÌíÊ›—*¥¬åª¯ƒ´D{R197t¯ÎÓ†“;¸¥e°yu̱CstÏ8€<P×øº~Ó\¯£,²ƒ
+ŒŠ§ýُ’M$:®ct†ðé ¼RC\ÒÞ¢¼÷i–Ÿgyë­)£‰¸Çÿ Î?Žr¯l“ó¸~‹6mÔ;‘#}"*˜ÆH›…'½ÐD¡ô%æЇ—¸ËGç^Øï&k»¸˜öŠQ¥Î 6§óƒHƤñà
+óh¤¾ÜW’Ml,…ÕsÈ$ñ©úh8Ø,Œª­Û½EƒGNª€“ÙX¶H¢¹ˆ™ËgEQ3‚@P(˜í9«"ë[VÈè1î‘Ð<V±î'…Hצ„Vµ¡\™Ð4ë p…GÑ™Šß…È,H$e”z«gNtÌÆ& £§`Š¨•©ß(”Àn@ å­Î×j_]mòÇ8i-áXõ<S¨
+Ž4ë¨âWQ·Í†í®+8¥O…u½ñœ‘¸“¸–‡†·®ûj)½Á	ñ¼ƒ¨—ñó–
+.ÏyűMB& P0Žèˆ€‡5¾ÙŸËAŽl²\\ÄâXó¤1”ñ|jšÔ•Ï5äw=ãåCOPéð®¥È—ύcÂYŽ7yxÎÏ“¶EÌì‹È°jħ2SÓ8PìÀŸÙ”S9Í o
+lväùÚnîÛozC8øC‡_G±RÜãš(#bñ¥lƒC˧ö^XfÉð²H\i™œS xŠÂÕxÓGŠTM¹L—kÚ†»ÚˆrVÓ=¦m“·¹¸d¶|5öÒ‡‡àãô.`ãö8øUlòÆN"£¤÷@âù£ƒ*õ„XÉ4uè
+TˆG>9Ê@
+ó ßi¯jòÙºšàÖ88p=-5±c,bg5„jèýÔ¾»ûÓa¥ÎÉP;£2@ñŽÖ*B¡Šæu"V]Crœ„\ŒÊp×@=«¨î¬>ðâwSJöþ4¯"–‚+¡ßˆ…ÆmÉå‘I2ª·ìÙ9;6.Ö§!¸Š.C³n¡{6ŽJEH"tôï×ýÕ£".–Hõ4ëP=‡á}*íY+ŸÝèêtp¡èãÕÒ»ÊÖ™›R5{_ Ã9go$±¤XJLöq-Ù–&#£ó¤ìL@Ý¢(”ސQéËZ®FLtÒ6ç 7n ڝM#¡Ôé¥WJÊÛÃsLw-ŒW¦€Ôq¨·BÜ®kË5«3p–½’íV(*ÝTõåÝ:'ÿ (w‡–·,LϹ°c¥¾+‡ao¢e mµóÚÏönñ‡€ÿ ßTeSmdV:©ANzšꔪmק»Z\ª@S«Ê´Õ:¥:ú*KS)TÛPZUÄÀr‰L€†ƒPYQCШ8Ž ®/iµ~aU0ÜPyuAÖ°×xˆç:›Ò²vùÅâž…°Èpcn™c‰5ïj=êÆÿ qÉÐOÜþôe* ªæp–ÓXÀ@Êœ£§~²v˜¸­øÓŠèÜ_¾nKÙhŒ­‹{³>1ÉV~F–•”<^?{xÛ­oyÔÈV{ÔÔaj/"Iç„;6Ê*›s ¤™Œô¢!òùÛ[‚oæZÇ9…ã°M‚0ë‘¦‘o3H3÷`‚@¡wI¤¯£¶¦o$.ñR]Û7*é^D&V	H3FA—k5 Ÿ³Ð	ê^Û–¢®™B(bƒQ ¯¦¬q/’M%xeÞA¬’…v,¨„z€²žýNþ¦åk5iŠd[ºV.ã éF‘з‰ˆ²‰èb†ø èÏwŽå´ë\V÷„Ô.2À;€±û=ÉäÒ°ÇúÒ§JÉz7¦œW5‡·[Æ¢b  œÁ ˆÖNÛÈJq]ï_3«Ôí¤Q~/ü¡6õq·ÖÍÞõÕS¯œè»µ¿ÊGI° ~PÐÉ]‹›a<z
+á‚àÂý]k勁AŠ@@7O®¡Ò׷Dz&QsKvé«­qÉŠ.e›¦&}ï'‡ecn0ÁÏÕ»±dÈn—q_LU”DœNbŽ¡¼:Ño‡~·ñ)K’.n–ô-íͬÝÔ×ÓNÏM kž\c báŽùÍaojåbÔ§eè¿ìw7|šWqÐvºÂR$×Ö¶Ûa»5”P^Ó]uÛ­t!Ʋ7v®Ü—Îx õ-¦JÇ"îÃs	#¨îòr÷ë¥q‡~¶p+³H±º]Ѐ,H(•}4Q®„×ö× ÊiâÕËØÛh´`,ËþH†ž:ïÇŽlp÷C¡u_zçÉÞ/¾
+(“œÄÿ d:øéÛX¶ÜÔ)žèÌæ R•Pª”J =ꛫÜâœf@½^á¬Üf®¤¸lÌæƘo.·3„ 3,½¹gC\È-qÁíµõ"Õ€¸‘b¡Â-ÓOPUä~é9„Ç~W捗46núzm³}”Úohï,[,ÏŠ7»§ƒn×8ºó$c-K€ ×ïû
+çaîm¦ý¯œ–…®:.M‘àÉ­„L@%Íÿ fæ9๔
+&§O6Áü
+ð§ÂÅÿ og|ÃÆ3¼blGéÝ6¥»¥¿ÚFf?u̺¨¡vÝSêEº;AŒsaPÎQHâ©Ó)Ò>‹¹9›¾wÎ&m­¶våõ´÷mÝãô±Üʘ¢da¬säuK†HpÛ0{iíLŒYüînÒx­Ý®6
+
+ÔáÅ®á$Ž~“ã1µÔ©ÌŽ3øoŧY&«¶Öd$Te‹bñ;7ÊZ°¤^' ñóeff%Þ½Gß GLÂ& ˆû_(ö<»'nɸ-vAï3N[Å¢G†‚ÐzÃÖ2¿Ö-$p+Ëyº£Ý9™r0‚Û6°G<¡¤Hê.sœêuCкÆRÜm,Ô…P ƒ§.µí·¸`í/,†íð¾ ð\8,ÀÛ€±û-{ÚòiX¿îgÖ•:Wûͧ«ŠçöõºÞºŸNQQÖ²V¶·+£qv鏅ÌJ§UwWV©ANòR¢uJ
+mêT	Õ()RZR‚›u¨-N©J¦Ý*KSªPS¯¢¦…:¥*›z†•uJ
+uT–§T ¦ÝjKSªR©ÕPZª©AN¾ŠT(ªB©·¨iP'T §=NžÄê”ÛÝîÔ–§T€~®Š‚ÕUJ
+Á©¥T ¦Ý)xUU()J€ô"© û{½Ê’ÕUHç©-ERüÃÔ5%ªª”çòTТ©NaÖ—´ÒéiìN½‰@üÃRZ{UÀüõ%©Õ ˜zªKSª@??’•èM!OÌ4¼)Õ •èE{ù†‘	×µ zjKS±\$ê=5%¡:«Ã¢•M yéxQ^Õp=¯B~p7w†¦‰Ôõ«‡ŸÇH„pêWóÔéOŠ¸0Ò¢*®-Nš¸:)P„Õ€iU:•èÏ	ÉoC”t0¯Íõûï™ý«wúÄ‹îí¡û§‹ýmú,Úì6y+U[†Ï%_‹Ž'
+»Ä§¥æÎ9d<Wìøw¼ûƒÊoúW¶áüwêp¯Ë®`WãÜÝ=ïyúÄ‹¤@üÃ[ÿ ¨×µ zi§àW‡>•%¨ª@8ôÔéNªàpèé¤ZRƦ‰Ô,ºÀ²ní“°s’®î¹†êFYé²Px9	7mÓ‘¼£9)D·vÑ&{ÅÉu= ¢D5Ò÷;,ïíÍ•ûÚÌcf¸ÿ ã2&6ÿ hx²½Òqš;£Q![Ö"9mìc’÷Ť´ÿ d¸ŸÂ;Òõbâ¾,¢ZS؁®Š!bÏ02“nc·`÷ã	çOdä]H¹xåc‚Š*(î	Ó å•,ðÙÙ3po9|Y¥¿ûόǚ½º"kXƱ­hZÝU¡è[ìw°Eg&66-ˆGÀôõ¹Î$’I4&€à±êÊOcI+fÁô)ËÊžJBkµŠX±æ`Ì¢éI4gÔC&]æL"";Îç¾›rn(ò¹ímŠ2ØéÝ3V³À¸¹ÏwŠ	ñkAu1ï8ëSmdiª¤“ýcBßM+Ú±[+ÚºÅUäD¢AA“täRNc³ª›ÄXÇ•”I”jMÑÞÞß2¯x“—~Âgv´÷ÝÙŠéÒ-% 7‡M $þ%‡¼°»kìãÓÇ£²µXH³"Oª¢·
+ÈѲ+˪V+Ò©DD=ñ‰p£a Š;½ü3Õ±ZÈ!¦¯u‰‰%•¥¢wzš½»v´”ÈÊ”aíkqÂÅ“¶žÄ¤Ôc6…AÊŽ»Pʏw5Ð4Þ×½ÉZ”ù˜ÍÀö[#ƒZ$Ô ÒãSð,£E§Ü¦kÞtpâ8žž¥Æ®;	2¶mEfßM̵E»øÒ¼·n¨¶äUÂnÜ<1Ýx¥ÌàSéÈ`(ià¬Ø›q\Êö°C¨#[xPtb½œ+ÿ ¦·ûnH\Y¸bÙÂÛ±³íˆ`Ý%ΝÌW	v…)ŠþN4‚`å×R‰uõsœniÃSîŸÓý ªeÍ›>Í»^>’»
+ƒf~›Þ"Ù´4pDníf—fRM3iƒ„‚8tÔG”G¾нÆI+÷‹«‡šIOÔ?Ì»L¿ ÅÞÊT­W:Ü-´½¸ª×1m§O"Z,»¸›RÊ¡'èm½<ȶ(ɦAtQT8{”+·q6RÙß’{~Ûº*hhMkÙõ®Åíëû÷ËÓV´ô
+V”!b¬­ÓsK¨ç³ÌkªíMÙ<Zr#Ššöú¦Å°4n.CQ>€ öZÖháqђﺆÝ'€qúÇêXæß]HÆ»¾&¿WÔ¶ÛžàNï4¡4ÂnNÉùݱtäȱ"ï cvÀ€:Q@ß05åÛ]KhÙ÷'21¡Ìs™ÑNƒÃ¢Ÿ÷.ԝã/‰.i
+wOhãÓÚ»/¸{öpÌž÷¢ä´ASDª·UC¹HÔGû$Êp&¥8sVW÷eþ½ø¨íô,&ᎌ†N±©§ê5°ANºÎÐ-f©M¾>í)§T ~%AjuìJ
+s
+IjuH
+TЧTÀ§]*êÛ§¹Hµ:¥÷AjuJU9†¤µ:¥*hSªÙeâ“•(úò
+t/,Ûr(WnÚäÀVáÌ‘È%ä 
+»ka4Ž…3Ìev¢·Sú¹ËW
+R•Mµªª”ê©¡N©AN¿%*'T ¦ßN”ꔩ-N©J¦ÝjSªR©·Or¤‚SŸÖ¨R•M¾:E©Õ()ÕPZª©ANº‚ÔꔪmñÔЧTÀ§WE*ÁJU:Ý©-N©J¦Ý*KSªPS¸*4§UµËF!*€¤§. <¾}Úê\Ú¶áš\»\:T.¾=‚ A5L	ˆ÷€G½­`Ý…p4i:VU¹0EH⹍½k¶ˆþÓ@2Ÿí‡”u®ý¦5–ü¬º—7¯›‡Rç%S@Ъ²«¥T §UN’R‚äTN©A]¾:šê˜ç©-N©J¦ÝjUU)TÛ§¹S¤§T §^ÐþŠI‚”ªmñ÷êhªPSª‘juJ
+uÔ§T¥SnžçôT§T §pRLÄ¥Sn¾í*ê”ê©-N©ANº‚ÔꐪmÓÜ©-UT §?“ú)qLÄ ¦ÝzjhT §U"ÕUJ
+mÖ µ:¤6éRZR‚u4!:¤*›téîÒ—…:¥)R½	Õ(˜jKQT€~z’ÕUH
+s»Z‚Ôêçä¥Å:¥6ëK‡Z*´§R·ü5%©×êH
+N”êÌ:ô÷kRZRùù)P¦·^ï%.iÕ •;^Ä€naîè©!:ö«úêKS¯b¸<¥I	Õ zjt¦®Žš8„ê4¸"½© ôS±?¸¦‰×µ\=5$#À®
+-)Ô«€ó
+I©ÕzcÂ:[Ði9J>2kóW}þüfjÝþ±"ûÃgþébÿ g[~…‹7ûÖ­Çé[GŒhãô¡~'8¢6œLñQöuˁɲÿ ¸¿p¹LßùU¶áüwêp¯Ë~`þþç?kÞ~±"èÐ0†·ò£R4¨B¸„øõ$s
+.íWóù)iM\Ò¤„ê»âؾ$¬·ökæïå±R)á»n–nÖUË9-Y®DÀP6ìТUDÁ¾dÌÐy5›üU¶V) {éèK€:A”8}!•Óô¯B³•ñXC§ Æßõ?γ/[ ú䞺̻‚,Æß<c—ÀT›®Ô­AJ€8v"Ä)	¼pÝÔt
+C_,ÝÙh4Aa‰ÒÒ$”=¬âàíDŽ£x‚IáÅf,âx’°iO§‚¬J³Ö4d”tSÕnÒRUÌ[9—‚$a ðWmY.ÉÒâFn‰Š bûÐ 
+4èÜÛÛe^Ùços)cuññ€âHèãQà@•ñpWâ"ôt¦¹§`dÝòkB A"h¸V=_ÑjíM»5“+fËä\LQÝ ëÞÐk­±»ÈÚ¶â:Š(kôƒý*î^çÙ½ßH^9J_×d°&WÓÏŒbŸ³`*zÆ0•=Ã5ïÑÅ 
+%¢‹T|Ž{ràrw(:¼¬¨“]ÝvÊi*»ÅN-Ù Òq›õ¸TÆ1“(=nPÓAä­O?³Ä¸d£¢$	«z:øÁeq°ºêBMêqükÐw…˜è<{iÙw½'p«z1ZZKûv±ÍØ=IÄ„<!Nô°—fÄ0§¿Ú	kÍ.÷¥íÕÔ—Pw­¶Ž*ihûEÜCý=|*JÏÛØ[CF88ž“Ð(?ùø/²úáL0RÄŸlÆuÙßCʈ¦,õ;`dá2ʤªÆ8	ÙAîa¹-¼ýR79ã€-ñƒ»xŠpë5ê¢á½ÇE8ÿ w£à§þ•ßø«%hA¢Òa£Iº:8M%ˆ@)L"dr‰„
+!¡@÷µ®n½Äì½ï{bçÇ	ãâ’;þ”ñ¶?uhg´ÿ Û©c׸ÁÕЭ´¤Z¯Ð%Žè©ủª$dÐ*I”À ŠIêPÔG–¶¾^f,¸eóØ ÒOH`žšž•Á—…Ž-¦•<:
+z
+ÄXî/éåFÑm2`W“
+§€&¡7"uŒ–›€Q­ÞóvmèäpŽVÉ/N˜üc_ 6¥baÆÝ餌ÒÖx.á˜Â˜Ï[¶ã^R]»r –ÏlB tJ²®u$’I›U¼ 
+°YLŽDÈÛrÈòírð'W
+µ£‰•¢Ë¾(#k]#êàÐ(>¥p+µœ3)E”„nvM¤ÛÆÌ‚ÅÜpÕœ„`.;¥WU›PPÇï‰Aþµ™Û¯{îd‰ä9Ñ°´‘Ð\uôW‡Ô°»™´²ü@t•´ Óñ..
+mÒ¶ÒÕ¥U()SNÄꐪmÒ—…4 §pR êL…SoPÔ–§^Ô §UIjuJU6ëPZWzYü5ñ[äºìœ•®›idŽ³YÈ+ä‘ŒM08œb¶Ž:RÂQLCF¨ïh]5Ò²ÜÆØ8+ó‹Ìæ±vÙhèå¹…a4ûm/?×ÓÏBÙñû3wemþ7=‘d9®èÚ;£úµ]E%' ò&f=ôL¬s…ZHFI´pÂA‹´L$Y³Æn“IÃg	41R˜£È![e½Åµäº´‘’ÚÈÐ潎cšz×4Aê Э~hf¶™Ö÷tw4s\\Ò:A„ÖªùM½C\¥«Ž©AJ’ÔÁJU9† µ:¥:©P§T §@ÔÐ'T ¦ß"Ôꔨ-UUÝ–gù÷!Áý¦±°ÎN»-ÑŠ36MÃ#ðSíRG¾nÀíä•HɈˆS  b€é™Ž`lLï÷no1µÈuÇ-ÄL{kJkiuX
+x ©l¸ÝŸºòö¿}Åão§³ê|pÈæÝ$6Ž§XmHúÂêéX¹{~Mì,ô\”Ìkƒµ’‰—dæ6J=Òc¢Ÿ0z’.š¸LGßBÁá
+Ùín­oí™yc,sÙÈÐæ=Žcšz\ÒZàzˆ$,ŽŤñÜ°ÑÌsK\Ò:œ× Aú
+øÁN¾Šç \UJ
+mñÔ–§T §UAjuJ
+uÔ–§T¥SmM
+uLU;‚• R•Mºûµ%©Õ)TÛ¥AjuJ
+]Iju]fáü¿‘#šÇø«$_PÍ_+æZϱ®{š1¼š-Ú»Z9wð±oZ¤ý¯QTȘà¡SX†ÐåÖòû¿iíû–Ù粘ë+Ç0<2{˜aya.hxli-.k€p%®¨+7ŽÛ›‹1¹ÄØ^Ý[5å¥ðÁ,­ Òæ5À84‘ZЃÐBäR|;ñ	#55‚3444Cr’ÒÒ˜Â÷aÝGoäd_»ƒE«&,š¤uYS4Ó(˜Â 5жæÀ¾¹ŽÎÏ9‡šògµ‘ÆËËg=ïy
+kÖÈKœçÐ	$€Wn}»í`}ÍÎ+%´l.{Ým3ZÖ´UÎs‹ kZ$’ ¤®Ÿ:ú+n-Zà)J¦Ú‚ÕUJ
+utTéìLÉUµî¦ÖÛ+É͵>…¡%$´<}Ö¼4Š6ÛùvégL§Nرn¤I#èS*R”DJ Xæe1rd_‡Žæe£ŒHøŒ362@tUÖI 8€ÒH¡]ÇX_²É¹'Á3qÏyce,pÏK%4— 	- u-Û§Mw¨
+ê×µ0)Ü%©Õ()·Z‚ÔꔪmÓÜ©-*ª”ëÚ(¯bb©·Çߥ@SªPSª¤µUR‚u©Õ)TÛ§Oz¤´§UºEGÊMÈ3ˆ…/- ¹0ŒŠhâBAó•9nÍ“TÕråsøB˜Ãà
+ë]\ÛY[¾îöHᵍµsÞàÖ4’ç8€ í$Ío÷S6ÞՏ’áækAsœOPh“ô »>êÁY²Å‡ûCxâ|‡mA µ˜š´g#㚊›€™<pȈ0QA8J¹“1¨ €€kx½ñ²ó—ŸÝø|®>æûª8çÏu:t´:®œKAë;Ú{£m÷Ì–>òN·¾µ£ÿ -£~€ê~%ÕeSn•´­~©ANº‚Ôꔪmê’ҝR‚]•U)Të÷jhT ¦Ý)ªªPS® µ:¤*›z†§JuíJ
+wJu[¤T|œä‹xXçÓòncÑÃù)®T*MÙ±bÑ5];táSHše1Îa  ®½ÕÍ­•»ï/dd6‘4¹ï{ƒƁRç9Ä5­‰$€Jæ·‚{©ÙmjÇÉs#ƒZÖç9Ç€
+h©$ž R¾‰h©{zMì$üT”Ìjæk#0ÅÔd›$Ó}»ÖRAÓUɨjES½ê‹K«L…³/l%Ž{9©’F潎ok\ÒZáô‚B»›{›9Ýkyâ¹a£˜ö–=§±Íp Š¯¹Ý¹rÇBCܲüÛrâ;äíûäKö°“ªE¸3I4áåVnFgŽtQIpACŠ* ”ú%uâÈãn/fÆÛÜ@ü¸i–&È×IxÔÃ$`—3[|fêPâ*$–7ÐZÅ}42²ÊbáŽc„rš;CÈÒí'ƒ´“CÀñ[@)·Jí–®µR‚ÁJ…0{M½CK‡ZuJ祧±:¤íî÷jSª@?pT–§T }ºÔ–§U¿ÅÛ×Ó	™Hx	¹XËq²O.	ȧÏØA4\çMS/ «x¶Ë(™ŠE2e0”@Dº79,}”ðÚÞ\AÍË‹bcÞÖ>WRØÚâÈ	·oc}u·°Ë%¼
+‘ÍcœØÚzÈ0P´‚uÜ ]T€p¤Zª¿Z at 8óÔ¢£À‹UU yõ¨-EUÀáÑKŠi@ý~Z\ð¤…Sª¸˜jHE{Rùêtªª¸˜jHíERÇÃËS§±5p8søèâRÆ—pW…*'Ç©\
+ÍH„ëÚ½Já-ë}°éßI!ñ¦Aäñ×æŽüýøÌþÖ»ýbE÷–ÏýÒÅþζýsv=ÚÖ©ÿ n…±)Ø÷kGýº¿<SKÄ÷À>ó—Ão&A¸k÷”£þUmŸø{úœ+òߘ5ø÷9û^óõ‰Dƒ¢½…jWxjH	Õ\ÏKJÀÜÃRBu*àq¥Døx„ø¬ýáfÖ°²L;«{#½fÙx™f,.ÎÈPP¥e1©*Ø®ÖE·¤‹cœ
+¢NÓ7¾˜µáüÁÍn-»vëœn–	*ÙÚ5jh5{ÚŽ%ºÀà[N{Ô³Çå,!mì¢'†Q„Ò„´é-5 vÇ¡f]ÊâÚ‹;´Å™êˆç|Gtìˆ)»bš´D…&ºróù~,dïešNíŽ"MÀPº¼ZâOk‰4Y›è ¶yŽ*<4‘¨Vœ:8Àº=ò-U6ôö†9Îc&át\{³X"tÛ  S€ º ºÖóo$ÌŒ‰t:ƒ¨Ö+ÒOWÒ°R†Ö­è[S(øÅc§"&£[º„¸Ìñ)ÖÆ (œ’MÙòÙN]ôÑ
+@£¼÷À 4ï"/s$µqmË ÓJñ ð÷öp+‰²¸¾ÁXÃ/·¼œ^J䘈zví£!Ú,“uaH¡Ô¥
+èê&w*¶ä1S\Û†ÿ -g¡Ý»Šä‹(àcdŒMzOgi§«é\BÂÑÕsÜü:ðùkaù†ç†œuq’êdÍ87Ί܆g¨Û–ªº§dºª»L¦*Å0ˆ<5ªîLÕæWL
+tN:À¯:EOObîE¬žéÇU>•”ïÛBL£gì“{ènÌ".›”ÄIôzåY£Ä¨Š6] ÝÐu.µ©1·1=¤º­ =GªŸŽ«•²ž£Ä-åÀ¢šn7Že ç÷¤Pºo	Îrˆ‰Í®¿äë]i-ËYZŽŠPt ó®Q3öŠÐË‘EWQ¾è”Ü@ê€ t€Â:{ã”F˜Œµl½5¯ƒÂ¨=äTNÅMÅ `0‰È¡•ô(¨•0H»„1D…0‰‡Qðìä«€é#Å"”ê<kÄô®V xžžÕµ]6r·4ªmÊ·šôS¹ˆzÑgt’Hª‰ÜPÄœ›¢SvqùSassb…Á¯ Ð	é¯I¥kZøx.GÛ	¡&SÑÒÅw¸Žå·:œºd•ºî!IËè¬téRž):*†$ÆDzPQ´-½žª™™N¢ÎÍ¡Ä
+JoD~á·Ë5¶Ø†ˆ1µ
+}Í4—‘ÀGjßµ#Ï«€?Jê²ÄÚ“-Ùl—-û1ƒZuÖNÀ;:{V'ÜŒ¢Î:›qrÍJJ<RnàPŠ ÑûÖÛªiÔàOFˆ@’ Dº&R€ t­×mÂ"•íc"dM½.‰$¸ñ«‰mOš­WuL_AÜ^ç¸×«€€êx.4
+t
+m´Kª@>Ý)§T ë
+‚Ôê®ÛÝîT–§T §=M
+uJU6õRð§UœÏœUgåž#áÓÈlI/aã«^éË7\"‰tg#¬v$vÖ)Ëeqã'.Z‹†æ‘Ër#éÄCÆ9õº2Û[—³;!‹9¹†Æ	¡÷.-sÁZá~‡
+8µÀÔ霦ÁcóÛÂ1–h“g·R³¤=°¶¡¤u´¼·Sx‡6­"„®•øÄâ,߯¯—Ù*ñ¶
+{[^سîy»rÛ²#˜¥Šˆ¶#"1lÁ(ÆÉ&Nܤœ¢§2‚&¬Þ×å&ÄÚØ6a!ÇZ\šiáŽY®^~Ü“=íqqy$é'KAÒÐ X¼÷0·f{*윷·xß›Ž_p´}–FÖ††Š
+©ÄUÄž+(3$ÂœNðAmñ+y&ƒœß‡rÂXZø¼Á²
+¤r‘)„ͯ)q(܈¥!7åê“WtV2ETê‰Ê!æ»FѼ¶çEÇ.±ÍÙy|YÈ[[Ô–ZܲC̈Kc”5Ò×Hq`m(Ví¸®½¹gòÈ€íÍŽ¿sM@q˜¤¥žÂàÀzHÔOH_~Vàç…®®è[S3q?v%!u[öôÜTU•‹BfJÙe8ܦ4ýò²³ Å¤Y•R¢ÍºYûa) ä)¸6·79›¿±Se6~Úµ0ZÏ,o}Åïvɝÿ elZœý:K¤“DMqÑWHäÏrïcm„v7p%ž(ÞÖÃm­Ñµãý¤Ä¿HmjªBѪ‚ ·W€‹õ§{y[Œ­[VÊ[-Îfw/öEžA’o͐’NUU at 2jvhÙL^ß±)œÄÎz`ååí¾ö†Îáù;«Ác<ß» \[÷]D 8]æŸödȍaÊ¬¬{Æm¯-Ä-±‚ØÝ>ðƒÝ05wúA' éÑ«íÔjÒÖû	ÂÇÙ±­Ùnð½oÓ-Zì…ÊÆÊÈ8ä–ƒLŸ™UšI¤Ì‚í%†ª·`ùHXÂU“é^s?~lÙmrËÂZYí[»†Bë‹[¾ýÖoÒ?½1Ñ´9„ø¯’7im	âKîÕ¶ÅÚ{–;‹M‘”¸¹ÏÛÂéöýйk_Ü8=Ä:œZǍG£€pÙ1_
+¸Âãá¥&2–p[Û-rÃüy)
+…ž­É1,›[sã†m,ä[I¶4¥Õ*ñBp
+Ú6d“‡j, ‡f~îçæ~åÇóܸÛ8Q‘É;Û¦HgÆÂé{·:à–1 MÔ÷Èèâk*ýC«ƒØ˜KÍ–7¦s&l¬›~ëw0Bd{€X€áªW
+;KZÀùïIã÷‡kÈŘ×=ጁ7bl3;i˜.Ëubîµ.û|uâeÙ³bñ)ÍÖYP0„OAÞæÈì^`fó[Ÿ#±w…„6;«sþbS4Á-(øÜæµÍ,%­s\*I¨¥×´1˜Ì–êÛ—rÝà/$|_ŒG,RÇÒÇ€ç4‡ \< ë¨+Š§]zÉjóê­îÞuÚvÄóe^Á¡-´Ë$dÖy“ÄO"Ք銸fS¢(€Žº‡~ºwñÝÉc4vN½tO¸ô5å¤1ÄPÔPžv-.¢}ÓKíD/¤°¨Ž$Tt¯o¸Žµ8¶Î× ån
+òãË󷇶‚ôpÎUoe<Æì"¡#›))`nØrÎi6Êt©.ôtÓ1S*eI?Œ9y”åNÈÃ|/ÍìS,wæ›ï3ä,ÃnÜùDŒºîæk£, T–ÇPçââç}5¼¬9º2_ßܺÈ:ëkãî"³º›vµ¸Èxp&”sè@  0+‰kû0gÃãÜŸˆå­®!m¸¶XÞfb]›È»»+/+*Í•âZìTaRzŠÊ*šNˆ£„ß¡9LRB½Ë—8-¥²±|þÚËEs°.%uÜqÆæ¾ Æ9×’5ï«H
+.a
+1è
+ ’Jò­é•Ü;Ÿ#ŽÄg1òC»¡`·{Þeº.pl%ì-m5À¸?UA‹³¤øPáŽË¾Ú`ŒƒÅÌfnYÄ|,ÄŒ7ø×Ú7„¢hú=¯1p¸žc.÷°tá4W|š)7ncÿ nŠj”šÕ·4¹“˜Á¿|`vÌ2l°×É%»Ñ}=»	¬ÑÄ"tm«Asc.sžˆ^ÒsSì-“Ê·jåó’3sÖ=Ì·×iÎ¥"|…í{¨Hx­¯¦Ž¯`ø8ŸBW‹býž=µtð¿b¿¼gl.Ã7)œÇwN\Ç.Ê&n-D·\Q2‚‚å&¨~÷›¶/µÚÙ<xÆn[æÀçètàú´‡>7‡1íÔ¦š8Ž+mË›¦OŸ±ÊÊ`¾ÁÚºRÝM–œ[BKHcÛG5Ô®—¯°F	i˜¬Î n·+˜0ž.y‘2B1'éÜ6Qr[…”zÔc’?cþêR¬!¯ù5°o}ñ6ÑÌ`qqÛ6værm´./-1Ž kµž?d–øV#kmX÷7-~ùÌGbn 
+﯊MFžŽšÈ{{„\…°¦vÍ\D«mœ«w({n>Ëyp]®& §RˆbÊ×i»Ó=ŠI¨,æIû„’M™½ !Îè¦&æÆô»Þ9‘³vø¿Ébä€wϸlPåˆÈçLç†éyv–CLƒ¼y-vû>^í‹}µŒÝ;—0lì¯Ù/æÛ	’Rö<1¢ Òu0
+ºG¸ Ï´%àŽ'Ãf$³±¥–¸‰Ë%•“Ö˜qŠ¬kÍFæ¾®;V)âmò—<œ¤LU»àU!ÐI]ãºI@:gÔ@ÊÞóuå÷%ÖÕåö*ÚòïØÅíÍÍÁ†Ú)žÒï»Ç¡’>WŠç6Ž®Xë]—·ñØ[}Á¼/涷¾/6°A’y"i§|ýNc#i¨-‹¨=!n¡ÁQ.¼•aÁbLµmÞX²ý²&²Y²t“% ÏaÙÖš¨%y+~Û>–íäL¥¼«¶é1P©»UÊZ"‰Å>©ç!ÅíËëí׊¸³Üö7±ÙýÍŽ}æâpM¸µ›KZöJçBXÖ;ƒˆhw8å ¿ÍZZíü„8+»WÜýåÍ,0Cc<u%ŽŒ–ŠT—7‹A:w[†.s+‰Û‡,ótÝ™vRbݾñá-(¤H6§w(ÎÊ“JeãÈ©f‚‹ „‚=¢„
+
+¸Bª²}[þeoÝŸ¾a`í­6œÓ29%¶»ïå²ï¥Ž¸a­{5×:'PŠ’Ö;žÓcí-Æùq{;+=ÆáŠ7=‘ÏoÝGu U—5ÔÍl‚¤tÐ9¸
+aQ%’¥:j¤s&¢J”H¢jD§!È`ä0h < 5îà‡49´-" Ž±Ú¼œ‚ÒZàC‚°)ÕÑÞ¢^¹pçhfÛëÙåwC`4î…o’qd³ÕKhÜE¶%~!CYéÈ	¤+hC}.×ßtwGwPùC˜Ym™„çý¥Þû6Ãv¨hïâï™Þ›Û‚ßDž5¨í<8ñ⾂ÙØíÍ”åŶÓœ§ÄǺ“ºvk¯¶¢¼xpàº/ á_h=¥dÜ÷E.ekbÇD;­i|©ñœ_ÄŽIèo‘‘ŽNó|gÌœ¤àSQ.É@P‡ˆÖïÞ\‚Êæ­¬6÷÷;³rLÞàGe¡ýàñšXónÝ.T;P¡«UËížnãñ“Ýæ¼›Šdg½.ºÔ݃ƒ›ß@ƒB(j
+(ºêÒáĹ7;Ê8®~JîÈ6•ÛnäLL”"E—‰Š¹±uÛΛI9s9 ùD[(Ql‘ÑXVþÍõ6¯0ÎÚß,Û;ží0v–ÒøÈ{·¾êš	ZXocCž·7E<gén³oj;9•÷{{†Çqi kcd:b–2KØçQ§Å]M©æwok²Î8熻ôB÷˳‘Œ’’(³´±äúѤ˜•†$Û7Òn&Sµãp³åÁÇt!+˜è§ˆÅsi“l¬1³¶n²ÚpH﹝EÓÝÄݲCšÁ™å­ºEÎîÉd9vè÷EžËÄÜ‹­Ã+÷‘¤­ä-Öökqx‰¡ÅîÒ:€‰håqü9p½w\r«ñ;*÷)´Fe™»ªÂonb;¶v»·+ÃÇÜcp;}ÝÑœ¨¾pU[«¹ª]¨¨™
+‹Ÿ˜œÌÄããÝíµ6ÃÝ|p]oàŠBÐ$t=Ó[!n ]^ÚÑÚt¸Žô[3cdoÄç$~u¡á–¤¯`$±²w…̇KÝVšxºªÐ{ŽΰfýŸxЙk ›ÛVÏ7»™ÇÂ-s]S’	ÅË1Jܵá‘]«E¤UTæ:®8I«dS1Ì&ÒP½Ë笹ù’;RÀdr78`Ýr`…ñ¸Í4„9Á€P±Ž{ÜC@HÙ-qØ›žQY
+Áy÷+2ó—ia–Y¥íÄÀ@.'‰sœÖ‚MxŒY‡[jصðîLÄWÛ«Óæ‰[~õßÖÑš¶nxY4¢_Å\äÎcÑn.¡Êè§*%M˜uO³UOJÚÁÉd²y}·»,[e¹0ѲYÝ<sC#|>(y4 , ¸—4}­Mn¹6mŽ;7·®s„ɽѱҴBøåcƒÙF¢Ð+S¨PÑGÉ?ü%AÞq¸š‰k®bþ~þ*ÕÓbc¸ù¼Y;4
+HÝ™%¹BNu“'.Šš®›>ºˆ$%9K®·~óZ÷&ê°Û–°àcò6›·Gzø£©.Ð!ÑœHcÍGki9“´y}k’fß¼ÍÏ&Yïk°[µö­{éA«½Ôö´›Àÿ £Bэ85}ugŒÙ‚o;ê2Ì’ÃÖ%Ýw¸ºÐîm÷¿g¤-¦ì\?QuZ9‹€¹ñWŠ*Ýÿ ¹k¹¹9Ã/cawÆÆKË|½ôui•½ë&.
+ 8>V¾YP×8ý [	Ëio÷^Ojä®Ùm>6ÒYŒ´¬nîÝiq$ÆæÈ]BZÙ%}Iðá…o¬”æpng¹okÏZ®/‹¢6ä°¾ÊÀ]V¤P˜'æm–w&ÍÔˆ+7É‚ÊJA!DÂbñžbo<&g½°öÖXlÍж…ðÝwòÁ;ÿ ÙGp45Ž/>)1 Ôê4¡±²öÆWsµ²SÜäñ–æy[$ÔrÄÏö„ë.£5‚µ¥€q¤(µrçy"ã±còS©„1­¥fZhÜ×Läd„™ÊÝRC!'Â.«‰&cv®ˆ`Q3h ÞËoÍɺ®¶žÀÇ[ß\c[¼žâs¾P\È¡sä-¸FZá^Ž¦?há-0û‡x^Ík
+ëž-¢†!,¯lfŽ•ÚœÆµÄ :\
+A¢Þr	¬`pÜç_ëå¥8u±¶¥²µ¤“sAËÛ‘Œ}!’ܵ9†xÞž
+è›3¶PJ¢©€(==³ÍY¯çÜqîËâ›·#ÓRa9=äs=Ô-kC‡æ‡u§Œí«Zïv3¼¾ŠÎ,+öíáÈÓålUˆÄ‡ÆÖÔ8öž=x0´Ð¹¼W+ÿ «
+
+/‚a'üJM/¨ZÎ&Zc£+‰™_\}–Vei¤f”I“zä{"6€¨b H¿â72eÂé܇á.뾺î—榮øF#1‚cüà‹Q}<PO²l†e>›7/Ä]çt^-ëhÙ맺// ˆd mx:ä"ãÆ7µÏîæ…eqÚRîá¥EAU¹—lxéšÆ"b»ÍÌESt½¢*ÚºW¯à3˜íË…¶Ïbœ_Ž»‰²0‘CCÒ8ÑÍ5k…Mê^m—Å^àò“â2
+Ó{o!cÀâ*:Áëk…ÓN ‚¸™TÛ¯k-¤,}V{ð)w[2Ù†·•»²Åç×·0õýu,›(h[Ã±3øñ–]'
+¡ßÌ“ÑÁ ˜¢‰ŠMåT•ðŽxâr7ö˜‹Ãgq‘Ú¶y6BÖ ]$‘ø®Ð263¯S¡Ô¨Ð\ßYåNBÊÒç%l.a²Ü6F;;‰Hk!>3uCÿ Kˆê T×vÌ+~>¸l¸~_0/cµ™IÝòô[(X÷eºùƒ´žº—ô)­H¶Å"¿¦8j‘ŠSTNrŸU½“üÆÇŒ{NákÙÜHÛqes­sK[¦@xiîÚ÷_h#aµg76MáËe"¼Èá‹]ß1Ó¨%Í!Åú])hã«[šÅ$Wĸb'-þ¥d«Šámˆp¦?p”Å6£'—CƸ$VNÛ²í–;'óNJ€(c¦T‹º¢€"rþ£º÷•ÞÓþíÛxûwe÷ûK"Œ9°µÝÓšâgB(ÇP\jÖžÃ@ÛÛbßpýû7{3qÛḃHúK{Çî›â™x6¤Š
+8ô€yeÀqµÏŒï£ÃÞHŸ½ZãQdã YW¥®µvÄÀH,£v÷LZ‘ò2QÓ1I¬‘ÅÁ	¸vÉNqïqXýý¸ñ›’Ïls”™-BÖâÞc4•€ÃØÇÆòÐMCÜCZ:HÈ^m%þç=³¯fºŽÇI¸‚x„r²7¬Òç5ì¨:€¡h“Ð=_…Ì-ecÜ]’2Î{ql²ÉØý¥ÑjÅZ¥î‡NÛ‘ÁÙ¢F*?I­¼Äª¦S?p™{UOÙ”€%¬|ÏÞy­Á“Û›SÛ™±—î†IßpØá´Ð8ê.•Ô$DÂt´j$‚²¯Ø[c‡°Íî» ŠúÌJÈ™	|¥äVƒIp¶ wŽ¤ÐEÓÏ›^V¡4òú·ò•™hÞVÙ£SŒs6ÚìA»2MãÔP~‹òöb˜«¼P‚`.ðVå±÷ÈÜø{ûܼ,±Èbï'·ºYxŒÁÄ»QkIioé¥C€­³ºö™Àäí-qÒ:îÎþÚ­äÒ^%à§QÁÜ)^°M*»b_„èç[«Edfd·±u”ÖñÌ*b!Da¬´o)4“F,ݪ¬ÚÌÑ~‚h"URUuûB›³Ž%Õ-9¹#ö5®íºÇ<ä2—®·°³Ž@d¸%å‘—9Í0â×8µÍkt‘«SAØ.9pÆîˍ¹ozß¹ØZ‰¯.^Â
+x
+i:ËCšÚ‚çjN“AgÃæÊׂ|<å‹žë¾ìˆ×BöUóe¥m«xÀÄn»Û9û)7Àg­ˆ¡L“	ƒ…·€=茒ówí‹Ë7smk‚½°‹‹kƒ0·–J÷m¸k˜ßЇHá´ë¨
+#Ù»o=mr6vB{Œµ¬.”Ã<#4lûn…Ís¼aÒá¨×«‰_e‹Ã>0w„ì\픳_éí±rÎܐ¯âR¶ÎN.æEÔ{–ËV®âEg`Ðë9UDJ“4ÀÛûÁ\YÎeîx·¥öÆÛ_ï´ÈÇ™„Q#÷:g8 ÀÝA¬hqt‡¢”+“±°2m{MÙžÊ}ÎÂydc˜"2<–8µ¢ ÒK‰¡.% 0tÖ«'IÖreµ¾ùyHòÒ(BI9 at Z¹ˆIâÉƾrÔÅ)›.í‘H¡Ó!Œ! i^½bë¹la’ýŠýÑ0ÈƝA’‚ö‡u†º °*¼Þí¶ÑÝÊË7¹ö‘ÁŽ"…̆¸Ž¢[BGQà¶â©¶»«‚«1øJl¢9Sˆ™D’3,d:qmzBbtdÛØŽ-‹¨¦>ñb »•×8€Q1>È`ñîlHü·÷_/m‰ï³w­PжÊÚ“\º½D†µ££U\Úž úW.ØÜqÈo9À1b­IŠ£ºž±@>šç4é[¯¨—"Ú8o‰¦"Šd›e;;#=ÍæùFÁH°Ï¼)4ìrC´MväL(·›MâëÕå{ÎÝËf9i9!¸Û“qiZñ²º=ãZÞÞæG¼ôj}A\ûùƒ5Æo¨…]} †ç躷]ÙÞ°4témOH]“0Îْ዁7”«È;iÕßšÓ“’aY·H/é6!"Ìá©]‘˦‘ÀN R(&åÓA×,æÉÛs3}O‡‰“ä›gŽÐÇ?»i?uejú;MWH…j³—1XO±6”Y9‹®oµ9¬ÖGûéâÔV® <xOR߸™À6Åÿ ÅÓüw‰¤™BL½A¬ÿ µ´ÞÛ²1”=‡g?Ji«èõE	6òQë*åÀ»}Ǫ!
+‚ tyi¿²xRG¸w\ožÍŽs-d®oe’êá¦75â¬,xkKŸXÁu n•Úß[>Ã1ÌwávëÛÓÀuÃB(-cd¸<9¦Ži.uÚ<†ñ.ªêÈ°VN”°pÆožŸÉíXH9€gvØ嶭\„ê)¢¯GÛrE—vö%[(¢^š˜Ê^þèåÚo÷þùÛ6±ç·ž}°ùÙ]Ï}=£^àÖ¾fwml€8€îìð'¶8M›´³×ÄmŒ¬ÓgšÇÄÐwQ\â؝¬¹†€‘¬q§eHÛq_
+–Ù‡¦³GÊdÆÖ®Pua\LßÛÎez3(‰S’£W!!s;–+b³wRI59„1³ºy‘—Åov~ÝÅœåÖ-·P¹²†6®–F~qÎYy“U\âÖW.¾ßØø܆ڗræòp¶·¿6ò5Ñ—:ñ :)sô†R€<š4…¼[|9bKžÇÉU,ØîX¹	­¬Ê^^ÐtêJ~xÈÇ©¸cƒ†¯”¸^:ìh)¦EU!
+ažK˜»³œÆíga[q¹/±îÑÇpÖ²)ÞÒ!h‰­f§IRx†µ¥Ä.Í–ÉÛ—ø«íÀÜ£¡ÁÚ^ˆš÷ÂK¤ak\Xwxâí-e á©Î Ãòn±£±D>nÄW¬åÛc¹¼W°'˜Ý0-àn+zåN3ã†à©>zÉã'qâSï³
+L'0'™Û;×9qº¦Ù;ºÊLÛlÅÔN‚S,RÂ_Ýš5®kšúŠš;€ bó»[Þ‹um»©nq.¹6ò6XÄrG(n±].s\ÒÞ<:*:jiÉßáþ,3D@äŒí;!xHÅÇȈ0µ#n«JÒ^A P#ßOšt§]™NTY¤ ]À6šã ÞÆÏ	¯öÞ
+ðñÊæG÷Ùßó†kl]Õ"èox領]ù¶ÎÈÄ­3™iŸ“|msþëe†áö]'yùÂÞ“ }ªîž°%±ŽxÎaŒr«+ ÌIÊYml£)n_ÑòÖ<ìŠ%›É,ªP¦‰9œLGEÍ»2ÁºµiœÀß¹=ÇÉ™7>Þ‰ö¢IË“ßMjøîba– d×%PX{§ê ±m7gØa9žÌjF\1Ï€wAñÜ5ðHà^Hf–UÝüãt‚x9ut>>}
+ÅKìa•®¤,»*Ù‚‘’cñÄI^àöBDŽ fc“–PØC?IR íBŽöéuÒ¶{ÍÁsæÕƒsâ­]š½¹•Œw{Þ›m,e%æ1WÈÒ‡‹CÂ¥köØX%¶Üà27
+ÅÚÁœÞï»ês«Û¯ƒXàtŸ½4©³!mãñ]ÅoÎ9¹í|«b²ºbd–+ÛLqo=mœ»œÁ,²:€!¾et†œ»fÎÝÒî;Œ®;!mr˜«çA#õ+Õ!´€âPoO®îm´Ì8ûÛ)]qÈZ6V8·I­$Š€š˜Éh'¬ž…Û’œ$¹m•c1[KѲàñ‹‘™.9˜ÿ F†Æ-Ł$fÙ¨VîÖVWâÆ‹ dͼoé$׳)T9u+^mG&Õ—uKdçE>Möxøc~©/N­¸U 3[ƒ6š‰h;Ç.ÍÃÞŽé¢H¬s{#ÛFZ:žÓBKô‚Ò8·V¡ö@$R/✅Á
+‚rµÇsd+väÛ[^ï³n7¾™EªI…¤õ¼“Å[¾"Z¨‹GIöÊ€€éJ¢„»­ý»¶Ä–÷›ïmm·®&lnžÞã¾6®wí,h-¯HÃ¥½<IkJ·Ùûk<É­vŽFyóPDéSAÝ‹†³íw.$:œZǍGèÎ~¯` +Ìê®ðR-N¿ZP?]Aj*®Š’ÕUJš(ª¸(úRâRÆ—UÀà4§R<õ¨¨ð$óÒ-T®æ’;QUp?8xªiØš@?0ÿ M.=iÕzÇÁÚzÛLÇAån€ó÷ÑLkó?~~üæ¿k]þ±"ûÓgþébÿ g[~…‹:»Ûÿ “ZšØ¨ìGoþM _†Ž*Í»ÅAÍŸ3rlÈwWîW)?éNØÿ ‡±ß©Â¿-y‚?óöržø¼ýfEÐÀ`ô¨TŽ•p6á „ê
+¸œ*t§ÅXá¤AER‡¦¦:«ÃÃÉRZɾn¬~”›Ë"»<K[¹Ví;˜îÞ>
+ìméG¥"ªBG-›Ë‘Eé9; y5QòždZg`æp >xuw‘‘S,tñšA#ÓÒà
+<`¦ìKŒ}Äc2d†T»û$õø*(OUGUVkHÆÈÛ%ç+$@nv©¼rF6Š¤w"ä­âç
+á14A@[]wÒ †•æy»+æÎåÑV ð¨i„xÍ¡áÄ}kn½ÅÏm!Š'°tPôƒÐGQ¯Ð¶ÇÆU±»ŒLŠæHçHH¢ªÞNØ€:öb òVjôt/•þ©­ÄJÃô­˜ÆjìälOHjSHs&ºº@JÂs v… Ð4]à×@Ò÷isº¼+¦8tš…Ä%!¤Ñjç}Gj šŠŠIûS.rh`íìN˜ÉŽ‚!¯'‚³6—VÒHÑP$ T‚8£é¯RêÈÉ#ããið™sì9-!+f ¤³BF¹m3(Ù…ÒlœsS¦1äjˆ¥ì„‚n]Ð.ÊÔw,‹&ã
+]£iÄ’H$ŸÁô®í±kâñxËÔ)OÆx.ÞMÙLCé¡Ä¿Û)¸c §ìÓÜÔ
+*x’µÇBC…xu
+ý&¾Ùèéÿ x(I^ÇtÀ "øE1 ö€A|Dˆ`Ôû¾ÀÔhužº‚5Úð¯i?ç)‰h>Áü?÷-í“—àS¡¡Ûn½²¤M$„å8
+j¨ªÇM4ÌTÇP.£ËÊ5Òš{~JÑ-iARiÖ '_à]¸m¯&«âˆèë&£ë4[ÜkB¬à)0YP "mdÑzä `)^>7f͸€j"'8ìïWNæg2>ùwQ‘þÒâ¬oþ«\~ ²Ö±Èá“5Òö £à/û#ð•Ü6ý¨ñ€œ‰Ã¶Pÿè‹ìËâ î’jþ‰„ºî¢u÷Õ¦ä2ÐÈx<££PÓOQlc¤ý.'À¶;k	 e>ï飵Jÿ  ¿ú£ÿ 
+>µÄstlsotÄôm%w4û(È[6ºzêX¾Š ‰S!—t©ö§7„5ËìÉnï³öóÞ=ò[Z“;µgM  ð.¦P[ÇlYnƳXé$ŸÆh¼QÈ­˜Â\jÆ»$ƒ[Q‡ZA!Éô¿¤.öqÂ"_xfä–vª(˜¼†A
+}gµÛ$ØßïšXû§™OKYÁ±ƒØK at q®+Å7<ÍvKîÌ5l
+¨ëwK¿§€Á@ûkb-Zõ~´ q¥DêÏ¥/
+uJë¥AÔŠ¤óPÔ–§T€~%Ij`¬»à‡;Û¼?ñn]×»uãÉø©Ü‘nš«.Ÿy1çÏŠÝ휧ð»U"ê*Š"e•åçÙ
+÷°î1Xgçà–;«RH ÏnímmO ^ÝL$ ç㤿òÓtZm=ÙC&ÒìD±¾ŠTžêfés¨8'KÈHi T…Ú7³ˆ´¢|)m¡ñdûµÇÙBømy)èc–˜TòíKnË ÝbâN$’\§Ü9Ó.ýkxæ`ÿ wiÞWÂnh՝ÌS2X¥ÇŽíÝë	Ææjqnš´8Ñfò<žÝß|®Ú„e0rº°\Á$ncØOŠ^uŽíÀ@ZW&âRÔáã…«Sƒ¨+ÂÞ½²tþIW2g¹K>E	»jÖ’B8s¶žlc5•}‚	8~Tµ+gÄ Â
+éXÝ…m“ßÜͺæåõ¥Å–Ûƒ,1Œ†9¦aË-ÙˆøÌkÉsb'‹ãxáV®îížÃhìx9ykq
+Îj[Ͻß:'ǃ4Gn89Í 9ôû/oOŒ²‡Î¸…ÎA[×V'±>Û@Icle æF*~ÜL¶ä³H2Í®´K3un¦-WMÉr™¨Ý@10Ê_5äW6vËØw½Ó}÷;øò7’†>)zÇIÀÀZÇ6S¨°—‚Gwnkr÷wnmÙö×ï6³¶asdóoâ%p1ð!ÁÎ¥¦ ž w?XÕ·׎‡¼ñë·L¸2µ8a´òÖ”tÆ/¸3
+€2sMØNKz.BÚ”“ž]‚Ç\
+šÎ)ÅDÌmFï—ûŠNYZoK»;öDýá>b{X㼊ÂëDeÑèñÙ3ehmKY&²F—°Ûîü37ÍÆÙ·¹´sÛ·"ÆÅq(kí¤»ƒSÃ_«ÅtnsÜÂMs4€j	ãv;®6ñÌ•ÏåK†Žmu9"ï-¾Âø´8~V.µ·,tí©–R÷$µÒ‰ÔA²[qrS9Ô"JdsQògpÛÛ`¶ÅöãÜùl„ѱ¶-È^Ð7P.–äÍ™! 9ÆFÕ¤P5®{zxÇó/4ùl宏³î7FÎÚ¥ÚHÃݽ®‘òŠµ¡†Ž*I
+8mq¼Qç²¢Üz©S*®øé~áR¢B¤‰T_]
+œL¾õ4ÀÆ÷¥@JõÜ|Bæ~âWKvK@¯A}âzÏÒ¼êòC'"¡‘Ôvèqú8ÚJ~ Žù?ÿ åÆ
+þ¨/pÿ å™ú¼ ÿ þ˜ÍWü5oúh”åüÆ~Û›ôr/9N௡hBñÐW(³][MîÛYÅèÑôœ…ǵٿ¢Ê>¶R“jyæqÎGÿ f~æ,ª‘?Ø(`c2ñddÅ]G‡{#˺ÞAž51³ž:Ú¤¸u€BîãŸdÌ„É5ÏÇ	˜ekMèÆ°ÓÔâÚ€zŠôG%ð3–˜ßÇ¿¸3BO*ákt$±Å÷Ž¯çSè¹nŠ® .¥+=/
+èÆIEI 1 »âEAT“ùÿ ns¯jÍ‚.oº<^ñ¥—v×p=±ÈA KX褎FÑÀ4šÐis½{5ËüYc•åÈ}þÛ”‡[Ïo3KØcÈsdcØj	p)R©£½óVaý![€hÜýq±¿ø†Á÷ó‹»1ÈGÊ°».[FÄ5Ýú"ѹ®Ç.‘šºÑƒD«#¬ªÄQ®ùÌ à«8Ò6vÒø­›êãb[¾Ã`æ¬{3Ü÷l“ÃÃLp	ipkZCè îË#Ú7&âø}ÛR×3n÷v2ìËvæ¹²Éë\Ȥ‘¤‡Ê€$[R|pçõîcàw4ež%îÌ…`%qàü¹~Jå¬àÂç·Æˇ³.é…îYI)%¤“Z9kQk¤fê&œ[fCï]ƒhó«gín\Zà3¦K}銱e›ñΆ_¼Iqb1¬!ârÖ»P:F³¨Šb7,w&z\eñ!“mŒ…Óî[zÙcîY¯29Îqp-1ᤍGO jG5Ê–M{A-\i1!)–0ö'äY±igl˜(ØHBI8XŒ]+0ý58Ã"‚Ú•2œÅóÉ6ÆW—œ·ØYMDZÛb³¢êúŒskF¨Ú@—…[!ÑBâÐwgqûËzîÛ,‘¾{üI‚Ö® NøXÖǤ—¸9ƒW 	SßùO	`N7$²´C+.VàáÒy´E™'1¥ê¼{A~w«yƒ—nã ='Fé.ë±kÙå)ŒO0¹¶7žúÙ–Û^gÞZÁ¸"2\27‹pçi¤BWµòÓÆsY«Ki¨‚@XŸ³ó»gjni³Ñ¶Úypï…Ïi˜´j¬†6’[|PçSQû €Jé)O§žÎ±ïkÄG’ö³ktå“kÎ>`ÿ ÷ø¯Õî±¾¿é¶Ïÿ …v6VÆ·X#…ËÛ Æ…ý-ˆq>ÉöTŒbwU£-g‹vq“ÊÁ<zÙÓØ»©r8n
+”ÞÐÀ '¯m}Ljå&øÜØm÷'Ü-rÙi26wOcÌÇ=\ø„­ik_£K_CZÒ ´»1žÂäy‰µ°y=¦Ï½\cñ̲¹®o{á kË	¶QW6¼)ZiÏxc³á¸>Ìã\™‘1û,—ž¸~½-IX)æñS®!¾&^Fº²mœ&rvôÂWcÖ+Ö‡Ò(Š)˜TIÁ6™9{Îmm&î=¹¿~ÜÁç­çd±Ç=ý´mx¸šÑš,f-m1È*ãã¸ite£+²qÖܼÜ'š¼´nk+ˆš'Fð×Åi3ËL1Ü;S£x“Kµ°Ð}–Mx'´¬bq£eÜ’÷VJ°øjá¦Ì°˜LIÉæ§øƒú+C"ÁÒlÚÙç·¥JÜoî-þÁ2T;DÕ1u2†"*ë9·rs1Ž‹·/·ãÌ_IŽmýæ§UÍ.uÇzÇ2&ÅöœdƒCžÜæ-¼ÉÆÞÉ™´Âáq¶Œ{xëKj
+4ÐCݸ:GIöZx‚GC]áì̺ósÓ.E39–“&àQ@SߺUÒ¢›T΢mÓ€#¥}©ihË;H¬ã¯wm`©ÔhÖ†Š¸Ð“AÓA^•ó
+Åînd¹}5È÷8ÐPUē맣©|%SnÞ*ç-\U^¬áLI‘³_³ví´1}®êî¹RâôÓ'Šfî5šÅŒeŠí$;í¥^°l$EW©@'þ@×O—7–ëÛÛ3ùˆ´Ën[–ÚcŽÓîÃÜ׸kuìä6Œk×uS‡J÷µ·ó;›“7츽‡^Z–ÚÄ	«‹GG]x¬t‘àŒxçòÒXNq´t['R/ÜžrÎ9[²d‚Ž].b¥qS1„
+Q0€r z¿=ùKwq­¾f\Jö± Gp*ç8ÅN$Ä€´é¹OÌ;x_q62VÃKœuÃÀ4TžW€!8L|—Õ^1/äd•‘¿œ†<øÝâÖ½á†Mƒ«Þð•*{À0Q,X˜Œ;tÌ‘ž1@j¡´jÂîon1Ê,Œ[Ø7ïW÷eâÚMmµ»+ÿ Å{œºHpSA:ehÛ¶£—8SÌ\°yšìýÞÎÜ8´ÎÍM3ÌêQm#Ô(_BGÉì‹*Ñ៍#.HÝO%8zâJï’±2Ô“¥–Y‚y
+=c¸Bå“zs¬Œåµ? ‚2›|Ü•Äšîfï-ÌŽNÞíK{VE¿öìÐ2æō 8Ú¸ ac@9¢cX(\Ó*4fq¶Øý“Ì›]Á5äÚ¨¦tn$–‹†š‰î!ñÈæ¶G8Ô5ÚÝC¨vŒözfö·t³\†hlsŠ-öÒòÓ9ÊRNFÄ%ºÁ³…㦢ým's˜ˆ•Ɉ9'n©	¸pA¹çöË—¸6CtÜ:6Gc$eÏzâã~¨Ëcî¼bçŸéñI¨Zt< Üñä$fcº²ÀB×½÷ÎsvÐK^Ú>¯×À5£Æ¼`(Vó~Š	û7ðù[.w
+‰Ä½îF¨º€ž–;~ÑnÀʐ ÂMóîˆé¨é­tðZÝüÄeÌ€6C¶íª¨½Š¢´§Eh+Ó@»m#“8á.g÷Üô4¥GvúTÒ½•ú×0zÒÖ”àÁèÛåú‘vT—7£ÂM%c­gw{†÷ôÖœQœJŠ¨ÐwDºéX˜fÊ[s‹zÜá#æcÛöî·a¶àÄÒ:ä
+}+#,vò×kÔyüÄ͙աlFb$p=D2¦«-硸²²ók[{Øx§ðËq@üQxÄÛX‹ìœ¶?+¶B[‚fõ¹ÍÍHÏK4Pæ1QP(áOxC{CyMç*³;-Ù
+ã}”Ës*Ky{ËwÍßÇu¥ßšŽÞG"Ô ¸wAƒÆ x£Ðní¹ŒÜí³ÛV–íÉ™¢fÇiÝ>
+·óš@÷ºGŠžYqà	ñŽÈ‘¿íÓí
+nrXÿ òî'®ã‡üØÿ ö›?Òß.«OüÓÞ°.Gh°ïƒëmq¥Ë®œåÁñ0J½wÂ™-›ÿ جWœr°ÿ ¹noønïýP»ýÆ7ŸÜ:pµp`Ø¢_¸ºÏ‘ÅYψ}œí­,Ñò‡”}ñÓc„|ûVÊ.. w
+LDuîkø-ˇå0·=†ö”ÙZäîÙ{i<yŠv9§¼c^ÖŸ'Ý$‡S W1–Áä·æÍÀÝíhÅÕÅ…»­n!cš$‰áÃCÜÒG‹ ÚºGÓNóºåãøfeìÅ}|ICH1±$sk+¾JސBv&(f&-8¹ã"ú4ÎP’= ¼Ê¤sè¨fj!?½×IÅÚÏ̉¹—9£žú<s d¬1=ýÜs¾*µúKÀ¥šéFÈÒêq[MýÄ;"-.Qñ¾+GÞ¶gFàö7[âl”sjÜ—í5«˜CkÁoópZHeWŸcqo
+RتVáw9oç"ã\TúÒ%¼’®Ð»ä§ÁÑU3Èèßí\¦.Nºfì÷õ)ÍѲ¿åM¾×g÷ÆSrEºb·lrã~ùzÙþò`dZi¥ïñX~Ài©BjæϘ3gÝýÛa„“$Åñß}ÚÕÑwĉ%kV·‹‡Ú.•¨'Ë.%/7×ÖsÈ·,•ß~¼q0Þ5[ÎÚ†,ÆìT}¸Œ¤DY¿"lWB(½š¥YB¹ í€tR¾ŸåÆÈÇãmí'°…°—‹y¤ïe‡½{å,‘ú[WóVéŸbž*ð}ë’—+ºo/g¸ŠîC iš6wqÉݱ±‡1µuC
+N¯µÖºHë­ÐµjõY_Ãn5ŹŽ#(XWók_0;…Œ’ÂR““©Ã[³L,¤Í«$w;ŒÆBq·b“A9ÀC}C”ɁMåœÅÜ›£h]ã3¸øu´Y3Ù‘dq&dnhÎÊxÚ#:%SA q#ÙX<ä·¾ÄÞJØ7¢k¬œù4D÷´’ø^ž(SÖH©9EÃ&âïe‹ráº>9Ãx®Ôk'”&.{Æ>Àqh´rU®.	Åâ'”d™Ñlt¸¤¹È¹LMÎоgÌ­ïÊmñµn1øÎç1º. s,£†ÞGÝ	ÜÚDà{±$aŽ!Ï-ÔÐXAÕ¤ï;ksjno/ûÜnÞPë§Ë3na²4e.h!¥¡ÔqR£Ÿa<¯{EñaðŒn<ºéÌ.²Ž³r,›zø^PÌÞ@DÄܽ”C)ƱMHå›S	˜¸& šj<ôÚ·Ø[«¸÷¤™î›\Cl²’J%¶”3Se’Hk#¢sÜY#ÅAÑ©Õsš—ÚùûLœƒµÙgýãq’7VpÜ1†9ã.¡Œ’Œkà sš¨(Ö¸¾éšâRÇÂYn{-ÂaLq[/lHÛq®/²â¯Œ¤7KFÉÂÁ¡oI7‘dÞ5»€pwŠ‘DÑ íHCf1{».\f÷®&ÇiÍšÏ\Ûܶåó:öáöÖ]Ñd’XXâò4ÚAwØ$j ðßÜïl^×ÈÝî(±xˆ&Ð66ÚÂÉî»ÀZæ0Fà憃¨¼‚Ú é$tWÓðT<ü<Æþ™o£ù£yÿ Äþ‡-S˜Çÿ  mØíþ²…);#a«.øÈ/ü]Mê«UE1u9`LAIÝV»ÖP†Qgì²,"dhA•4QÉï•(ŸóNÛ7·w…î ÃÜo‹X-Ã…tÇu¬‚g8ºÒBd<	s‹’·
+>/5¶­r¹—ûjO,Ô4«íߥ‰ õ¹·ƒˆºGÖ\f“Ì_<DEÜr¶‹Lží¹)+^FýjÅå™'›JÈÍ3¶¦[ËoÇ•”úòÊ _û0JBï()Û77ökm0{zëÛð8–2vZ¹Í¸e¡c#tјèýQÁ:xøÅƍpÁrÛsœ®fÙ-›—ËÀçDéÃL.¸sÛÃü]25pñ@qh=õmIq_Q»ï¬‘h`~­û.
+Y_¶OqF?$„ì¯bd›Zv«h)6²3/.ï¦A@â‰ÃÞêa1J:.JÛ•{ö˜=¹wÜ9ÙãwmõÖˆ™Z™ç2±Ì±p'PÔ:x HÛ,fæ·9lݶ'
+ikÏ|ëK}R:”Ä#psÝ'4'£‰ \ÉGÿ °G
+#ÿ IÙLé):ôý¶?ç¾äÿ Œ²ÿ Q‹CÎùGƒÿ ùë¯õœ°dî
+öâÕå ¦:ýÚT)ÕzK3á[‡¬7ŽQ²qÝßuåÖO3]ÿ ’­f×|c(ÉeŽÇ„N%⨁Àæ7jQ2•P(js|ãgo4¹ƒ˜ÜR^ä-1X—·k%œæÝî|`¾ì™
+[Þ8§ƒšZO@^Ûu—vÀÙ¸Ì+ml®rºöá—1	šÖ¾·ñE†“Çì¸:%rM’Å~3Ì\;½°ñ}™:ðå,TÇÙ­læOo{PÉ–Q²±ìÜ.ÙÔÌôA‘fEŠB*V€°NP(¡ºöãyU¹pü‚ÿ '{c÷¹_:òá×m´õÐCÜlqIªBÒKLš)BM{{{6yƒƒÉlÉm,-nûŸ½Z6Ú]<_h´_#(ÀàÕZŠS€d—)³àû‚.OØ¢ÚîÌË89€ßÙ¦†KpuLb€	ýáJ"  #ÉYý¹¥æööŠ1WºÓÒM˜§áX|ÛÛ-¶«ßÁ­¹½'èäÕf•Òá|[Ç=ñÞAŽ¸ˆÇÇØúþœ^&NÑV\,|w¸æY·¤¬2ÖùZ©é$#uStS	»#áã8¸Ùº9c€Ã÷Ówv±‰p#ûÍÝDgHüçw)xÐKÚX@ÀÓïÞü5îó>ê,.fËîö÷,t%ýÅ·ŠŸ\z C®’Jàö‹>,-û¡Ìµçdðû„íM’rYÞ4ǁ
+Ý&‹™‹ËyÜKæÏæU—8‘4JÔåSE½öé½àæòÓr«!‹m¦÷pf²×e¬f=·—}ãÉpÔÙ[#KcŠ—Šx¼*<aŠÇGÌ+;÷\äípؼu¸szm­ô4 t˜Ëòþº
+xñ¡àqÚFi{ƒ…p9Y5ÜÍñ’úYÂé4+–^JÉzª©1"Š‘šj(¸ˆ$0&»¨é­z%½›,9鏰ŒÅÎl`j 2êF€]A¨€>Õzh´©î_yÊ[Û¹såÜÎy iºÝŽ$6§HãÑSN…³Úÿ °Wú|µ“þ"‡®æ\ÏÌHáŸô².®7þäkÅú6/ªP7³æl¨t›‹&ep¢eßQ4@§L‚:åLD@<#\Wáãù€ƒ» Éð›¨A?{–•=•\–š&åï
+ñ©4û´u§ÓE•9ÞÏ6TôTO	Ön<·pOÙÛ}ÜUk
+Œ¥žŽZ)¢Ów
+ùz^M¤Îš¤Á`PÊ5‹tÄ¥0ˆ|³Ø™«	nù¯y‘¸ß_x•²ØºKÖžáV¶ö倂Í4 ÷E	^˜²ÝØ«¸íùwmeÒî#,»µx‘¥€É%Äóô:µ¨PõpÉ6aí6ÅN$äY³²ÛɤÕãù\cvÇ1âM=däž&š%(ñÕ)@9 at +§¶’åŸ+´o¨¼s´ñ.kY{Ý^“â1¤¸ž€	+³y<póÛùÞÚPÝ] ¹ö³5´è3ˆ
+d€º*ð.üibñÕlÞÐêAͶ¤¢ŽY»í?¸nX¼Mf.¢d$Å÷ÛÚwÀ+zÏgñ—;±²xY„ö_™š€shæÅsHp­<
+v©b0Ù,#vØåb1]}Î'i«OŠé$- ´‘B8Žµ¹ð’¡—±›W I Ír
+y¡ªîŠE
+¾8Y›ùK²©
+¬p\qH¸w¨“Pr^Qå
+êóeù}£¹dÊíøÜù76<㜗Íd×û}ËÜÈú~Á\ü¹n7r`™Ì¼5˜ß¾‚xÖصϚ:g½c\þ´ÇÃfvFçÍYáõÍ!nÃOçkfçmi¼¼ÒjúÕgs™ç¦ZÖÌêOÊ,”ƒ;=è°‰N&–†2]þdìWã6^dwX`®¡3¶Ü¹³º:gš"ÏK«ÇñxNw Òº{v¶ÿ tåæ¿|]åà”BfÑ6]Z¢Š@ïÇO¤7‰!w¬ãŠ-ìíßZxC[–dd£Ç
+Ö2°Áe•ªÈ·…µ‰	&ÖBjBy3$ŠÙMÕJa 	Žr&};)+óPAˆÀ]æóùÙXÑhÛÛªêÉ?xÇ26Dh犴€ê ›³ãß¿±rÍ’Ì[â°öV±½ÆäÚÛÔšvàçºN i4#‡CO“+º3—¹Stª8YEÎ	”˜S™C_zBÈà
+úÅ‘ãlm©k@¼OOjùÑï/y{©Wxtqú€q额ŠjÛ§MêJ€ô'T€}½ÞåIjuíH©-N½‰ üÃ¥IjuH-M;ª@>ß.=iÕ ž•B at 8R-N§Â<õ%©Ô+ÃÃS¥:¯^ø4Oz֏;í¢<íӯ̽ûûóšý­yúÄ‹ï]û£Šýmú,ðìvŒkS[ŽÀñ_…+ÄŠn%C½¦́âÈ·Wîg)þíø{úœ+òÓ˜_¿ÙÊ{âóõ™Aë^E¨T…`0…¨=*à~झ;ÀÀ4"§­X!Þ(Ÿ¥p?=NžÄҐ­•:@å$×H‹¶rTÕ.ò`»7);js—A&G(N_öiï¼a¬fZÉ×Ö/¼%¥Z~‘þ~#ëY<>Cûºý—ÿ eZ<v´ôþ‘ô…èž:pÕ{-û{Ùµñø€‹ÛjiBã¶)V#èy(ÇEY‹¦ž‘B·U™ ºP
+>v½¸{²¶¹´uµÄdøÂŽd”á¨8P‡MAÀÚ½§¹³A3dà°á^#‡FžÂg3Gâá2psr°ÉâÆŽ•…”Û÷
+2‘©‰œöb %ñ€4¬t–°ÎíE¿œm%Žÿ Úiñ”‰#ûTw„>°j"JJP¢vë@Y%)SQWŒ$ Ü
+J&ûhùˆ
+ª˜5¤(&”¾é0£›wrÃZ!k‡¥Í¯¥qºâÕü%¶ŒŸôjßè4üK‹O½HƼÇì^·tA"Åe~ܐN@0
+ñ#n”GT'(rdíáÊ襵è«Oõ¡ßåë\“ýx_à#ü…r¸'%dÕ˜îA»tÎo"¡H EJnª :Žð€	®¼µÕ¹Šÿ YuÎF>ôŠP[šWüŠ»û Í[’ߦCÇësF®]ÃØXP	§¡Dª->õa0‘C¦}¼…ÝÔ@L‡–(ÇûLÁ=‚&Ž‘Û_誦]BÑHì¢I{ŠÞûp³–¤hþÛ‚D¥T“8dÞ &/)^¼2¢U
+chœµÒ‘¸ØçÌË«‡pûRÔÿ ám8.Ôwwã„FGú,ñš­í½°ÑáÁ[Žz^qN]QU낶ÔâQM‚GM±SÓ“Mšº’e¦„hÅÛÁnÎÐÖêáÚóWWëRèß3ëu#äãÖISzÔ»’ҍbÙªiÇ1'Úvi‰)L¢€A(ï)ºDÌaè<£ ~´¬ÅÍIJ—\ÉWR¦§ x8žµ²aÃc5kG`<;?Ëô.Ûe¶âe„L_ìôÝ( sŽš€Duæ­N[¦j$ž+`û¼’4
+VBâ:z>’z8u¬Eâû Ââë=7ʼE{¶u³ÈË&8§Ij“¤Á;†ër™4›52mª%ÿ vqÉïLcÔù_ˆ½Ü9?¹BÇ7LJ\?¨éã5ë5¬Žh?Õmx€«ºnáÂØÙÈ3DMí'†¡×N zÅHà¼7:çYE9„Ê*s(sˆ‰ŽqG^QÔF¾Ïclc@ }|èù#Ì’q{‰$ý'ŠÔÏËOObš«ù‡¨i§T€~z)Õ ˜jKSªPSž•
+uH
+mÒ—…4€~१±:­É¬´‹4¶g"õ«g¤Þ7nítv˜éŠnRMBr
+jº40‡†ºòÚÛÌöÉ4ltŒ5i-´ôÔ8€xv.V\M\ÈÞæ±Ãˆ€|4à~µóùêËTUe÷|GÃñ˜G"Ù,n[b%l{gÙnãæjÝó£Ûñ~€ÿ ·,Kçm–v~RÇ1Ê(w«ÉùKËÛ½´þ̾Þæè_Ïp×FZÞõú›Mmihé p=oüÂÞû»pÿ {ã[<Ha-yÇ»n—WCˆ-=@ŸX”
+WªñZ
+~µ¸-&ýÚ-[º|íÓv$2lpåe‘f™€€b5MC˜È`H  P Ðæ
+áe½¼Ot‘1¬‘æ®  \{IIéí\¯šYÖHç´PIÁÙÑÔ€ê÷+µER‚}ªªÛPZR‚œô¨z“ªÜ˜ËHÇ
+†zÄ˳XYº]°¬Ÿ³PQ:b¡5ð¡]y­­î ±àM¡í‹–9憦'9•hH¨ì4_8)ÕÑ\ºj¢«ïNIé*À•ŠêeÙ‘Â¥j²¤ÝÜUVÅ8"¢…Ü
+%
+š¸m	”Næ7¿h u ;éjäÈbpˆš‘SB{HèFšÆLå:g2jÅ9S	LC”u)Š`˜¢€÷ÀjœÀàZáV”ƒˆ5#ð¯©Ã×/;—ŽváQUÕT]uD
+QULcœ@¥ åðWp²áhlc    8*|‘Åò8¹ç¤“R~µR©·ÇUNÔª¾öR/#Ö:bà
+bìÜ*Ù`!ƒCDäP
+ok ×ÖðÜ3»|}Ž Àx.Hæ–k‰ÎkûA þ$}©Œ"cxÆ1Œ#©„G”DDyDDj´ (85©©é_z’oœ Ý«‡®ÖlÐ
+[,áelÓx¢s™4@Ú» é\
+¶†7ºXØÑ#þÑ ï	OÖ¹]4¯cc{œæ7 h<«êB
+Ué§BŠ¥6øûµ©§juL
+t‡”)Rªª”ëè©-@)J¦Ú‚ÕUJ
+TЧU÷šIê­b£ÇJ1ns(Ý™Ü*f¨(q9Žt[˜âŠG9”0ˆ@DL<ã\"[)œ1¢w
+ 5Á=' uõÊfÆ"sÝ€I ðŽ´ESn5zAQT §pT–¦
+ûÍ ñVÈ2QÛ•¶1ÌÝ¡×Tí›™CêaI#(c˜J¨ˆë\Þ&ÈéšÆ‰]ÒàM:*zM>•Êe‘̹ÎîÛÐ+P+ÓAÐ>¤ESn•T*j˜ëè©N«1±þLá†W[vNb±²E¥uZN'K%àp´ž¾ ç¦ìÑ>é^9	ÅveIªä\û©¡¸*
+¾GžÛ|˵ܗ9­¡}Ž»Åݶ2lòx1[IK{ËWBXRç´´UÄšý>‹‰ÍlkŒ$8½Çk{on^͏r;$5ÑpÙKC´Òpq൫qž-ü®\oeãëfJÑÄønØqkXQS¯Ñ‘¹übá“—Æá™Iœ¼ã–¨™T›’ §¨ÛÚ¿Ë͍µŽG3Ÿ¹Žïuf.D×O‰¥·@-Šƒ¼sAÎ
+s¨ã^N==纬óâˈöûŠHà騂ù$#Åy¡¼:Mxc™$ž‘¢ŒñÉXª ,«2¸T­X74UFà~Äê &_|%×Þ‡0W¡:Þ(œ±½ø Ô`=4âxW­i¢if 物4'¶ATÛã«¡QT §WE*&
+b©Ð>íIju_z²œ ƒW®Ù° 6l»••A¸w@Hç2i 4÷ •×m¬½ÒÆÆ6Gt 'ÂGõ®gO3Ø#{œæ7 h< }HJ²Õ_s™ÕŸ<rõ`(&
+»]W
+îD@€¢Æ9÷J&]ZአnˆXÖ2µ£@ðÉ$ÒJíS9Îu:I'ñ”eS«Êtªš¥:ú*KSªR©¶ µ:¯¹iŽˆÝ7NܸMª`‹R,áUHÙ ”@ŠÀŠ`R n—@К¸oNs¢cZ縀'´Ó¤ñé+•ÓI 
+{‹šÑ@	&ƒ°W£êF
+tj袩Š¦Ý6
+*UJ
+wIjuJ
+m©-N©Nª‚Ôê˜è%M
+u_aß9]4YÊë$Ø¢FÉ,ªŠ&܆ÂTŠa Ô 
+q¶˜ç=k^ãÄ€'é#§ë\Ž’G´5î%­èôx;AÚ¨"ÕgNTjÜL-Û(º§n€˜DL(¢c
+i	„G]Ð
+u¨ðµæV5¢GtO„ô”̲9‚79Æ1Ð	4ÔŒªmª-ST §UIjuJ
+t
+MN«ì+÷^è^”àö½·¢
+Êz7m¦ïmØov]®ï&öšé\]Ì]ç|XÞú”ÕAZvW¦ŸBäïdîû­Gº­iSJöÓ¢«Bª%Ð@C”¾TZ§R@Ó¡}K<píc¸tág+©»Ú,áS¬±÷
+.úŠ˜Ç6é
+  •ÄÈc‰‚8šè  _@áÒ­ò>GÈKžzI5?„ª‚ŸÖËRªPSnµ¢*¾Åºpš¸tådš”HÙ%—UT›Û b C˜J‰L. P äjâd1Fç=Œh{\@ ŸoIéí\®–G´5î%­è’ƒ³êT:êèU 9é§T ¥AjuHÛ§wŠ¤µURœþJšŠ¥*œÃÕKRè¥zª@?0÷tT–§^Ô€~z‚ÔÁìHæÔêÏä©¥:HSó
+êJ€ô"«Ù.ÓÞ´£‹1Ôv¶K½_˜Ûû†úÍ~Ö¼ýbE÷ÆÎýÑÅ~ͶýzöA³ÅZVÇÅNÈ6x¨ª8¯Á灧<L7Y˜?þƹ+÷;”ô§lÃØïÔá_–|ÂýþÎ~ؼýfEÚˆW¡-BªÀ~zZQÁ\á©¡G[ZTN¥X?×I
+¸»¿B|z•ÀÀ4"½«tƒxú2u´Ät™Ø9Ñlà‡2‚ÙÁP0'8‚gÊ™ýî∘7„½˜	´}φn‡ßÃ¨Ï x´8ž¾°EzÍ7·—kšÜmË´¸³qÿ Pÿ öbΫNñ{¢wwÏ{$Ìdh‰Ä¥3Æ‹öošœ¢"LÂ;ºk¥y¶ñHÓ5››+	áN£ØGQú?ßxÝÌ;z×y8qA’,£—)Bz0	fÝ`íUfE@5³‚é„Å1“0xy£lë¹ÜmݸõžŸé<!Ç(ýGþßJê[¯3A¦«¦¬W’
+Æꜥ:Z81H#é$eYEÔO©4Þˆ€xhÆàîÝR1ºúˆè¯WPükq<zªËñŽIƒº¢E(S¸p«RÏË(€8? ¬*ªŸb¡DÊ JnN`ÖºYlMÄ2‰nhè¡êìê(‰í{tµw{	 °
+©©º@PL)”Êî“tJR‚‚% ä×”{ÁZÅÅ«
+h[SNž~Ûh}Rç1‰ªéÂ[âe Éö`ê œ‚™„‡
+Âh`éáku¢(Í(
+kø+^=~ÜdLw+³¢£‰Úf€„T
+äÈS(QT¥Ox@y3A ðˆ V±u9Óã:Ž"¼G?Zï².>(]ßn4ì•!• &Fè'|¢á}Ӂ€9ÒoÈ#Èÿ eh¹)5´†š—;ñŒÿ BØñO0ÈñâøúzÑ—³‘…ì—÷•âèˆv¬á Z¨CK\Ó—jœ[‡A9D¦.§û“tµ9Ä  “mmŒ®çʳ‹i×À¾B˜™Zj?I?e¿iÇ£…HÌÞä­m,ߐ!¶ÂºYZ8šŸìŽ©Àt4_Ì·–®ÌÍ{J^÷k;ÇÆ*,c[¨¡£`â1ý"13èlÑ5SPÆPÚ	·K÷–ÏÚvG2É´-s¿¬ç´ç·8ñ> …óVéÜsî,ƒ®OpŠ?îê phêI+­@áÑ[QjÖkؐ54N½©Nz\Sð$)ù‡ª—U œ<T´¦Ì5%½©Õ ž¤µ:®]bÙ—>I¼m›ʍøêí¼&˜[ÖäO¦ÇÇ|c1&¹1iéÒÎØF´í×PÚ.²I]L`ZÄæòøÝ»‰¹Îæ$îqvºY_¥ïÑ\í,kžêÐÖ¸ž W½Ìä!Åc™Þ_ÜHØãmZÝOq£F§´Tõ¸€:ÊܲF:¾1
+ïpcŒ“n¼µo[YÙXÎA½Q¢ê´YVè»nt°pî=û7lÜ&²¬³uÑPª&sÀ#Á··uá Ü;zá—X{–jŽF‡ à	i«\æ¹®®kÚ×5ÀµÀBæÌaò{'.1 É@í/c¨H$(ZK\ µÍ%®H ­âàÄYÔÆØó/O[ށŽò«‹¥…püoëãçlª°—"³“s9ñl¢&KW­›m7’“CWVÃvmì¦á¿Ú–7óø¶Â똴HÞè\0I	Öæß­„;óo~ž‡i<=ÞßËØa­3÷pèÄ_kaÖaqdž q{t¸SÇkkÒÚŽ+® ýÁ[•‡ªû™¶xý^Á‹W/—Ü:‚‹Tp°&˜j¢š$9÷¢:h\I
+×;šÆV•q Tô
+žW$qÉ+´ÆÒçtÐM>¥Ø¶î#È·V7ÈYvÞôì{ŠÜ[-/Û‡ãx&¿¸¼eS„¶Óø©ä›iÉOŒdÖ*Z²là¨ë¼¨ššµì†êÛø½Ãaµ/®4gòm™ÖÑwrô[°É)ÖÖÙ¡€ŸÎ=…Ý
+Ôx,½ž1}†»ÏÚůbcÉ©ƒA™Ú#ñKƒÝ©Ä®§K¨8®¹6ÖÃ¥aêê¥áN©NºTª@Sn5%ªª”Ü%©ÕvÎ"Âyc;Ü*ÚؒȘ½f7’­c¢ˆ˜¤y9;*å„5Q)UxåÌpÝä­Wuï-­²,Ou^Ãghçin­N|ŽþÌq°:I\ØØâ(³Ø
+µžÝ7fÇk%ÍÀvš°v½î-cÒ÷4ÁwBà‰<mjÉß2ö39ûBÆ%Á?`]¶–Ain™2Š‹}½¡5/#ݺA¾¢ë¢Fé”Cy@­KÎ~^n,¤x[K×Á–œ~j+¨'µtµà;£<q²BO Ö¸¸ž†•°å¹i¼°Ö/ÉÜZ¶\|_í±N#íÖ!{ÜÀç44u•Š ¦ÝzkÔh‡T §HyB‘mSªûŽÙâ-›¼U«”Ù»A«³ ©9N)¬
+×1A%…†é·DwGk€Iät,sL̦¦ÔUµâ*:Ez«Ò¹$k…®º´444é¡è4ë]…“1>BÃs1þH€û9/;kÃ^qLþ5„—ô«jà*戒íàd¥¡é…lìT9'»ïÈ]C\ÛÝ8
+ßg-þÞŸï\Én÷h’=3ENñ”•ŒqÓQã ZkÁÅeóx¾Ý¹ŽÓ3sq,™£[X䮇UŽp¡àHpëuè)ÏYú°õJU6ëÓJ©Õ()ÒP©ÓTê»/*bœƒ„oYw“íÿ ³7ŒKxçRá+	3èèJ±BE‚Ÿ[òRÑJö윐ús	uÐÀ ×6ÆèÀï<4{ƒmO÷œD®{[&‰#©c‹4ÊÆ<QÀŽ-éVg;Ë휓ðù¸»ŒŒa¥ÌÔÇÐ9¡Íñ£sšj<i×ÅuñTÛã¬ñjÄÕ()SBR‚½t©ÚŠ¥*›téïRÓUUL
+wAj`¥*›jSªR©ÕJ…0R‚u4N©J¦ß"Ú§T §UAjª¥*u©Õ}É ìí•x›ghÈšîŠŠ‡lŠŠdUp(¤™Ô÷ ">
+ât‘¶AœÞõ¡µ t:M d…†@Òc$Âz—j
+e[¸²ìcþoæ©ÙkHÕ½ÿ 9f⧋l¿eèƒ-é°Ý„áÁÒA6¨Ÿ]ò˜S÷õ¬é¶FC)Š7?ïøh5ã{¹3âïší]Þ™+H‹Ü:à³£lgM†@Aþç“•ÑÛ;\œ{$îœÚkÔÊ?Ŭ€ô‚GÆo‹2èÆ×tõ‰zÆ|Mu[/9é±ò"ÉéMS£éÑ.ßG9Њw‘YBr÷ûõ“Âæ1›s
+'}‹¹f¸ß¥ìÔÒH®—µ¯oÐæƒô.†S}…ÈKŠÉÇÝ_Àý/n¦»Kºi©…Í?Q!oVV1¾òEó;gÁüm­µnëÑ×ÆpÑÿ ÛȘåVC°”dâGtSìšuÇNBWK3¹px»+¼ýÕÖFàAnÝ;¼”ÒŒ«àΟ´òÖý+³ŒÁås÷WXè»È,¡2Ìu1º#.£œÒïô-è˜['šÝÅ×`[:Ûù¢vBÛÆ’[Áö–j*t¶Ëö^‹ñ·¦Ãöf;GéµHß唟¾®™Þ[hd2x¯¼ÿ ¿á d׌îåüÌo‹¾kµhÓ%cñ©{‡AÜdmœá³°¿î?Ý2rº;gkódÛ›Mz™Gøµ4Hⶺ¼¬;ºâ±.˜7.»MÂÍ®(”g.1Š·"J.*½…s!ª)ro*šÇH7ƒßWžÄg16ùÌdí“tÐbyX51àš ðè]<Ž#%ŠÈMŠ¿‰Ì¿·q0ý$Rµs›AQÄ>•ÄNò…e¨>©AN¾ŠE¨)TÛã¨-UT ¥F”ê˜è Ò¡N©J¦Ý:{Ô¨ªPS¸*KS)TÛ­AjuJU:ªtªªR©×Ñß©N©Š®ß*ê”ê©-N©J§]AjuHU6éîT–§TÀ§?Œ*S±)TÛã¥@RU%©Õ()×RZR•Mº{•ªª”çåè¥B€R‚›z‡Ü¥@R‚•:UU )¶¤µ:¤:º*SªPS jiDê‚›téîÒ—…:¥)P"© üÃRZª© üõ%©‚”§æ¡¨-N©NR¡M ˜u¥Ã­J¥§±:¤ó
+IjuíHç©ÒRù‡¨jKSªö§‚’kgD<sèÕ¢=êüÃßß¿y¯Úן¬H¾úÙ¿º¯Ù¶ß¡bÏ®Ïo“üu©-‘NÏo“üt!~8¶ä⯉ æâ3ÿ ¬{’¿sùGÿ JvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXù^„´õ(B”!j!ᢁ:«ùêt£‚°¼4ˆG[ZTN½ªàqå
+¼!§„<4ˆ¨¡èLS¤p+¶­|«-ÞM³yø–d90‘t«c²¾+’(c•@ûÛ…9LÛtæ(”¡Ê>c¸v$où<%bæ¯c@ ž²À:½`ïìšð^‡ƒÝÕ‰¶“­l‡¤v‘OíqÚkwO;×hšš¤¹
+›¨ÙTõU3h ‚ɐåSAÐÉŸt€~M5
+Ö!Ɲ_ž-ï¼Axx´ÉG6±qŒñ`ŽÐGá[#Û¾×–J¹\¤IdÊ£èõ‘?¢©Ê%MRoêˆ8ßÝy`0w´×?n'ŒªH¨¯ÀV:HK N’?Ê8JÞ-X%'n,xÙ‹’*œe®” H•DÔí&lALtÜ´ÿ  wDj/¯73áû–:ÊÞJ´ñ‘Í¥< õ.{hqÅÚîe{hGÙþú}k'¡x¤ÆNx[^'$M'Ô}t©»ù2ƒ6.•f`ÈÐÚ9
+Š‰€¤ÓQ8€V¥6ÖÎÆ6AöM–Ytµ	 ¸‡×‡
+p4ú|Íe+¤6½èdm©ïMOÑ¥eÊVÖBq7Òeš1’ŠE¸k,À[8,’(r²¾»WmÄŠDå0€è;£È:†âÁßcå6·ZËkPê‚Úñ­ý¾š.Í´Í{u
+R½Bœ~µ‘ñ×)IÙ©	•8‚d0©¼'Ý ÔJ‚]©ÌpOÃÈ=þýh÷‚jâê0q<?Êh)U’d§€ë+„äþ$­;£™©ÌÜ*öƒdÄ8KÓTTûÆ+Ë•Ñd #
+m4"Æː»©#˼¬Å¿ÜׂÚÊ72ÔS\îi ‚؁§xÿ ô¸DÓÅÏ4Ò{<-±»È=¿è°'³W`ÿ DUç¨ÅxÍ—3ã™.÷—eß*«õÎS4‹fBú<d$IT1ÑŒ‡)Œ›Ú
+¦2®
+õ:¤ú«ilÜVÒ°m¥Œa®­I®¢\Eœâ*çÓ@ŠÐOŽnM×}Ÿ˜êqÝC¢ t
+
+hêhð’Jêð70ÖßÀ­R½© üü´‹SW‡€t©!Hš’Ôꮎš’ÔÁ) ãJ‰Ô$óÒO… m*Š¬®àdúñ‰Ã@Ó5‡ÿ .´¯/çPÿ ”›öEÏèÜ·®YÔ,7í?×Ñî1"Xq¦Ÿ3Vû‰q)ÁŽQÊöíÅB$ë(pב.VpS” gSؽ"v.7=ñÚ‰ŒsW-Q'Ï|¥ºŸ“ÎÛ¶wïyåÞïÆYKŽ5yy-at±¹ßÕŠðL¯ ú ØåyöaA1ÆbæՍÇn_]G#ÀÜã™q cÀë}·C©ÒÚ’KžÆŒyÏ	&ëÙËìèl³¤¤êëâUº]v¾ŠÍ5²Ü‚gtç°Me½¹M¾}Âû : %oÛ!΋ù‚æŒkžæÚâki©ÄX´é Tô
++ÒBÔ·CCùA´\×O‘5 ­Ó¸šh:M+•Â⎏qÆXV&!âɘ«
+sq	`9qœ¤‚,‹3!jY¨XÏpŽŽê2n
+°†!Ž© ª©‹¼Ýæn>Læo-µöåõ$|8» $±¥ÝÛg¸7-ñä
+âèZ[BkMZÞõ¾–†ñ˜¬^?=™µ«%ü±šœ·E„ø¬'¢GPA.qÈ®0̓Ã?´=àÛ€×U×pÚ64áì+™“è¸Ö²¦,bÝ“(\ñ¢ÕÁÞO¿·®´›ªÝDQAʘɉNB@æþðÎóØ=éc÷[[»Øþóš÷»ïÜ÷˜_¨ÄÙb˜¸<9Îc˜ªÒNÝ˝¹ŠÙœØÊ훳<÷vöÏî$k[ܾõâFÐÕîŽHÃKHÁäŠAâ</}pÕÆŽq°‘É6ô^&ŸÁqͱpÝQïÊ£ÖçÉ{–2%›iç	UÕftE·a¼A0”uö‹Í×»ðœÅÙû/8qÓÜå`ɹ¢…Í£­à|±}ß[Üb‰µê¡èªó;lÜÉìÝǹ±bö,%²ñÉ+]âÍ+#“¾ÒÐzKÓ§‡MÉÄ¿
+ݱ8~K|{1aq7`Ø6%Ã"ÚRYªç~¿1gÈÈ0`Éd¡§W@«ˆêˆ¹*c©Šjîrç˜Ù–<íõÜCœÛw×Q]÷L,a‚™cŒsœC$Œ8´—xÚ¸[yìË;,¶%»S½“šµ‚Kq#ƒœ%‘ÝÛâsšÖ‚æ<¶´5S¤rü`ÅxˆÎöÜeÓ~6áû„Ûöe¹¢Íp^÷eúéM{BÇDY%'/;é胤#eã–)÷÷ÊpЭ9Ž[°0y›[oÍÓ{+qð¿\VÐ[4ðžäê/{#L®Ðæ—¶VJ¶ËŽ[m‡n쥜Ý7iàm˜ë¹¦I¥œŽ1B4†µÏ~¨Û¨×FàkPVÅ€8qâZØÉјÄÍxg.ã›2fÿ ¶ar<ãK®ÔÊ6íµÙ©3/ÂÍ»zªÝb²$QV¢:ê& éw¯·×0yu’ÆÜï‹ì6_jd/#µšKHÝörÍQô÷’	mÁ=Äôtî­®ÔÙûÎÊö
+­k’ÇgìíŸ<l¸x–+˜ãûmÕ¡†9ˆ#H·Â*[æ(5ô•‰Õ )·J<)¯P3LìŽà…Ìib¹VœH’þÊyŠV8þŠòî,L´\e©n>tÊБñ40öY± ï_šöu•¾õçžæÜy¶‰ŽÞ6¶VŒØ5±ïžV´ð9í:^<`׸p£W¶nK™¶Ï*ðx\[ŒC3ßÜݹ¼ºÖňâXÖ‘VôÐxÔ¬`á0ÝXgˆ<cqÛr’c'wÛöÍßUL1·UŸpÊ6ˆŸ–bsú‚.#Þ¨d;rœ¨:*k é”CÒ¹±´±›¿ad±ùÚfŽÒY ’ž<ÄÂø¥c¾ÓHs at v’˜\ÃÁÅi<¾Ü7ûsvÙ^Y½Â7ÜG¬¯‹,R81ìxèp-'N tºŽ@Y•‘øFÅ̯¿i ’ÑÈðîÎîÆQ[³ˆ`KÙË™rCÈ5Y‚껍ˆdé&è&E1
+—)Í߯!ÛÜÖÜÓa9x\b‘ûòÁxù]#¸÷Œpp
+|Žî$8ô虍ƒ‹)¼@ïÜCc–Ù¬ 1½ñ/ÐàZIkC@R%c/BËÊ8W‹;þäZl“¸NÀ¶.k8‘›µ`¬Œ¼¬³7ešn³'*½l²&áSQ×ߺ¤oíç˜Û;Çk`±Âe™¿š‚ö’àÈØÇ7»!À4ÕƤ‡upZVÑÛ8ÜÞÛÏå¯L‚ëi‘ip
+.{œ°AÔ( !fOÒ¸(þÎ>þ+µ²:=S1#Œîå„Y8;…®D_¯.ò¥™¦bå_‘ÑãRl-Ôj’‰•S(%0‘röÛ{æv}æëæ0XÍ0È‘:×ýÙ°Uç»{ Lçê!Å¡ Šz.ñŸkžOmþâÀç±mYtH.?>eñ¶¹ÚŒaºKAÄЮkÄf#¸¿Ã6;éáµ-n±Í÷î·j[v=¯4¼¼Š
+‡Þªåg.µKP1H£‚œÅ1J%?/·Øåï)³¨ ûÖZmÛwmkt‰®ftb6Ô yè$0´MFGxmOŒy…ŽÆK/qo[Ïq-+ÝÃ^^à:É%­4.‚CcŒYÁo÷T¦ÂÑyŸäçQ¼Kx_·U¿r at d)kz)äÇÄפ(v#k++ª‰(És!)„ÂsÖÞ7çç-qqo=ã.%¶Û,M¾‚Úa–Õ’½±÷–ò:GwÁsA4T@LŒÕpø.[ï{÷흷JË6èä6²Ï,rGpøÚ_¢f7º.kI†ƒj at c¸0À˜žÈÁRÜHq8…òú!ÎA{Œ1Æ*²_Ç@L]·4+wÜR7Âý¤ÃÛq*´]±…»I@Á¨ï&U3Û—|îœÖ÷‹—œ¶u“.Û`Û˻ۆ¾Xà†BLŠ&¹äÏkƧiÐáØâÜNjàq›^Mã½EÓ­ÍÙ¶·µ…Ícå‘€™$ŽÑsN‘«SOh²Ö÷/Íx áÈoX{j÷Kå<i}ÈGNÉÙ3’‘}1	q0i2ÖÄ€8I 2évþ±yCuB¶®òݸíøîZsîsd¥²7VW–Ì|L¸®-’9"sŸ¢fQΣ]§KOkK§?¶víæÓn÷Ùÿ yŽÊ;¡oum;š÷B÷ æ=’47\n¨oŒ5j?A=øÝáÚáâ“2ñdfì¾쨜{¼„:)Û“nå,xp°qÚNÒU²\8.ŽßªQjÌ…0êUN‡†òc˜7˜þYáöÈŽÎ`ÞKtðÉ	î,à2jº»- †þÎ&r(8´?Õ9›³í¯7ÎGvî‡Ém³í£·is ïneîY¦pA'í¼,¯C‹|DŸ}önQÕ·êw«)þP&ßGG‰´lÙì¸1Œ$‹²&Ú,VÈçÔJ™B‡Ùö^CeY[5ûX’5Û^î²Øõ?CIèi{ˆ.'‰ù–îKi.^û8Ý©qÐÇ;[šÞ _¥º:N–‚zµ‚›té®ÑjàªÍ°f7˜Åy#‰õ%u·Äxêj΋¶ìCÇ6ºò@™+gI at 2”•E˘بçH¸|¡“íL‚Â)¦&†ñÝý½w¦çÇrócGjíא†K‡Ís¬ÁkkZesC¤{Þ×21]!ÍñáéGká®0W›Ëu>àmû9cƒH–âwЈÜXÖ´‡<ÒºOŠAw[‚ÅáŸ0Y‘²|=žîÇy}[öÖ²R—ýÑu'yµ¼$P…Š˜²nñQoEãGiä“t©Æ&€@:Ö¾cí,Ä–ÛøZd6˜±šàäma|ÜÀÃ#㸈½íÒæ5ÝÛ˜j\ 5¯‹ÏwŠÙ[‡ÉöÞ,÷	»Šg<­”L&pc_5kˆÖפtqíkãð+ƒò)°CG5^W,2ñðy3Û7-«r<A²¯ÍkÙNa$+oÐ&ëÒÕ:ûÉ*	‚¢Õ𻃝ÛÓoüw€vÏ3_%¦>he’I¡i!½õÀ‘š$”6¬ÐÐÚê-©¦{)‡ånÙÌ|'˜+›ØËYqy‘±‘H at .î¡,v¦GZ;Q.àêp[õ‘Àݍ	œ8£ÅY¦ë¸SÜ9NÞ¾ífèW0h!)t9<tÛA¾1ÜG"ºfQÒ'D‹é¡Ç£šçfn÷emÑ³­mÝ‘Ìæ"²–Úbh$%ì’Ëâ÷dÈÐ+š@cƒË:—gÊü]¶çÎ`w-ÄͲÆcdºŽx€âÀæJYÇ]â]p«šZÖ¾kCðm™ñRɶ™³^*áæJÒ{|«7#oßsõ™u-&Ê58¦-cá£-ëÒZFD9ãXB™nÙ3	‘åËooìýÛŒÛyOîl¥ÆàŽvÛÙ-´v·†9åîs¤|¶ñ²@ãÀM 3C…ý·ËÉ·¯³vÞváߧ/ts¾xe.kt´5Žg¹…£‰„ÕÚšjÞ¼É8—Ýü1/Ävˆ¿,ulì¢Ó^vmïqÇÝhÈ5’†FN2牗g¢.̳´RY¸“³ã‰J at H¦_?·wVøÄó)¼¼ÞÒØÞ¶óëË{‹had…†HÜ÷‚Ú5ů­x6¤ê!˜|ÖßÚِw–ÖŽêÔÛ_i¡žFÊÀæÊdž´ƒR›Jq4H.í,µ‰x3áѦq{Cfl…rdì/`dö”5Ñ	oD@–áM÷Æ—®aVzùY¨‰¤R VJwí’ë;Wusƒ˜2憛Çcs7V­žHd–I{¢ÝwB@Ö†´‡K1$¸ÈÑcC«œÏíþ[ìèñ¯ÉÇ’¼¼¾ÆÁ;¢d¬‘÷Ú¤ï	%ÄÇn‡¼êm8%ÿ Ã.°³¶2e=–%­Î²Ö?‹Ë–Ýû#é·r¤›NS´×kå˜Ýæ|Ý6Ý¿¢ú:	¹"ª&cèŽs̝åØù)¬qQ\s~û­Xý0Øæƒ8sÞÜi%úuëqcš× CÖ+-²6Ö+uXÅu$;'!hÛ¸çsuJ"sIÖ‘Þ꺴éhpq‚ÕÜØˇÄ\Œƒ°w¸±ûû~qþ?Ë÷Œ€MZR’‘ê?Fïdkb2=¬â)w™½íNR¦p­?rs}òúÞ<î7·2Gqn¬-ÙÝÎÆHàטß>Gº2ø‘ýK‡
+-	³6žñ™øœF/5a+á{ »™Úâs˜Ò扛Ý5úé ¾¼)…öwgC]¶Ö@‘E¥ýe¥â†b¤´û‰òšÎumÜ[€‹Žb£2?I~ÙG
+&¨¦bŠãßvÛÍÿ Ìbnl#{ì.
+¯yŽˆEþðÙ´¼k{Ü$1é
+¡ÀÐדi϶YÉì¡ÈAvö¶î>‰Ýr?2b«N–µ¥áÕ.!Ô"¡u}©‰­»ZÂö|å¨÷÷
+×RÍ“-n/å
+æßfŸ˜™BÆ`5LÑÊ8jˆÀŠªvªêo{Þ­›)º²9<îþÚ··ìf7Dæ²’¸ÜX:G÷¯Ôu€ãFpG+a·ì¬q;G?æ7·ù7‰çV1ÜÞ5ÐÚx¤ãq5<x.óâ%§x¶¿¬\„Ë/ËÝW½úÞ>èȐÓpVõ¹ŽeçSbÙ’0¶ã˜É'7oIHd];T»Æ"‚‚&)JÒ9}/8!åM†so¿2ÊĺI#–Y®ãˆ¸¸É0{.“K»¦1§h‘à’FѼcå¼¼Á»Åf‘’þêì6[†=‘Çn÷é
+ŒµÆF²£¼sÈ⡤^—„á>:ÖžãjȽ&g•—áóH\¶ÓÈ'åŠe<'D$àN²;gFrÂFÓuŽØ]Ã(%ŽšÖå{ÍKŒ†ÌÍaá€ZgòL†fÊÝnŠ‡D­‰À¶Žd{Cèj :GBÖmv6{Ÿ’’Sqˆ²t‘–;Cdá©…í¡«\ÂÒ[QJÒ«›OÂ3ºxSök[*»A…Ë–2´å˜,
+Ÿ$Î_4„s¥Y¸(
+ÝϺmÀƒ¦•†±¾—Í.cdíÃöØ«Z*ÒèñÚÚ8U¤Ž"¢£‚Ê]ÚÇ°vUŒÅ²Q¸´ÑÀ>óI-<hhxp+½¸u´1&+â'Ž,v£öeKKå&Å”^âYWxѪvqZ0ª©w½|º&jô@¤™S¤aÑù…–Ý{£—Û'pµö¶ï3dtžo	¸îž }
+hp|mÄ‚(¶ŽÛØãº0Å—r:ßt5I¶ÏxÓVÔÌçéÙ ZVIâ|]xðá‘3^+ovÇKã\ÂÊà·®f2âË^+2eáØƳ)f	>`b±Ê ŠÝ™Ž èíöÛ§sâ9‰Ù›¡Ö’Zd±’)bc£Õ{nA¸¡Ïwæû¯Î4µ¥y\û’Ù—›ŸÛ†\YdZÉ#‘áôµ˜R-oÞx„ý“BhϐñŸŽømÂwÔš³–³ÍÏp¶3ÖáŒ`”<L{…cHЖF~ID\¶\ÎC¶íÙïRööþìËîbæ°–Â…pðÃ~“ÞIy(Öðªš"`sÐÐCôT<zٍ»ŽÃì¼fRs'Ä)e4¸he´~#Im+ªG渺…µ¨áŒ ¦Ýz{õé”Z5R•Mºt÷©P'T §pT–§T¥SmAjuJU:º*t”ê˜èv’uJU6øêh
+uJ
+uT–§T §]Ajª¥*›t÷*KSªPS¸?¢•±1TÛãïԐª@Sª¤µ:¥:êKSªR©Ì:t÷ªJuJ
+wôRLÄÅSn¾í*êê©-N©ANº‚ÕUJU6é°{Õ%©Õ()Ü)ƒØ”ªm×Ý¥@RT‹SªPS® µ:¤*›t÷*KSªPS¯¢¦…:¥*›z†—…:¥9éiìN© üÃRZRùêSª@S˜uéîÖ¤µ:¥:¼´¸§T€¦ÝipB@=-)Õ{}Á!5²¡G¿¬dxøÙ 5ù}¿ÿ 3µï?X‘}û³t1_³m¿@şݘÿ µ%j_ZÙìÇý¨y(úп<\rq[Äàõš?ÖEË_¹Ü£ÿ ¥;cþÇ~§
+ü²æïösöÅçë2,z¯BZz”!J¥R„)B a
+(ª¸ž§J8+€‡€iQBû¼QL›w%!NB&íܐ…P	ö¥1’k¨îˆj<µˆÈáqù1[†R_í´éwá>P²ØìÞCÝŸù¯ì»‹èðŠ»6™b‰»u bÜ;(n&à‰‘ŠÆ@4IÊÉ7\®Ì:iª©ºhQÓZÔîöŽAŸþŽã¼‹û/¯ýãýU¸Zo	(/!1¿¬¶„~êñ–øÑk¢Û îÁš©é
+h3‘Ëöʱ3g­ÓQ1!ûBHMÒ”7@§(ã~á¹-ÜDðЯGhý}=«/W0;†4v;SúW-€`AI¤ñ“õ¶>ógL1Èö­Ôm_ÊÀ¢# €d÷ˆb¢q
+áFì‘i}¬†Vôè §ej¹¼qLq,»„ÓãµwÄW–µƒÚ߶;œ+u..”AFd]Ã¥Žªª9QÊ¥XÇL M0&á@ F±_ç2—âñÙ=¤p€vqð©“qàí¡“ŽÆµÇ†”ükƒÎqS~ÉÊqÀ„88“}º®
+¢i]äˆdTCB˜Cw„Á  ¹ûN\Ø Ó~í`t€4è©p=€¼Þï.:-'ûN<~¦´ÿ ”ø:ÈJ¿•r£·î”r²ªS˜Ú{EGyC!L¡¹L ˜yGQ­òÖÆÖÆ.æՁŒú:O„ôŸ­i·W×WÒw·O/ÓÐ< }Kã󇊻WU\
+¯xjHN¥ B•¨WП
+ at 70Ò (¨Wóù)iM ˜jHíEUÀãá©Òš@8søêKUT¬šàÒàƒµø®áê⹦¢­Ûz-YRS3³²,â!¢cšM6UÓù9I›²`ɲE(ª§!PÔD¼ã›¶¹.Wçñøèe¸¿›pÈ⍎’G½ÑÖ±Îq<Z	' -Ë—wv¶[ëyy#!´Žþ=ïpcÐðKœçÖ€8’HveÉÄ\Æãç.g¼W78ÙŸ9rm’ñ’HÈ[Ý•;.%Güz˲•·.¨_Ù.‘”&Š&áo‘3†»Ø›Ç‘˜­¹á’·ìcp{f¶¸ŽÖ ×éxd°ÈÞ- â…Àæ¯7uÎÛæþéÁÈÉXܽÓÁkƒ£žÏ!-ÔÒC£•‡CÚjYÁÇVGácð?ˆ'mùÌQ‘2ùxc+‚)ÍÝd[Y킾î{FfÝŽ;UTKȱf‚ ‘D ˆ¨r>3É=½Í[MѼçݐÏè—kmä‘<Aq5¬[C<r½º&G’8T’â^ÐIÒ¹Ÿ˜Ø7=µß–pQÝÏ<¶Ì‘¦Xc¸•“ÉãkµEBùÆš H]™œn<›tf7Æ8ö‚áìOÂSÛ+ØðØ÷78±Ü[6DT{-g“Y%‹¹e.„…¢äô5‘8ùJ¡Û”¢ŠæËÇí¼nÓ~pì<¶Sšî™.±ÂäMp÷8‰þÿ q®Bu4÷pè%­çæw5æj÷p7'‡Ý˜û
+€Ó…–÷†-kkÝ!Ó#¤pÐAé – ZÐgšpêžØl©y)ØA/›	+B$7º`ßX*K¾ÀvLbeRíhýX"$YhµÙ	ÅÆè=( "
+írK³÷k”¼f c/¿¿ì¯ŒòZdmȍ¹;‡š@æ‰+¡í’škݝgŠˆ÷Þ?ÌöDßZÿ tÝZˆ™p%c .uŒ-ÿ jYMm,®¯¶4ôðX±o±¶pw¾Ð¬seLG;~¼¸xe5´ÞËÈ0“쯂5½ .i…,SŠŒŸÝ$¶ãžîÉ‹VæôXªîöb5é—ód·§6võÆã2°`Ùo˜ïÅ¬‘:غÞXc<ØL¯oæu¼wsk¨£ÚEg¶y}»vÅíõ„¹GMŽîÄ3±âjLÉÜñ—»iü斝8:”+µø"ÏxE§ìd³eÇo5¿x!»ïœ¯íÙé¦ïoæwõ™>tìqƒÇh<–xÛ'³o&§¢Ž‚†l&§¾zÕùͱ÷œ»íöû6ÞáØ=çime’–(ÜæÚºÚâ*ÝJæ´µ6n|#]‡yB]¤,ï-wNڏj6mË4MÊí«‰®¬£{ÚÓ8žÒÚH."ä6C¦¤ ©]CÀod´§8”³¯L°¾$¹ø—k!	œÜŒÞÕËP·Ì+û•t\X@Ü.n§¤|ë³¥©@Û…8¨žÙÎþZ;+e·rØ|[r¸Ý¹;›&4tÏc+"ŽFÂ	¥ˆC•«¸Ò¤»_ånöYœ~FüØ^æbeéèŠéŽ‘ìt„¥’^êpáZ\2öEâÙêâÚ%	&ÑRaž4±°NT³ò=ß‘n÷I ÌåVûä!,Dƒ§Ž
+’Ä)ƒ† *š;aîÖ?°vÑLn£uÝÎJÊ{H- ó”.•¦K¦šh¥Í$t¸T·m—/ºðøËËíÛ»£|b‹xl®b¸–âR<Jƒ <u=Ô £@|Cô…}œZ¾iªP?_EAju^”cÛÃq?Ã=‘Ã^IÈÖÎËx.jæ‘Â7þ@t¤f9º-KÍÙ$ní¸“AÁmw­åRIVï—(  ’` p7ÎùìNæå·1¯y‰·q÷9}«›†dmmZwöíÑÌ;æ–×FÓ«Sœã”öLNC½¶]¶ÍÌÞAÏâä‘ÖsÎtÛËÇTK ºpp¯pÓ¥­«zÄ\=ãoˆ,׾rÃ’ÐØâQ¥Ûkâ¬A}Ådû÷#Ý0.·#ÌÒ´·í£K ™Ü:|©ST2) ªNžëß»—˜¸Yöo.p¹x®ò:	¯oíŸgki ²Wj––nìÆFÒF ð\Z{
+¥„Ù™8·&óÊc¤¶³x–;[IÛs=Ĭ!ѶŒñcXÎy¡¡i C‘pé`³„÷–îI½mLgzqih8{eLÞ’éÄØìnXÉé9(«%õÂè‰%Üì¥hÕÂàØ´6 u…4”ÇódÞìË‘Û¶wY>Õ»
+¸ŽÞ2û—BøØÇÜ6!Ró©Ž{Øßë<}–js{›?sÛnk­Ñi™¹‚Ë#Ÿ·.…ó?L"F½Îl.ÓH£ƒZçu4ôº<ŸY¼3q«jÞ\A`éÌ¥±¥´Â"À²oÈ‹„åB2bQTQm>EЊ¸.7ª;8ž.4]8f‚eQq/lB†;sf³¼Àæ>ÎÉáð9¨v͆JgIuqlø¸¾6LT/Š&†ŠM6†ÈâZÊè%w0xÌVÐÙ{’Ç#–ÆKœ»²¬‚Ù'½Ä !²HêšÇ§1 SP„ÞMmŒ­ìÞáå{'c(ûŸ‡I¬Òâü°îK½Œ5îñ+Òüw3ż°(úmGLž $Ý)©Žbæ2J¹œD¹-¯üÃgݍÉIÜãŵÌ0:Kv›{fÇ'}(£c
+s]^’ €Òq™ì³¼œÄ6ÒöÉ—¸y/ðI+Y1N^Îê3Åä‚)Ð
+H–2ZèâgZÜ^ÙNf¯X9¬U“¸!¶øx¿ï6Z>èFÉVçláGŽ‡» å#‘ó}AËd2‚C	@‡ó¬g.7ŽO”÷‘ÙÙÏçÆï9²¶¶÷t&àB at hoxâÈǼÆï°÷46 á¹ßoM·cÌgÜÜÅ&
+÷lÇa<°½²ˆL€ÔÜXæ´=¿i­$БCÓÜ<aûƒì´‡ùWˆL
+wÙØÆ>é”°`1^G¼ï±pH[Ò°"-ؤ•ÏzPtáÞâM슰öQbm›ÿ vg9³µ]Ëݱ€ÎZeòRBË©omooced’ºI^Cdw‰F5•tÔYㆰëÛGob¹{ŸÇ9–Å\c¬™+ ŽÖá³Mu#£s#k#h.`ñªç:ŽÒâ’áÆm[²ÒâÓ…ÀÁ²¹ÂÅ™«æ;»(ÙÄÈ·6••[¹i)ø7+Òü_s±œ”8 ‹ U"$RAEŽß'“ÅåyWÌύml/²{;!ˆ‚Êãî‘î-eµdRºøÏ…Ñ0js>É.$U¬t¬o±ûûcü1=Ý¥Žä³ÈËsÞ$C<s—9ì;Ål¡î:Cº@h‹‹6Ì‘!dpßÁÜç
+Íò5‰“òþbɐ—­øLip%uÚxþÓ´›´RÕÌÍ/Šä.—sÊ*¢ÜÃÙêÄ
+š'qÙÛ°fy‡ÍÈ9‡&>û´ñÙ-í¾ù‚{©ç.H!qÖØ[Ž—<xÄ4Ž.x¯™—³¹y.Íeå­öáÈÞ²iþí –("ˆÆ ÒéKÇÞ€]^¥ùŸ¸ÂÇ÷W™	ä<‰¸@ËÖM™ÝÉÛ÷$í±ç‡k)-Ù¨·bšÈÛ·«ÓžAȨ ¦˜–’	ÇöG)3ØÎRc÷–=‡6q7·Md±I×Q‰k,o
+{™-»@‰”<[ß=ÇÑ÷O0±7üüÛY{È®ù{¶†èäcãåÍž7´–‡G3‰‘Õ4]^í­'dë5s.«)¥Õkßmùw£¯.r2â¶n8ÍAhÙx¹HwÙY*™ÔH*&E@*„1C익—~áÀÚæeµ¹²žâ çÁqâš'ô>7²FµÞ+Ô£ÛG¶­p+æ¬Þ5¸|´øØî ºŠl°½²G#zZö¹…ÃÆiŠÕ¦­wW*›u¬ÑjÅÕz!ÕÑae.2—×]÷kbÛ²O%BælWvß’F…±¥®&ñÖÌí­qO‚*§¢ð±Ä35U)’QUM®†L¥SÀyƒÎížec9¯‹±ºÉââÇI½‚ٝåË"/|ÑMUP$yàÖŽâ[ëÛ>÷œÙÜ¿¿º‚Æý÷¬¼µ–wh…ò67Å#ètU	àI= ~$ñ…ƒÂ„u›–.ì³d_™âÙË6ÑbãIzA^m m…Å1)‘'#ؼo¤#-Ð\ªo,š‚
+—µ"\îÜÙÞi\^mlV*öÇcÜ⮡¹¼¾·–ÞGK<NŠ6ZFç4¼4¿TsiF¹£IÒ]Â0x…
+¶{!µºÝ0_Á,Ö³2fE#d{®֐ÝZhƵÕâŒ5öîcáûñ	š§sōĦ·ðÎN™F÷¹Ö¾/øËo!ãÕ%JÝÍÕ	-b?Þ“s:YpXäP¤èçL€p ‚†Õ6ŽüÜ[fÁ±ó[s7q¼1°›hEµ«æ´º¨‚Hî[â´i2¹Ôs qÒMZ6
+Ç´°Û»r˺q™œ\;rúA4†iÛŹu¬|ñ‹õjîÀ¨q-§Û?õœÅy72ñív°¹ ­«6_ƒ{ób•.‰foU¡mæ‘-ášÎ,Åü„½Êõ%—dÄæABÉ€b†«ü6Ýohl\TöÓÜåâÝö×·¢Ý+mÄ’ºG™sY--l’Wº!ÚH+?ñ¶7¸÷^B)â‡&ÜžÖ×½xŒÌYcË\çÈAsMzHºª±C†ËÎÒƒá#nné·!î+¾¥i at JÍÆGÍ]
+Ä]÷c™tíاnQ6¤[g)¨à&¨ E
+cèRæ.+{Ím‘²µ¸›i6HÏ+#{ã„I3+Úc †k-ÔA¤¡lÌŽ>×—ûªÊêxb¼¸ŠÄDÇ=­|¥’Ê_Ý´çéi€‚iT–eçi5öwåû)ÍÓn6¼äø…´f£mæã¹ä!›@B¢æ]ŒŽK*î1ºÉ‡pšFH†(€˜–_–—ŸøœÌv×ÃÅ€ž7Î#y…²d"7J†¼‚ipqÇdqìåCùá'åâ{b/h•Ì°¶2u‚. €GJÊî.x{q™pÁ)
+–°¥¡(Ç„¬-)mdëù¥‡*Ös:ow´<«ak1eÝ8Ar´:®Û®¦DJªb>]ʍýЋrÛ^b³7vÏÝy²k;W\±Ò~e¦h:£–kš^LJðx-rß9ƒ´_¸äÁÏmÆ[ÎÍ¿f×Gs8ÁŸœ"Q¨QñÔ¹§I.ioÑÁ}–ötáÝ)ð-öíµæ,N°)1=™–îÀµ†¾hk
+¡~ª›¢×i&_Gjá]ävR¹M at Hr7û'˜å†w5
+­Ì9¼þwï×1\Œ{ŸCjx÷ÎgŒö¶Žs	Í/.rZn Í÷ŠÆKq˜¼F+î°ÝÈ+¼
+¨Ÿÿ ;ÅkZÁÓG®Ôáªêɸÿ ˆHû»Š<qŒµ¶ª*ìö|@§pÛ#ב2@ÒQÌ+WQ¶E£Ð
+eÚ¨ù6ŠÉQA{Cæ±Ìl^ÛÏl1\´ØÙ(²!З\;bš¶Fj`‘Í}Ìò;ƒ^#/…ï{ôŽ9Ý—}›Änæd7Æ걒ȉ „_÷‘ÈâÇQÅ€¶˜>ÓKÃ	v–µµ<0ë…¶ÖÞKá#‰L#XWåÁyc[¶™2ìcgCIÄ¿Ay3¶“z
+vÊ3F5NÐMNÌÊ%¿ºU ÁëœÍ“#·9­·7·÷vFûogy†Î\HÇÈÒV6”/©új[Eç;;,×/ó[[ï–v™Y®m¥gÞel,sà]G;¦¦´„¶´«xG Ø¡€ýšÐãzÚA/bæ{îRøŠŽ$¬Ø·™­	V’7[yéVëQe)¬ì¨¦váÚDœµÔ~9ñß1¯>åw÷Kì=³-ŸÜÉ¢áíÇ9;N™\×ø…±—ïŠð]†å±_	ì»o¼Ûýâ×%;§oxÍP´Þ‡‡JÚÖ6–øÀ¼ [Æ´â¹ÆcÁ66OâžïÌíx—áÌ0ãëýÑrÍ'”"qÃÅÇ(ÀeâÛ[)G³2ÎÌÉT£NÈ˵|c¦b*]á)pÛC|f¶×,-6t»spü^ËCfÍý̏xwvó1£ccuL$
+|tp-4ä÷ÕÅç7ÝÆä7†øq÷bY÷–÷Œktëhˆq{Î’#,.kêÒǃ2â6ÃÊW¯´s!¹¸a-¦y79ÇŒ.9hØI[¡ÖöÄX¸÷ë5púnJ&Ìͪ²fWtw„7†&åæwla¹y·ã·šæ\n\Kvèc|Œ„Êó4®{Ú#š$qkHmxt
+‹xâ³¹=å˜|ÑAö4ÇnÙÖ>QDQ†µÄ=Ìc]¡µp&œzWG X¥À¾Í¸q½-0—±³5õ){Å
+ÇVtc¼Ô„«I©¦zM¼ÁÔX”ÖvTS;pí
+"NZÌ¿›;瘷sºû¥îÙ–Ïî¤Ñpöã‹È¦’¹¯ñc.!Þ)à±­ËbþÙvÿ y·ûÅ®JwLÞñš¡i¼•µ¬m-ñ}oÊíë ã‰N:øÄILcFÀæO•¬"örÅ’É;q…š´f·:NU‹ôE’‰qº¡?htÁ2”1J:–w¸­y!´\Üuì—ØŒ­ÕͳaÞ[?xüÉú{jS¨ÐHØ19|4üÔÜm7¶¬µÈãî­á™Ò7¹t’w%¿¶„5Ô š‘AR@]!ÁäCxl镸P».;~^7Ø·n*y?iJ䶼#cœOÚwDDƒr¤Œ©¡ž´p“s	@ á}
+  ÖëÍËÉ/6F+šx»yá¾ÂßA|اa†cÞ"žjYÞ5Í/®–ðêZ¿.­™mºoö
+üÑIk”´–ÔɻȄÍi’)XáÁÚpoV§q]OÆÞC‡½3Ü䦠}ÄQPøfÂA3&£tmüzÜÑ.‚¨ˆ¹AåÀ/WIR—C¢¡4 ­¯’ø¼6Å‚÷*?úöZY2DÔ-ÑÖ*
+H-‹»ii<×U¯ó;/o“Ý’Úãÿ þя–pBvãA¡2k Ž–±,î
+õbÕçÕJU6ÔªªR©ÕÑS¤§TÀ§@ù¦‰Õ()·ÇJ€§T ¥IjuJU6ëPZR•Mº{•:JuL
+XTª)TÛãïÒÒT §UIjª¥:êSªR©·ÇSBR•N­¡R˜)J¦Ý}ÚE¡:¥6éRZR‚•©Õ()·ÇS¥UR‚]êIÕ)Tëè© ER•MºT–ªªPSž¤µ:¥6õ
+Fš'T€§VФS›u¥@R›t©-N©ANº’ÔêÛ§wŠ µ:¥9ü”¨SªR©·]”¸u§T€¥-=‰Õ(mAjuHêÚ%©Õ (<úÔé¢u^ép>]lx!牍ÿ ÜGݯ˾`~þfÿ kÞ~±"ûÿ fþèb¿fÚþ‹Ð-ÀÛäþŠÔVȦàmòE_^.ï]Äïþ!sOúȹk÷?”ô§lÃØïÔá_–\ÂýþÎ~ؼýfEUèKOR„)B¡
+P…(B”!J¥VR NªÀpðÒÒŽ
+à<ÃSDø…`6”QíWÒNƒ©\B*B°0éEPUÀãáå©Òš¸e"
+uWxjhª¸Ÿ’‘jÀÜÃRBªžµp8Ò⎀p¡>) ÜÃJ€¢¡\Î*)«ù‡«üTˆíN© üþJ’ÔÕÀüÃRZRƦˆ¨HŠ<)ñJšT¡0UÀáÏ¥IjuHš’ÔêúT–§T€q©¢*<	@è¥áUT §]*U n4‹SªP??’ µ0RüÃRZRœõ4)Õ)TÛÕK‡ZuJ
+w-=‰Õ )·_v¤µ:¥:ªSªPR§JuHU6éîE/
+iANà¥@˜=‰AMºôÔ–§T §UAjª¥:êt§T¥SnžçôT‘ڝR‚ÁJ0R‚›uéïÔ–¢«!¸ƒÏîóôž0’ym7¶
+0Õ•‡ÐI´š²…—mf¸šp”ê§U“!f»ñ™3p
+ŸfÚòhaű-²Vðܺädr÷ä–wfàFBŽv Þ_²(¶ýÝ»$Ý“XÍ$-ƒîXØm .Ö!/:Í@¡v¿³Æ”é+ ÁNºÞ‹V§T¥Wm*´ê”î
+šÁJU6ëîÔ–§T ¦Ý;¼U%©Õ()Q¦
+ª˜ªíñÒ§juJ
+uyB•N«)pŸP2Ùœ{jb¦3£¶Ó‘vÎk}vJ¨{*"}ŠQÎÍbDÆÝ©œ¼—¤‘Dʸ”S17ʧ˜ï>^ßïl”å2’7d1Ѿls``ûÄ‘8½½åήóº.Ò]‚š‡BÝëlïM­e,¶
+;¥Í{c½t¯=Ë$hiѝàƒdÔÕJPq˜W2‡1Îsç0œç9„Ç9Œ:˜Æ1„DÆ0Ž¢=ñ¯HîÃF(Ò5jx’®
+wN“ÔŠ¥zÈ4¨S›té¥@UU()ܨ)TÛ­Ijª¥*›tîæ¨ÒSª`S¯¢’uJU6øéi	Õ()ÕPZR‚u©Õ)TÛãïTUU()ýaý“¯bb©·_v‘hN©J¦Ý*SªPR µ:¥*›z†•
+uíJ
+t‡”*hR•N¾ŠE¡0R•Mµ©Õ()RZª©J¦Ýz{õ4!:¥:CʨR‚{B§H=	Õ()¶¤µ:¥;‚ µ0R•MºìšQ:¤:CËKS}¨ )¶¤µ:¥óÔ¦
+B©Ì=CRZR‚ÁKŠuJU6ëÝã¥@RU%©Õ{¿Àçÿ ÀÄñŸþAµ~[s÷÷9û^óõ‰èÌýÏÄþ͵ý •¨-•J¿\\ÿ Þ»‰ßüBæŸõ‘r×î(ÿ éNØÿ ‡±ß©Â¿,¹…ûýœý±yúÌ‹«Ð–ž¥R„)B¡
+P…(B”!J¥R„)B€ÃÓJ:«€vR¡B¾µ4N¤-@Â" ô«ûƒú)'NÅp0
+©*àna¢‰Ôp?8xªt¦¬ï
+*U CmMuV‡EN”ü	 ÜÃSDWµ\4qO‡R¸(OZ at 8óøéPÀááä©Òš@0øZ’ª¸ŸÉS¥:¤ó
+I	×µ ž•
++ؐúQáO×KObuH};¼U%©Õ |5Sª@>ßðT–§_­ (>TN©MºRð¦”×Jƒ©Hæ¡©-N© üþJ’Ôê”Ì5©Õ )J…:¥6øûµ¥@R‚]‹Sª@S¯¢ µ:¥6éRZª©JšS¡:¥*›ixQT §pTÐê”Û¯»RZR‚U%ªª”¨§buJU6øéSµ:¥:º)Pê”Û¯»RZR‚›tîñT§T€¥Nšt'TÅSoŽ¦©Õ()Ò¨
+uJ
+uôT–§T¥SmAjª¥;‚§IêN©Š¦Ýi'T¥SnžåMN©ANà©-L¥SmAjuJU:ªhUU)Tëò
+$Wð¦*›z†§H)Õ()ÕRZª©ANº‚ÔꔪmþŠ’
+uJ
+w*&bb©·_ Ô–§T §UIjuJ
+sÔªªPSo»Zšꔪt‡”)Q:¦:ú*KSªR©¶¤µ:¥?¬*SªPSn½=úšR•MºyB‘:¥<[*KUU)TÛRZR‚]©Õ()Ð>í*R•MºtԐR‚”´ö'T¥SmAjuH
+wIjuL
+t»SBªB©·Nžõ/
+uJ
+RÒ:“ªR©·»š µ:¤*KSªPSn½=ÚÔé¢u^õp5ËaÛÃÏÿ 'µ¯Ë.a~ÿ g?l^~³"ýÙŸ¹øŸÙ¶¿ bôµ²©BàK‹Ÿû×q;ÿ ˆ\Óþ².ZýÏåý)Ûðö;õ8Wå—0¿³Ÿ¶/?Y‘cÕzÓÔ¡
+P…(B”!J¥R„)B¡
+P…(B”!JµÔB„UX>ZZSV ÔУÀ¯­*'R€Â‘PUÀô'CÔ®¡íVw†‘	ðêWó…-)ñWs
+I¨ª¸zii	«Ã¢¤µ?¸jh{RèâW…$ëڐ=4i¯b¸:*t”ê<úÔ–§Up?UIjuìHæ’¯j at Sž—ëؐÌ:QÀô¢½© üþJ)¤óPÔ–§T€~%IjuWó
+IjuíJ
+sÒ¡N©
+~aÓgø©pëN©@üþJZ{ ˜uØ5%©Õ )ÕPZR‚›{½Ú’ÔꐥÅ:¥6ëÝÏJH
+m÷*KUU()×ÑRZŠ¤*›jUU()ÏJ…:¥6øûµ©§juJ
+utRÓTê”芒Ôê”ÛÝîT§T€¥MèN©Š¦ßv´©ÚR‚!ÑJ•N©AN¾Š‚ÔÁHU6Ô–§T ¥MRuL
+íצ¦©Õ)TÛ§”)iUR‚ÁRZ˜)J¦Ú‚ÔꔪuTЦ
+PS¯ÉSDꘪmêZjR‚ÁRZR•MºÔªªR©·Or¤‚R‚ŸÖ4ESM¾>ý"ÕUJ
+uT§T §]IjuJUvøêhSªPS«¢•ª¦:¤µJU6ÔªªPR§JuJU6ëÓß©¡N©J¦Ñ(R N©Nà©-L¥SmAjuH
+utT–ª1Tëò
+M
+*”ªmñÒ UT ¥IjuJU6ëPZR‚]%©Õ()׶¦…:¥6øéP'T §=-=‰Õ()·Z‚Ôêêè¨-UT §_»J…J
+mñ÷iJ‰Õ()ÏS§±0W¾Üð
+»ÿ Dÿ ÉÍkò·˜_¿ùÏÛ¿¬È¿Aö_îv'öe¯è½­=lªP…øâçþõÜNÿ â4ÿ ¬‹–¿sùGÿ JvÇü=ŽýNùeÌ/ßìçí‹ÏÖdXõ^„´õ(B”!J¥R„)B¡
+P…(B”!J¥R„)B¡
+P…¨‡xh¢uVóÒÒŽ
+à`
+M
+<
+ÚÒ¢u*ÀqþºÀ«û»ô“ãÔ®¡íW=*ü
+àpðòRÒš¸˜jHíEUÀãáå©Òš¸9ütˆ)‚z•ÀÃSDTu«èL}	 Áà\¯j at 8ôÒ-MX‹J*=5BuW‡E"ÔÁJzš'^Õp?=.)øù†—U ŸÉHµ:¤ó»¤µ:¤óÔéN© üÃRZRœô¸§^Ä¥So»Z\ª@?õ…-)Õ(nµ©Õ )ÕRZRÇž¦‰Ôx‚T¸õ¦”è%*U )·Nš’ÕUJçòT¦
+B©¶¤µ:¥*hSªPSn½4¨ªPSnžå"Ôê”þ°¨-L…SmIjuJ
+TЧTÀ¦ÝziSµ:¥6éîTéªuH
+wIj`¥*›jUU()Ü4)‚˜ë¥DU()·Nš5U^Ô §pT–§T¥Snµ©Õ)Tê¥BR‚}4LÅSoŽ‘juH
+uTªª`S® µ:¥*»|t¨SªPS¸*hªb©·_v‘juJ
+mÒ µ:¥*SªR©·]ƒJŠª”é(TÐ'TÀ§_EIjuJU6øêKSªR©ÕÑPZ˜)ANò
+*'T¥SoPԐ¯jPS¸)§T¥Snµ©Õ)TÛ§¹PZª©N¾ŠTN©J¦Þ¡© 'T §U"Ôê”ë¨-N©J¦Ý=Ïè©-N©ANà©LÄ¥So¿J:¥:ªKSªPS® µUWÖÑ%]¹nÕ¹¢îVMS/(¨¢§ ßt®ŽFòÛa6JõᖐDéãÐÖ°| .Õ•¥ÅýäV6­/¹šF± t—8Ь•ú#àêXk>1±Š;­XµnSi 	[·M ^PܯɌÖEÙŒÍÞ]⏺º–b;¯sÈÿ Þ_¢Ø«&ã1–ØÖš¶Þã荁¿äYÃXÅßR„/À—?÷®âwÿ ¹§ýd\µûŸÊ?úS¶?áìwêp¯Ë.a~ÿ g?l^~³"Ǫô%§©B¡
+P…(B”!J¥R„)B¡
+P…(B”!J¥R„)B¡
+P…¨‡†Šê®ç©ÒŽ
+À`ð
+*#ˆVÖ•¯j¸—øp8PŽ!\„Tu«„6Ò 'àV‡EN’š¸˜iڝUÀüáS¥ÀÀ>I	Ô«Ä)Q:„€zÇ©\
+Ì4¸ëڐÏËHµ5p8xJ’T€qðòÔéM\útÔ–§R54N£ëH
+	ñHÛ¯M*Š¤‡E-)Õ yõ¨-N© üüžåIjª¤=MT€¥.)¥6ëÓJ:¤õR-N©@ýu%©Õ\Û¥AjuJ
+
+MªPSnÞ*<)¥óòûµ4I×± )·¨jKSª@SŸ’¤µ:¥*›u¨-N©ANª\SªPS iP'T ¦Ý:i§T §=Aj`¤*œÃ­AjuJ
+uR¡N©NºšêÛ§M"ÔëÚ”¨-UT¥Snµ%©Õ)Tê©¡LÀ§]*ꔪmñÔ–§T §UIjuJ
+uÔ§T¥SnžåI:¥;‚•uìJU6ëîÔ–§T §UIjª¦*SªR«·ÇSDê”êò…*ê˜ëè©-N©
+¦ßAjuL
+wNžÅUJ
+ôjhŠ¥6éÓJUR‚ÁRZSMµ©Õ!Tê©ÒSª`S¯¢¦‰‚”ªíñÒ N©ANª’ÕUJ
+uÔ§T¥SnžçôTé)Õ()Ü“±1TÛ¯»S¤'T §UIjuJ
+uÔ§T…SoŽ§Jª§!Œs¥)Œs¥ 	„Æ0è 
+DDDkŽI#Š7K+ƒbh$’@ $’x :ÉàÆÇÈñ@¹î4 
+’O@ t•˜¼:`雎àa-$ÅRn*C3l¢c¼–ð€zBÅ÷ªGÞ”yKßJøŸæ´ÎBý™´åï1¥Ãï3´ø²i5î£=l¨«Ü8:šEZM~©å,.12·sî(ô_Só¸qeGûGŽ§ÓƒZx·í:”ýâëE;RÞhÐ8"@0né˺óxkåô:ìê¥_ŸÎ"ý’ØâïÉwæEŽ¸r¡¥²
+åsß-‹1iŒci[²qôô‹xÄ~ÄúRè»~r¢EVYR¦(qÔÃõvÝþp¹™¶vý†Û°±Á>Çg
+´n’£#£‚6ÄÂòÛÖ4¼µ€¸µ­֍€ð,Ïòç²s™{¬ÕÝÖU·W—2ÎðÉmÃå{¤ph6Î! ¸†‚ç)ROŽÿ ´%·óÎJúVØü£Yîk{¿oyÏoXß–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;ÜÖ÷~ÞòžÞ–
+ƒé™+mìŠ~ЖßÏ9+é[cò;¼Ö÷~ÞòžÞ–
+ƒé™+mìŠÁ솷ûç%})l~Q£çwšÞïÛÞBóÛÓù`Ø>™˜ò¶Þȵý¡íÏž2OÒ–Çå*_;œÖ÷~ÞòžÞ—ËÁôÌÇ•¶öE?h{s眓ô¥±ùJÎk{¿oyÏoOåƒ`ÿ y˜ò¶Þȵý¢-ÐþùÉ?J[”©|íó[Ýû{È^{z,;ÒòþVßÙU¿h«{猓ô¥±ùJŸÎç5½ß·¼…ç·¥òÁ°}31åm½•kûEÛß<d¥-ŸÊT|íó[Ýû{È^{z,;Ó3VÛÙTý£-àþøÉJ[?”©|íóWÝû{È^{z>Xv¥åü­¿²«~ÑÖÿ Ï#éKgò/®jû¿oyÏnGËÂôÌÇ•¶öU¯íoüï‘þ”¶)ÑóµÍ_wíï!yíÈùbØ^—˜ò¶þʵd„ |d¥-ŸÊt¾vy©îý½ä/=¹?–-…éy+oì«_ÚFç|ôµùR—ÎÇ5=ß·ü…ç·%òÅ°½//åmý•kûI@ü“¶¿*Qó¯ÍOwíÿ !yíÉü±ì/KËù[eVd¤{äo¤í¯Ê”|ëóSÝûÈ^{r>Xö¥åü­¿²­iX/ò/Òv×åJ>uù©îý¿ä/=¹?–=…éy+oì«PöKÁ‡z_"ý'm~U¥ó¯ÍOwíÿ !yíÈùcØ^——ò¶þÊ­ûLAüí‘>“¶ÿ *Ñó­Í?wíÿ !yíÈùdØ~——ò¶þÊ {&¡½-‘>“¶ÿ *ÒùÕ査öÿ ¼öäþY6¥åü­¿²«~ÓpŸ;d?¤­¿ÊÔ¾u9§èÈ]ûr>Y6¥åü­¿²­iØ_²ÒVßåj_:|Òô
+¿ä.ý¹,ÛÒòþVßÙUƒÙ?ÞÙé+sòµ:|Óô»öä|²ì?KËù[eZþÔß:ä/¤­ÏÊô|éóKÐ6ÿ »öäþY¶¥åü­¿²«²Š?½rôÉ[Ÿ•é|ésKÐ6ÿ »öä|³l?KËù[eZþÔpÿ :䤭ßÊô|ésKÐ0BïÛ‘òϱ=//åmý•[ö¥ˆù× þñ·+ÒùÐ揠`<…ß·#åŸaú^_ÊÛû*×ö§‰ùÓ }#nþX¥ó¡Í@Ày¿nOåŸbz^_ÊÛû*°{*bƒûÓ }#nþX£ç?š>€ò~܏–}‰éy+oìªßµTWΗÿ Ò6÷åš>sù£è!wíÉü´lOKËù[eVý«bþt¿‡ÿ xÛß–i|çsCÐ0BïÛ‘òѱ=//åmý•jÊèÀïIßßHÛß–i|æóCÐ0BïÛ‘òÓ±}//åmý•[ö°ŒùÎýúBßüµKç3š€ò~ÜŸËNÅô¼·•·öU¨{,£CûÎýúBßüµKç/™þ€ò~܏–­‹éyo+oìªßµ¤wÎWçÒÿ åª>rùŸè!wí¨ùjؾ—–ò¶þʬËhðïI_ŸH[ÿ –èùËæyÿ ö!wí©üµl_KËy[eZþÖñÿ 9_H@~[¥ó•Ìÿ @Àù¿mGË^Åô¼·•·öU`ö]0ï+ìz_À~[¥ó“Ìï@Àù¿mOå¯bú^[ÊÛû*·ívÄ?¼o¯ãà?.RùÈæw `|…߶£å³cz^[ÊÛû*°{/™÷óü|åÊ_8üÎô‘»öÔ|¶loKËy[eVf0ïHß?ÇÀþ]£ç™Þò~ÚŸËnÆô¼·•·öU¯í„ÏçãøøË´¾q¹›è8#wí¨ùmØÞ—–ò¶þʬÌFýá|u¿‚ü»GÎ/3}änýµ?–ݍéyo+oìªß¶3_œ/ã ¿/RùÄæg à¼ß¶£å»cú^[ÊÛû*°{2÷…ïütåê_8|Ìô‘»öÔ|·lKËy[eVfSpïH^ßÇAþ_£ç™žƒ‚ò7^ÚŸË~Çô¬·•·öUoÛ1¿ú}ëütåú_8\Ìô‘ºöÔ|·ìKËy[eVfrþzõ½ƒü¿Kç™~ƒ‚ò7^ڟˆÇô¬¯•·öU¯í úuéül'Ô¾p9—è8/#uí¨ùpÙ—•ò¶þʬÍ$ƒüúóþ6ê
+_7üÊô‘ºöÔ|¸ìJÊù[fVf¢aÞ}yÿ 	õ
+7üÊô‘ºöÔþ\vG¥e|­¿³+~ÚÉÿ ¦Þ_ÆÂýCKæû™^ƒƒò7^ڏ—‘éY_+oìÊÁìÙ žÞ?ÆBýEKæ÷™>ƒƒò7^ÚŸË–Èô¬¯•·öe`öm”?Ïoã!~¢¥óyÌŸAÁù¯lGËžÈô¬¯•·öeoÛt?Ó/ã!¾¢¥ówÌŸAÁù¯lOåÏdúVWÊÛû2°{7ôÿ <¼:ÞC}GGÍß2}än½±.{'Ò²¾VßÙ•¿nóË¿øȨèùºæG àü×¶#åÓdúVWÊÛû2·íÈoôË»ø¸©*~ny‘è8?#uí‰üºlŸJÊùX=™jÎSùåÝü\?Ô”|ÜsÐp~FëÛòë²}++å öeoÛ ÿ éwoñqRÒù·æ?¡a<×¶'òí²}++å öepöu(çw`ô»ˆú–›~cúÈÝ{b>]¶O¥e|¤̵gb¡Þwvõ-/›ncúÈÝ{b.Û+Ò²žRfVý»–ÿ Jºÿ Š‰úš—ͯ1½	än½±.û+Ò²žRfVgŠáþuuõ5/›>czÈÝ{b>]öW¥e<¤̬Ï5üêêþ*'êz_6|Æô,'‘ºöÄþ^6W¥e<¤Ì­ûz¸ÿ IºŠŠúž›>czÈÝ{b>^6W¥e<¤̬Ïw!þstõE/›búÈÝ{b/;/Ò²žRfVý¾]¤]ÄÅ}QKæؾ……ò7^؏——éYO)³+~ßnÿ Ò.âbþ¨¥ó_ÌOBÂùŸlGËÖËô¬§”ƒÙ•ƒÙúð;Î.âbþ©¥ó_ÌOBÂùŸlOåëeúVSÊAìÊßõ yÿ Ÿ¹¿‰ŒúªšîbzÈÜûb>^ö_¥e<¤̬=÷û—ø˜Ïª©|Öóа¾FçÛù{Ùž•”ò{2°pø?ßîOâ#>ª¥óYÌ?BÂùŸkGËæÌô¬§”ƒÙ•¿êÿ ÿ =rõ]/š¾aúÈÜûZ/›3Ò²žRfV$ýþãëqõ]5|Ãô<7‘¹ö´|¾lÏIÉùH=™[þ¡R!ÞZãþ"7êÊ>j¹…èX_#síhù}Ùž•”ò{2dxß.ò—Ã^Rv;¢ÃÙÇÚu…qKüÓsF6×Çë6Š«§Â
+äùÙlxs§É8£,4>0ø]÷øB9Êž0©¨Q.ó‡w<ÂUŠ[Þ&è5yVëæ†ùÞŒ0g²¾Èš÷,
+Š/¢¬Œ4>FMdv¯AÛÛiíw	qq²è
+w®¬’}4{Ë‹kÖ¤}Ѽk†!,–艧۔¥ÔÛ…×PþºsÖ€·Þ…)HP)C@ Є+P…(Bø|]¯ü'Ñ÷¿ûÍ5¡æùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüڧȞ§æÐ…>Dõ?6„)ò'©ù´!O‘=OÍ¡
+|‰ê~mSäOSóhBŸ"zŸ›BùÔüÚ¾ô=Oì;
+?û¿à¡é¡
+P…(B”!ÿÙ
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/middle_bg.jpg
===================================================================
--- trunk/openchange/doc/doxygen/pictures/middle_bg.jpg	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/middle_bg.jpg	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,2 @@
+ÿØÿà JFIF   d d  ÿì Ducky     d  ÿî Adobe dÀ   ÿÛ „ ÿÀ  d  ÿÄ U               
+                            Q¡Ña‘                ÿÚ   ? ßÀ#¿ªÚ0	ï涜 ‡3Yû žñݲ	     ?ÿÙ
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/nav_tab.gif
===================================================================
--- trunk/openchange/doc/doxygen/pictures/nav_tab.gif	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/nav_tab.gif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,7 @@
+GIF89aP  æ  ïïïþþþýþýûüúõ÷óñôïøú÷ýýüúûù÷ùöôöòöøõïóíðôîóöñùúøüýûòõðïòìîòëíñëòõïõõõÿÿÿúúúîòìðóîêëéðððôôôñññýýýñôðÆÉÅìîëÇÊÆÈÊÆÏÏÎÇÊÅËÍÊêìéïóîçèæÎÏÍÐÐÐõ÷ôÊÍÉïñíÆÈÄÊÌÊêêéïóìüýüÊËÉÏÏÏèêçÕ×ÓüüûÍÎÌëíêÌÍËíñêÏÐÏùûøêëêòöðóõñÉÊÇñôîîñì                                                                                                                                                                              !ù     ,    P   ÿ€ ˆ‰Š‹ŒŽ‘ˆ‚@;/Ÿ ¡¢£¤¥¦§¨E(ƒ )·¸¹º»¼½¾¿À¸7„23ËÌÍÎÏÐÑÒÓÔÐ=*"DÝÞßàáâãäåæä8îïðñòóôõö÷õ. A
+þÿ 
+H° ÁƒM R ¡Ã‡#JœH±¢ÅŠ0)ˆÀ±£Ç CŠI²$Ɉ8Xɲ¥Ë—0cÊœIsæD-èÜɳ§ÏŸ@ƒ
+*”¢’*]Ê´©Ó§P£J:Q‚X³jÝʵ«×¯`­È@‚³hÓª]˶­Û·p‰ßÆ@ôÀݻxóêÝË·¯ß¿~O Bð °áÈ+^̸±ãÆ<
+@@¹²å˘3kÞ̹3gˆrMº´éÓ¨S«^Ízõ
+D4 ÈžM»¶íÛ¸sëÞ­»¢ÀƒN¼¸ñãÈ“'·H€óçУKŸN½ºõë×} 
+À½»÷ïàËO¾|y  ;
\ No newline at end of file

Added: trunk/openchange/doc/doxygen/pictures/pixel_grey.gif
===================================================================
--- trunk/openchange/doc/doxygen/pictures/pixel_grey.gif	                        (rev 0)
+++ trunk/openchange/doc/doxygen/pictures/pixel_grey.gif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1 @@
+GIF89a  €  îîî   !ù     ,       D ;
\ No newline at end of file

Added: trunk/openchange/doc/examples/Makefile
===================================================================
--- trunk/openchange/doc/examples/Makefile	                        (rev 0)
+++ trunk/openchange/doc/examples/Makefile	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,15 @@
+all:	fetchappointment	\
+	fetchmail		\
+	mapi_sample1		
+
+clean:
+	rm -f fetchappointment fetchmail mapi_sample1
+
+fetchappointment:
+		gcc fetchappointment.c -o fetchappointment `pkg-config libmapi --cflags --libs` 
+
+fetchmail:
+		gcc fetchmail.c -o fetchmail `pkg-config libmapi --cflags --libs`
+
+mapi_sample1:
+		gcc mapi_sample1.c -o mapi_sample1 `pkg-config libmapi --cflags --libs`
\ No newline at end of file

Added: trunk/openchange/doc/examples/fetchappointment.c
===================================================================
--- trunk/openchange/doc/examples/fetchappointment.c	                        (rev 0)
+++ trunk/openchange/doc/examples/fetchappointment.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,97 @@
+#include <libmapi/libmapi.h>
+
+#define DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
+
+int main(int argc, char *argv[])
+{
+        enum MAPISTATUS                 retval;
+	TALLOC_CTX			*mem_ctx;
+        struct mapi_session             *session = NULL;
+        mapi_object_t                   obj_store;
+        mapi_object_t                   obj_folder;
+        mapi_object_t                   obj_table;
+        mapi_object_t                   obj_message;
+        struct mapi_SPropValue_array	props_all;
+        struct SRowSet                  rowset;
+        struct SPropTagArray            *SPropTagArray;
+        mapi_id_t                       id_inbox;
+        mapi_id_t                       *fid, *mid;
+        char 				*profname;
+	char				*profdb;
+	uint32_t			Numerator;
+	uint32_t			Denominator;
+        uint32_t                        i;
+
+	mem_ctx = talloc_named(NULL, 0, "fetchappointment");
+
+        /* Initialize MAPI */
+	profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+        retval = MAPIInitialize(profdb);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Find Default Profile */
+        retval = GetDefaultProfile(&profname);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Log on EMSMDB and NSPI */
+        retval = MapiLogonEx(&session, profname, NULL);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Open Message Store */
+        mapi_object_init(&obj_store);
+        retval = OpenMsgStore(session, &obj_store);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Find Inbox default folder */
+        retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderCalendar);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Open Inbox folder */
+        mapi_object_init(&obj_folder);
+        retval = OpenFolder(&obj_store, id_inbox, &obj_folder);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Retrieve Inbox content table */
+        mapi_object_init(&obj_table);
+        retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Create the MAPI table view */
+        SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID);
+        retval = SetColumns(&obj_table, SPropTagArray);
+        MAPIFreeBuffer(SPropTagArray);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Get current cursor position */
+        retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+        MAPI_RETVAL_IF(retval, retval, NULL);
+
+        /* Iterate through rows */
+        while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) != -1 && rowset.cRows) {
+                for (i = 0; i < rowset.cRows; i++) {
+			fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID);
+			mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID);
+			mapi_object_init(&obj_message);
+                        retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0);
+                        if (retval != MAPI_E_NOT_FOUND) {
+                                retval = GetPropsAll(&obj_message, &props_all);
+                                mapidump_appointment(&props_all, NULL);
+                                mapi_object_release(&obj_message);
+                        }
+                }
+
+        }
+
+        /* Release MAPI objects */
+        mapi_object_release(&obj_table);
+        mapi_object_release(&obj_folder);
+
+	Logoff(&obj_store);
+
+        /* Uninitialize MAPI */
+        MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+
+        return (0);
+}

Added: trunk/openchange/doc/examples/fetchmail.c
===================================================================
--- trunk/openchange/doc/examples/fetchmail.c	                        (rev 0)
+++ trunk/openchange/doc/examples/fetchmail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,96 @@
+#include <libmapi/libmapi.h>
+
+#define DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
+
+int main(int argc, char *argv[])
+{
+        enum MAPISTATUS                 retval;
+	TALLOC_CTX			*mem_ctx;
+        struct mapi_session             *session = NULL;
+        mapi_object_t                   obj_store;
+        mapi_object_t                   obj_folder;
+        mapi_object_t                   obj_table;
+        mapi_object_t                   obj_message;
+        struct mapi_SPropValue_array	props_all;
+        struct SRowSet                  rowset;
+        struct SPropTagArray            *SPropTagArray;
+        mapi_id_t                       id_inbox;
+        mapi_id_t                       *fid, *mid;
+        char                            *profname;
+	char				*profdb;
+	uint32_t			Numerator;
+	uint32_t			Denominator;
+        uint32_t                        i;
+
+	mem_ctx = talloc_named(NULL, 0, "fetchmail");
+
+        /* Initialize MAPI */
+	profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+        retval = MAPIInitialize(profdb);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Find Default Profile */
+        retval = GetDefaultProfile(&profname);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Log on EMSMDB and NSPI */
+        retval = MapiLogonEx(&session, profname, NULL);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Open Message Store */
+        mapi_object_init(&obj_store);
+        retval = OpenMsgStore(session, &obj_store);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Find Inbox default folder */
+        retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Open Inbox folder */
+        mapi_object_init(&obj_folder);
+        retval = OpenFolder(&obj_store, id_inbox, &obj_folder);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Retrieve Inbox content table */
+        mapi_object_init(&obj_table);
+        retval = GetContentsTable(&obj_folder, &obj_table, 0x0, NULL);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Create the MAPI table view */
+        SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID);
+        retval = SetColumns(&obj_table, SPropTagArray);
+        MAPIFreeBuffer(SPropTagArray);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+        talloc_free(mem_ctx);
+
+        /* Get current cursor position */
+        retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+        MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+        /* Iterate through rows */
+        while ((retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset)) 
+	       != -1 && rowset.cRows) {
+                for (i = 0; i < rowset.cRows; i++) {
+			fid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_FID);
+			mid = (mapi_id_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_MID);
+			mapi_object_init(&obj_message);
+                        retval = OpenMessage(&obj_store, *fid, *mid, &obj_message, 0x0);
+                        if (retval != MAPI_E_NOT_FOUND) {
+                                retval = GetPropsAll(&obj_message, &props_all);
+                                mapidump_message(&props_all, NULL);
+                                mapi_object_release(&obj_message);
+                        }
+                }
+
+        }
+
+        /* Release MAPI objects */
+        mapi_object_release(&obj_table);
+        mapi_object_release(&obj_folder);
+
+	Logoff(&obj_store);
+
+        /* Uninitialize MAPI */
+        MAPIUninitialize();
+        return (0);
+}

Added: trunk/openchange/doc/examples/mapi_sample1.c
===================================================================
--- trunk/openchange/doc/examples/mapi_sample1.c	                        (rev 0)
+++ trunk/openchange/doc/examples/mapi_sample1.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,33 @@
+#include <libmapi/libmapi.h>
+
+#define   DEFAULT_PROFDB_PATH     "%s/.openchange/profiles.ldb"
+
+int main(int argc, char *argv[])
+{
+        TALLOC_CTX              *mem_ctx;
+        enum MAPISTATUS         retval;
+        struct mapi_session     *session = NULL;
+        char                    *profdb;
+        char                    *profname;
+
+        mem_ctx = talloc_named(NULL, 0, "mapi_sample1");
+
+        profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME"));
+
+        retval = MAPIInitialize(profdb);
+        mapi_errstr("MAPIInitialize", GetLastError());
+        if (retval != MAPI_E_SUCCESS) return -1;
+
+	retval = GetDefaultProfile(&profname);
+        mapi_errstr("GetDefaultProfile", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return -1;
+
+	retval = MapiLogonEx(&session, profname, NULL);
+	mapi_errstr("MapiLogonEx", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return -1;
+
+        MAPIUninitialize();
+        talloc_free(mem_ctx);
+
+        return 0;
+}

Added: trunk/openchange/doc/howto.txt
===================================================================
--- trunk/openchange/doc/howto.txt	                        (rev 0)
+++ trunk/openchange/doc/howto.txt	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,434 @@
+Copyright 2005-2008 OpenChange Project
+under the terms at http://creativecommons.org/licenses/by-sa/3.0/
+
+
+OpenChange developer howto
+--------------------------
+
+== Updated on January 2009 ==
+
+
+###############
+[0x0] CONTENTS
+###############
+
++------------------------------------+
+[0x1] INTRODUCTION
+     [0x1a] What is OpenChange?
+     [0x1b] What is libmapi?
+[0x2] INSTALLATION
+     [0x2a] Samba4 installation
+     [0x2b] Requirements
+     [0x2c] OpenChange installation
+[0x3] POST INSTALLATION
+     [0x3a] Create a profile store
+     [0x3b] Create a profile
+     [0x3c] Test the profile
+[0x4] USING LIBMAPI
+     [0x4a] Doxygen
+     [0x4b] Sample applications
+     [0x4c] External resources
+[0x5] OPENCHANGE SERVER
+     [0x5a] Provision
+     [0x5b] Extending users Samba AD schema
+     [0x5c] Setting smb.conf
+     [0x5d] Running the Address Book Provider (EMSABP)     
+[0x6] SWIG BINDINGS
+     [0x6a] Installation
+     [0x6b] Sample applications
++------------------------------------+
+
+
+####################
+[0x1] INTRODUCTION
+####################
+
+
+[0x1a] What is OpenChange?
+==========================
+
+OpenChange both provides an Open Source implementation of Microsoft
+Exchange protocols under unix/linux platforms and a server able to
+replace transparently Exchange in a company environment.
+
+
+[0x1b] What is libmapi?
+=======================
+
+libmapi is the OpenChange MAPI implementation. It is a programming
+interface designed to offer Exchange support to third party
+applications.
+
+
+[0x1c] Why do I have to do all this compilation?
+================================================
+
+Several distributions (Debian, Ubuntu, SuSE and Fedora) contain
+packages for OpenChange. These packages are not maintained by the
+OpenChange team but by the distributions, and may be out of date.
+
+Furthermore the OpenChange project is moving along quickly and you may
+want to evaluate or benefit from latest features, changes and bug
+fixes we may supply in the future.
+
+
+####################
+[0x2] INSTALLATION 
+####################
+
+
+[0x2a] Samba4 Installation
+==========================
+
+[*] First of all, you need to install a Samba 4 version and pidl
+    version compliant with OpenChange. Furthermore talloc became an
+    external dependency and needs to be installed apart from
+    Samba4. This task can automatically be done using the
+    installsamba4.sh script located in the script directory.
+
+    Note that the script relies on sudo for "make install" operations
+    and requires your account to be in the sudoers file.
+
+    Run the following command:
+
+
+$ make samba
+
+
+This should give you the libraries, headers and tools you need to
+compile OpenChange. It is rare that you will need to update Samba,
+when you have successfully done this once you should not need to do it
+again.  As a hint, as well as your base compiler (apt-get install
+build-essential on Debian and Ubuntu) you will need pkg-config.
+
+If you want to control every detail of the Samba build, follow the
+instructions for checking out the git tree. You will require
+tools such as autoconf (apt-get install automake on Debian and
+Ubuntu), it will take more time and disk space, and there is more to
+go wrong.
+
+Since the libraries will be installed in /usr/local/samba/lib,
+ldconfig needs to know about it. On Linux, make sure this directory is
+listed in /etc/ld.so.conf and run 'ldconfig -v'. On FreeBSD, add this
+directory to the line 'ldconfig_paths' in /etc/rc.conf and then run
+'ldconfig -rv'.
+
+Similarly, you need to have /usr/local/samba/bin in your PATH for the
+pidl binary. This is also where OpenChange installs its binaries. Eg,
+if your shell is bash:
+
+$ export PATH=$PATH:/usr/local/samba/bin
+
+If you did a standard Samba install to the normal Samba4 location you
+should not need to change PKG_CONFIG_PATH, however it does need to be
+set. Use 
+
+$ echo $PKG_CONFIG_PATH
+
+to see if it has a current value. So if PKG_CONFIG_PATH points to a valid place
+and OpenChange configure still complains, you may have a problem with the Samba 
+installation.)
+
+If you have installed Samba4 somewhere else, you need to change Samba references
+in ld.so.conf, and in the PATH and PKG_CONFIG_PATH environment variables. 
+For example, if you installed to /opt/otherplace/samba
+run:
+
+$ export PATH=$PATH:/opt/otherplace/samba
+$ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/otherplace/samba/lib/pkgconfig
+
+pkg-config >= 0.20 is required.
+
+
+[0x2b] Requirements
+===================
+
+OpenChange has only these dependencies in addition to Samba4's
+requirements:
+
+* automake (autogen will fail with 'autogen.sh: aclocal not found')
+* flex
+* libpopt
+
+Samba4 can *use* some of the above, and will tell you in the
+'configure' summary that some of them have not been found, however it
+does not *require* them.
+
+OpenChange also includes a new build system which will gathers
+dependencies on your system and only build what can be compiled with
+your current system. If your system doesn't meet the requirements for
+a particular tool or library, you will need to install missing
+dependencies check below for the list of dependencies you need to
+install:
+
+	* libmagic (with development headers): exchange2mbox. For
+          example:
+		# apt-get install libmagic-dev   (Debian, Ubuntu)
+		# pkg_add libmagic               (BSD)
+
+	* bison: libocpf, openchangeclient
+
+	* dcerpc_samr (samba4 installation): libmapiadmin and
+          openchangepfadmin
+
+	* doxygen: build the documentation
+
+	* boost-thread: thread support for libmapi++
+
+Similarly for the others:
+
+# apt-get install automake flex bison libpopt    or
+# pkg_add automake flex bison libpopt
+
+If you have boost development libraries installed, but they aren't being
+found by the configure script (see below), you may need to set the
+BOOST_LIB_SUFFIX environmental variable:
+$ export BOOST_LIB_SUFFIX=-mt
+
+
+[0x2c] OpenChange libmapi installation
+======================================
+
+If you retrieved the soure code from Subversion, run autogen.sh now:
+
+$ ./autogen.sh
+
+Now, run configure:
+
+$ ./configure --prefix=path_where_samba_is_installed
+
+The default is not /usr/local/samba as you might expect, but /usr/local . So you normally
+do need to specify --prefix.
+
+You should already have made sure that the output of 'ldconfig -v' mentions
+the samba library directory in the Samba installation step. If you didn't, OpenChange
+will not find the libraries it needs.
+
+You should now be able to build and install openchange MAPI library:
+
+$ make && make install
+
+You can test like this:
+
+$ openchangeclient --help
+
+
+
+#########################
+[0x3] POST-INSTALLATION
+#########################
+
+The MAPI library requires a profile database and a profile in that database
+before it can be used.
+
+
+[0x3a] Create a profile store
+=============================
+
+$ mapiprofile --database=/tmp/profiles.ldb	\
+	      --ldif=/usr/local/samba/share/setup -n
+
+
+[0x3b] Create a profile
+=======================
+
+$ mapiprofile --database=/tmp/profiles.ldb	\
+	      --profile=testuser-2000		\
+	      --username=testuser		\
+	      --password=openchange		\
+	      --domain=OPENCHANGE		\
+	      -I 192.168.194.22			\
+	      --create
+Profile testuser-2000 completed and added to database /tmp/profiles.ldb
+
+You need to specify:
+    - the full path to the profile store database
+    - the profile name you want to create
+    - the username/password couple mapiprofile will use to connect to
+      the Exchange server (you might want to use Administrator, on a test server)
+    - the Windows domain your Exchange server belongs to
+    - the IP address of the Exchange server (this must be real. Change the example!)
+    - the create operation
+
+
+[0x3c] Test the profile
+=======================
+
+You can next ensure your profile was correctly created by running the
+commands below:
+
+$ mapiprofile --database=/tmp/profiles.ldb --list
+We have 1 profiles in the database:
+        Profile = testuser-2000
+
+$ mapiprofile --database=/tmp/profiles.ldb --profile=testuser-2000 --dump
+Profile: testuser-2000
+        username       == testuser
+        password       == openchange
+        mailbox        == /o=First Organization/ou=First Administrative Group/cn=Recipients/cn=testuser
+        workstation    == LOCALHOST
+	domain	       == OPENCHANGE
+        server         == 192.168.194.22
+
+
+####################
+[0x4] USING LIBMAPI
+####################
+
+[0x4a] Doxygen
+==============
+
+HTML documentation and Man pages are supplied with the MAPI library so
+developers can have an overview on how to use each function properly.
+
+Run the following commands to generate and install man pages:
+$ make doxygen
+# make installman
+
+If you have troubles accessing man pages, be sure your MANPATH
+environment variable is set properly and point on openchange prefix
+installation path.
+
+$ export MANPATH=$MANPATH:/usr/local/samba/share/man
+
+The HTML documentation is available in the apidocs/html/ directory or
+can directly be browsed online at http://www.openchange.org/apidocs/.
+
+[0x4b] Sample applications
+==========================
+
+A sample openchangeclient application is supplied so you can test the
+library and have an overview on how to use it into your
+applications. Please refer to the openchangeclient man page for
+further information on its command line option.
+
+$ openchangeclient --database=/tmp/profiles.ldb --profile=testuser-2000 --fetchmail
+
+
+
+For further examples see:
+
+$ man openchangeclient
+
+openchangeclient is also useful in its own right as a scriptable client.
+
+[0x4c] Web resources
+====================
+
+For up to date material on how to use libmapi + discussions, you
+are strongly encouraged to visit the OpenChange wiki:
+    * http://apidocs.openchange.org
+    * http://wiki.openchange.org
+    * http://wiki.openchange.org/index.php/ClientSideProgramming
+
+
+
+########################
+[0x5] OPENCHANGE SERVER
+########################
+
+If you download one of the libmapi releases, please note that the
+server code is not supplied. Consider using subversion to retrieve the
+latest openchange revision:
+
+svn co https://svn.openchange.org/openchange/trunk
+
+
+[0x5a] Provision
+================
+
+In order to run the openchange server, you need to setup Samba4
+correctly. If you have not already installed Samba4, please refer to
+section 2 for further information.
+
+Under your root account, provision the server:
+
+# ./setup/provision --domain=OPENCHANGE --realm=OPENCHANGE.LOCAL \
+		    --adminpass=secret --server-role='domain controller'
+
+If you need to add a user, run the following command from Samba4
+source directory and setup arguments so it fullfill your needs:
+
+# ./setup/newuser <username> <password>
+
+
+[0x5b] Extending Samba AD schema
+================================
+
+In the OpenChange source directory, run the following command to extend
+Samba4 AD. This script will add necessary schema and attributes to run
+OpenChange Server
+
+# ./setup/openchange_provision
+
+[0x5c] Extending Samba AD users
+===============================
+
+Finally running OpenChange server for a given user implies it belongs
+to the "Exchange Organization". The openchange_newuser script will
+extend existing user records and add attributes needed by OpenChange
+
+# ./setup/openchange_newuser --create <username>
+
+Users created with this script are enabled by default. You can
+enable/disable these users at any time by running:
+
+# ./setup/openchange_newuser --enable <username>
+# ./setup/openchange_newuser --disable <username>
+
+
+[0x5c] Setting smb.conf
+=======================
+
+In order to run OpenChange server, you need to set up additional
+parameters in the [global] section of smb.conf. OpenChange server
+being part of mapiproxy, detailed and up to date information can be
+found at the following address:
+
+http://mapiproxy.openchange.org
+
+
+[0x5d] Running the Address Book Provider (EMSABP)
+=================================================
+
+The simplest is to just run "smbd", but as a developer you may find
+the following more useful:
+
+   # smbd -d3 -i -M single
+
+that means "start smbd without messages in stdout, and running a
+single process". That mode of operation makes debugging smbd with gdb
+particularly easy.
+
+
+########################
+[0x5] SWIG BINDINGS
+########################
+
+OpenChange has introduced SWIG bindings support for its MAPI
+Library. This development provides MAPI library support for different
+languages.
+
+[0x6a] Installation
+===================
+
+o Perl bindings support:
+  [*] run configure with --enable-swig-perl=yes
+  [*] make && make install
+
+Note: The compilation process requires quite some time due to the code
+generation for mapitags and mapicodes constants. If you intend to
+develop on libmapi bindings, you should comment out the following
+directives in mapi.i: 
+
+	   %include "swig_mapitags.h" 
+	   %include "swig_mapicodes.h"
+
+
+[0x6b] Sample applications
+==========================
+
+Tests applications are located in the tests directory of the 
+supported swig languages.
+
+Example: swig/perl/fetchmail.pl

Added: trunk/openchange/doc/man/man1/exchange2ical.1
===================================================================
--- trunk/openchange/doc/man/man1/exchange2ical.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/exchange2ical.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,93 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2008 Brad Hards
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii exchange2ical.1
+.\"
+.TH EXCHANGE2ICAL 1 2008-11-21 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+
+.SH NAME
+exchange2ical \- Convert Exchange calendar to ical file
+
+.SH SYNOPSIS
+.nf
+exchange2ical [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING]
+  [-P|--password=STRING] [-d|--debuglevel=STRING] [--dump-data]
+.fi
+
+.SH DESCRIPTION
+exchange2ical provides a way to extract appointments from an Exchange calendar
+into the ical format. The ical is provided on stdout.
+
+.SH OPTIONS
+
+.TP
+.B --database
+.TP
+.B -f
+Set the path to the profile database to use
+
+.TP
+.B --profile
+.TP
+.B -p
+Set the profile to use. If no profile is specified, exchange2ical tries
+to retrieve the default profile in the database. If no default profile
+has been set, exchange2ical returns 
+.B MAPI_E_NOT_FOUND .
+
+.TP
+.B --password
+.TP
+.B -P
+Specify the password for the profile to use. This can be omitted if the
+password is stored in the profile.
+
+.TP
+.B --dump-data
+Dump the hex data. This is only required for debugging or educational purposes.
+
+.TP
+.B --debuglevel
+.TP
+.B -d
+Set the debug level.
+
+.SH EXAMPLES
+
+.B Extract appointments from the Exchange calendar:
+.nf
+exchange2ical > appointments.ical
+.fi
+
+.SH REMARKS
+If you are using the default profile database path and have set a
+default profile (using
+.B mapiprofile --profile=profile_name -S
+) you do not need to specify these parameters on the command line.
+
+.SH AUTHOR
+exchange2ical was written by Julien Kerihuel <j.kerihuel at openchange dot org>
+
+This man page was written by Brad Hards <bradh at openchange dot org>

Added: trunk/openchange/doc/man/man1/exchange2mbox.1
===================================================================
--- trunk/openchange/doc/man/man1/exchange2mbox.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/exchange2mbox.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,116 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2007 Julien Kerihuel;
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii exchange2mbox.1
+.\"
+.TH EXCHANGE2MBOX 1 2008-11-14 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+
+.SH NAME
+exchange2mbox \- Convert Exchange mailbox to mbox file
+
+.SH SYNOPSIS
+.nf
+exchange2mbox [-?|--help] [--usage] [-f|--database PATH] [-p|--profile PROFILE]
+    [-P|--password PASSWORD] [-m|--mbox FILENAME] [-u|--update]
+    [-d|--debuglevel LEVEL] [--dump-data]
+.fi
+
+.SH DESCRIPTION
+exchange2mbox provides a way to synchronize an Exchange mailbox with a
+mbox file. The tool is developed so it only retrieves mails not already
+stored in the message ID index database and reflects changes back to
+the Exchange server if the local message copy are deleted.
+
+.SH OPTIONS
+
+.TP
+.B --database
+.TP
+.B -f
+Set the path to the profile database to use
+
+.TP
+.B --profile
+.TP
+.B -p
+Set the profile to use. If no profile is specified, exchange2mbox try
+to retrieve the default profile in the database. If no default profile
+has been set, exchange2mbox returns 
+.B MAPI_E_NOT_FOUND .
+
+.TP
+.B --password
+.TP
+.B -P
+Set the password for the profile to use. This can be omitted if the
+password is stored in the profile.
+
+.TP
+.B --mbox
+.TP
+.B -m
+Set the mbox file full path
+
+.TP
+.B --update
+.TP
+.B -u
+Synchronize the local mbox file with the remote Exchange server mailbox.
+
+.TP
+.B --dump-data
+Dump the hex data. This is only required for debugging or educational purposes.
+
+.TP
+.B --debuglevel LEVEL
+.TP
+.B -d
+Set the debug level.
+
+.SH EXAMPLES
+
+.B Create/Update the mbox file and indexes within the profile database:
+.nf
+exchange2mbox
+.fi
+
+.B Update the Exchange mailbox and indexes according to the changes made to the mbox file.
+
+.nf
+exchange2mbox -u
+.fi
+
+.SH REMARKS
+If no mbox file is specified, one will be automatically created in
+.B $(HOME)/.openchange/mbox .
+If you are using the default profile database path and have set a
+default profile (using
+.B mapiprofile --profile=profile_name -S
+) you do not need to specify these parameters on the command line.
+
+.SH AUTHOR
+Julien Kerihuel <j.kerihuel at openchange dot org>
+
+Brad Hards <bradh at openchange dot org>

Added: trunk/openchange/doc/man/man1/mapiprofile.1
===================================================================
--- trunk/openchange/doc/man/man1/mapiprofile.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/mapiprofile.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,281 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2007-2008 Julien Kerihuel;
+.\" This manpage is Copyright (C)      2008 Brad Hards;
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii mapiprofile.1
+.\"
+.TH MAPIPROFILE 1 2008-12-16 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+
+.SH NAME
+mapiprofile \- administer OpenChange MAPI Profiles databases
+
+.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]
+.fi
+
+.SH DESCRIPTION
+mapiprofile is a command line tool designed to provide administrative
+support for OpenChange MAPI profiles. A profile in this context represents a
+single user's connection to a server. It can be thought of as a user's account
+information stored on the client side. Most OpenChange utilities make use of
+the profile information stored in the local profile database, often by referring
+to the name of the profile. In addition, because most users only have a single
+account, it is possible to designate one profile as the default profile. If a
+profile is not specified, other utilities will use the default profile (if any)
+to establish a connection.
+
+mapiprofile is designed so it also provides sample code for developers interested in
+adding OpenChange MAPI profile support to their applications.
+
+.SH COMMANDS
+
+.TP
+.B --newdb
+.TP
+.B -n
+Create a new database.
+
+.TP
+.B --create
+.TP
+.B -c
+Create a new profile in the database.
+
+.TP
+.B --delete
+.TP
+.B -r
+Delete a profile from the database.
+
+.TP
+.B --rename PROFILE
+.TP
+.B -R
+Rename a profile in the database
+
+.TP
+.B --default
+.TP
+.B -S
+Set the default profile in the database.
+
+.TP
+.B --getdefault
+.TP
+.B -G
+Get the default profile name from the database.
+
+.TP
+.B --dump
+Display information about a specific profile from information stored in the database.
+
+.TP
+.B --list
+.TP
+.B -l
+List existing profiles in the database.
+
+.TP
+.B --listlangs
+.TP
+.B -l
+List the available languages. These can be used to specify the
+language name (--language) when creating a profile.
+
+
+
+.SH OPTIONS
+
+.TP
+.B --database DATABASE
+.TP
+.B -f
+Path to the profile database. If no path database is specified then the default one will be used
+.B $HOME/.openchange/profiles.ldb
+
+.TP
+.B --ldif LDIF
+.TP
+.B -L
+Path to the ldif files. If no ldif directory is specified then the default one set at compilation time will be used. This option is only used when creating a new profile database.
+
+.TP
+.B --profile PROFILE
+.TP
+.B -p
+Set the profile name to use (e.g. the profile to create or delete, or to dump information about).
+
+.TP
+.B --address IP_ADDR|FQDN
+.TP
+.B -I
+Set the Exchange server IP address or fully qualified domain name.
+
+.TP
+.B --workstation WORKSTATION
+.TP
+.B -M
+Sets the local computer name.
+
+.TP
+.B --domain DOMAIN
+.TP
+.B -D
+Set the Windows domain name.
+
+.TP
+.B --realm REALM
+.TP
+.B -R
+Set the Windows realm
+
+.TP
+.B --username
+.TP
+.B -u
+Set the username to use to log on the Exchange server.
+
+.TP
+.B --password
+.TP
+.B -p
+Set the password corresponding to the username described above.
+
+.TP
+.B --langcode
+.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.
+
+.TP
+.B --pattern
+.TP
+.B -s
+Set a username string pattern mapiprofile should use rather than the
+default username. This option is used during mapi profile creation.
+
+.TP
+.B --nopass
+Do not save password in the profile.
+
+.TP
+.B --attr VALUE
+.TP
+.B -a
+Print an attribute value.
+
+.TP
+.B --dump-data
+Dump the hex data.
+
+.TP
+.B --debuglevel LEVEL
+.TP
+.B -d
+Set the debug level.
+
+.TP
+.B --getfqdn
+Returns the DNS fully qualified domain name of the NSPI server matching the legacyDN.
+
+.SH EXAMPLES
+
+.B Create a blank MAPI profile database:
+.nf
+mapiprofile --database=/tmp/profiles2.ldb --ldif=/usr/local/samba/share/setup --newdb
+.fi
+
+.B Create a new profile using NTLMSSP authentication:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel
+     --username=jkerihuel --password=secret --language=0x040C
+     --address=192.168.194.22 --workstation=LOCALHOST --domain=OPENCHANGE 
+     --create
+Profile jkerihuel completed and added to database /tmp/profiles.ldb. Note
+that this account will use French.
+.fi
+
+.B Create a new profile using Kerberos authentication:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel
+     --username=jkerihuel --password=secret --language=0x040C
+     --address=exchange.openchange.local --domain=OPENCHANGE
+     --realm=OPENCHANGE.LOCAL --create
+.fi
+
+
+.B Delete a profile:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --delete
+Profile jkerihuel deleted from database /tmp/profiles.ldb
+.fi
+
+.B List profiles:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --list
+We have 2 profiles in the database:
+        Profile = exchange-2000
+        Profile = jkerihuel
+.fi
+
+.B Dump a profile:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --dump
+Profile: jkerihuel
+	username       == jkerihuel
+	password       == secret
+	mailbox        == /o=First Organization/ou=First Administrative Group/cn=Recipients/cn=jkerihuel
+	workstation    == LOCALHOST
+	domain         == OPENCHANGE
+	server         == exchange.openchange.local
+.fi
+
+.B Dump profile attribute:
+.nf
+mapiprofile --database=/tmp/profiles.ldb --profile=jkerihuel --attr=HomeMDB
+Profile jkerihuel: HomeMDB = /o=First Organization/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=EXCHANGE2000
+.fi
+
+.SH AUTHOR
+Julien Kerihuel <j.kerihuel at openchange dot org>
+
+Brad Hards <bradh at openchange dot org>
+
+.SH "SEE ALSO"
+The codes for various languages can be found in many places, including
+the Windows Language Code Identifier (LCID) Reference.
+

Added: trunk/openchange/doc/man/man1/mapitest.1
===================================================================
--- trunk/openchange/doc/man/man1/mapitest.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/mapitest.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,146 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2008 Brad Hards
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii mapitest.1
+.\"
+.TH MAPITEST 1 2008-11-21 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+
+.SH NAME
+mapitest \- OpenChange torture test utility
+
+.SH SYNOPSIS
+.nf
+mapitest [-?|--help] [--usage] [-f|--database=STRING] [-p|--profile=STRING]
+  [-u|--username=STRING] [-p|--password=STRING] [--confidential] [--color]
+  [-o|--outfile=STRING] [--mapi-calls=STRING] [--list-all] [--no-server]
+  [--dump-data] [-d|--debuglevel=STRING]
+.fi
+
+.SH DESCRIPTION
+mapitest is a test harness / utility used for verifying correct operation
+of various ExchangeRPC calls / MAPI functions provided by the OpenChange
+MAPI libraries.
+
+mapitest is not normally required by users, but you may be asked to provide
+the output of mapitest for some kinds of bug investigations.
+
+Note that mapitest performs a lot of transactions, including deleting folders
+and messages. Unless you're very familiar with mapitest, we recommend only
+using it with a test account.
+
+.SH OPTIONS
+
+.TP
+.B --database
+.TP
+.B -f
+Set the path to the profile database to use
+
+.TP
+.B --profile
+.TP
+.B -p
+Set the profile to use. If no profile is specified, mapitest tries
+to retrieve the default profile in the database. If no default profile
+has been set, mapitest returns 
+.B MAPI_E_NOT_FOUND .
+
+.TP
+.B --username
+.TP
+.B -u
+Set the username of the account to use.
+
+.TP
+.B --password
+.TP
+.B -P
+Specify the password for the profile to use. This can be omitted if the
+password is stored in the profile.
+
+.TP
+.B --confidential
+Remove any sensitive data from the report.
+
+.TP
+.B --color
+Use colors to indicate the results of each operation.
+
+.TP
+.B --outfile
+.TP
+.B -o
+Redirect the output of the tests to a file. The filename must be specified
+as the argument to this option.
+
+.TP
+.B --mapi-calls
+Run a specific test. The name of the test must be specified as the argument
+to this option. See the --list-all option to obtain the name of the test.
+This can be specified more than once in order to run a subset of tests.
+
+.TP
+.B --list-all
+Provide a list of all test suites and test names, along with a description
+of the test. No tests will be run.
+
+.TP
+.B --no-server
+Only run tests that do not require a server connection. This is the default
+if a connection to the server cannot be established.
+
+.TP
+.B --dump-data
+Dump the hex data. This is only required for debugging or educational purposes.
+
+.TP
+.B --debuglevel
+.TP
+.B -d
+Set the debug level.
+
+.SH EXAMPLES
+
+.B Run all tests
+.nf
+mapitest
+.fi
+
+.B Only run two specific tests
+.nf
+mapitest --mapi-calls=NOSERVER-SROWSET --mapi-calls=OXCPRPT-GET-PROPS
+.fi
+
+.SH REMARKS
+If you are using the default profile database path and have set a
+default profile (using
+.B mapiprofile --profile=profile_name -S
+) you do not need to specify these parameters on the command line.
+
+.SH AUTHOR
+mapitest was written by Julien Kerihuel <j.kerihuel at openchange dot org>
+with contributions from other OpenChange developers.
+
+This man page was written by Brad Hards <bradh at openchange dot org>

Added: trunk/openchange/doc/man/man1/openchangeclient.1
===================================================================
--- trunk/openchange/doc/man/man1/openchangeclient.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/openchangeclient.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,562 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2007 Julien Kerihuel;
+.\" This manpage is Copyright (C) 2008 Brad Hards
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii openchangeclient.1
+.\"
+.TH OPENCHANGECLIENT 1 2008-11-24 "OpenChange libmapi 0.8" "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]
+.fi
+
+
+.SH DESCRIPTION
+openchangeclient is a MAPI command line tool designed to facilitate
+mail send, receive and delete operations using the MAPI protocol. It
+also provides operations on tasks, contacts (address book) and calendar
+operations.
+
+.SH COMMANDS
+
+.TP
+.B --fetchmail
+.TP
+.B -F
+Fetch Exchange user mails from the inbox and display general information from
+the mails on the standard output.
+
+.TP
+.B --storemail=DIRECTORY
+.TP
+.B -G
+Store mail attachments to the local filesystem in the specified directory. This
+is the normal way to retrieve attachments.
+
+.TP
+.B --fetch-items=STRING
+.TP
+.B -i
+Retrieve specific items from Exchange default folders. Possible value
+for STRING are Mail, Appointment, Contact, Task, Note.
+
+.TP
+.B --mkdir
+Create a folder within the mailbox or public folders store
+hierarchy. This command requires that the --folder-name option
+be used to specify the name of the folder to create.
+
+.TP
+.B --rmdir
+Deletes a folder within the mailbox or public folders store
+hierarchy. This option requires that the --folder-name option
+be used to specify the name of the folder to delete.
+
+.TP
+.B --mailbox
+.TP
+.B -m
+Display the user mailbox folder hierarchy with folder names, folder
+comments, the folder type, number of unread items in the folder 
+and total number of items in the folder.
+
+.TP
+.B --notifications
+Monitor NEWMAIL notifications in the Inbox folder and display summary
+on standard output.
+
+.TP
+.B --sendmail
+.TP
+.B -S
+Send a mail to a user belonging to the Exchange organization. This
+requires specifying one or more recipients (see the --to, --cc and
+--bcc options), a subject (see the --subject option) and a body
+(see the --body, --html-file and --html-inline options).
+
+.TP
+.B --sendappointment
+Create an appointment in the default calendar folder.
+
+.TP
+.B --sendcontact
+Create a contact in the default contact folder.
+
+.TP
+.B --sendtask
+Create a task in the default task folder.
+
+.TP
+.B --sendnote
+Create a note in the default notes folder.
+
+.TP
+.B --deletemail
+.TP
+.B -D
+Delete a mail from the exchange user mailbox. This requires
+use of the --subject option to specify the mail to be deleted. 
+
+.TP
+.B --userlist
+Display the users listed in the address book.
+
+.TP
+.B --delete=STRING
+Delete a specified item from the store by ID number.
+
+.TP
+.B --ocpf-dump=STRING
+Download a message (specified by the argument, which must be
+the folder ID and unique message ID for the message) as OCPF format.
+The message will be saved to a file given by the message ID, followed
+by a suffix of .ocpf
+
+See the separate (HTML) documentation for libocpf for more information
+on the OCPF format.
+
+.TP
+.B --ocpf-sender
+Send a message given in OCPF format to the server. This requires
+use of the
+.B --ocpf-file
+option to specify the file to load from.
+
+See the separate (HTML) documentation for libocpf for more information
+on the OCPF format.
+
+.TP
+.B --ocpf-syntax
+Check the syntax of an OCPF file. This does not perform any network
+operations. This requires use of the 
+.B --ocpf-file
+option to specify
+the file to load from.
+
+See the separate (HTML) documentation for libocpf for more information
+on the OCPF format.
+
+.SH OPTIONS
+
+.TP
+.B --database=DATABASE
+.TP
+.B -f
+Set the MAPI profile database. If no database is specified, then openchangeclient tries to load the default one: 
+.B $HOME/.openchange/profiles.ldb
+
+.TP
+.B --profile=PROFILE
+.TP
+.B -p
+Set the profile to use. If a profile is not specified, and one of the 
+profiles has been set as the default in the profile database 
+(for example, using mapiprofile -S), then that default profile will be used.
+
+.TP
+.B --password
+.TP
+.B -P
+Specify the password for the profile to be used. This can be omitted if the
+password is stored in the profile.
+
+.TP
+.B --pf
+Perform operations against the Public Folders store, rather than the normal
+operations against a user's private folders.
+
+.TP
+.B --folder
+Specify the folder name we want to work with want to open. This option
+is mandatory for public folders, but can also be used to open specific
+folders in the mailbox store.
+
+.TP
+.B --attachments="ATTACHMENT1;ATTACHMENT2"
+.TP
+.B -A
+Set attachments to send when sending a mail. Attached filenames need
+to be separated with
+.B semi-colons
+as specified in the description above. This is only meaningful with
+.B --sendmail
+
+.TP
+.B --subject=STRING
+.TP
+.B -s
+Specify the mail subject. If no subject is specified, the mail subject will be empty.
+This is only meaningful with
+.B --sendmail
+
+.TP
+.B --body=STRING
+.TP
+.B -B
+Set the body of the mail to be the UTF8 text only content specified on the command
+line. This is only meaningful with
+.B --sendmail
+
+.TP
+.B --html-inline=STRING
+.TP
+.B -I
+Set the body of the mail to be the HTML content specified on command line. This is
+only meaningful with
+.B --sendmail
+
+.TP
+.B --html-file=FILENAME
+.TP
+.B -W
+Set the body of the mail to be the content of the specified file. This is only
+meaningful with
+.B --sendmail
+
+.TP
+.B --to="USERNAME1,USERNAME2"
+.TP
+.B -t
+Specify
+.B To
+recipients for the mail. Usernames need to be separated with commas
+as specified in the example above. This is only meaningful with
+.B --sendmail
+
+.TP
+.B --cc="USERNAME1,USERNAME2"
+.TP
+.B -c
+Specify
+.B Cc
+recipients for the mail. Usernames need to be separated with commas
+as specified in the example above. This is only meaningful with
+.B --sendmail
+
+.TP
+.B --bcc="USERNAME1,USERNAME2"
+.TP
+.B -b
+Specify
+.B Bcc
+recipients for the mail. Usernames need to be separated with commas
+as specified in the example above. This is only meaningful with
+.B --sendmail
+
+.TP
+.B --location=STRING
+Specify the appointment location. This is only meaningful with
+.B --sendappointment
+
+.TP
+.B --dtstart=STRING
+Specify the start date of an event. The following date format needs to be used:
+.B "%Y-%m-%d %H:%M:%S"
+e.g: 2007-06-01 14:59:00. This is only meaningful with
+.B --sendappointment
+and
+.B --sendtask
+
+.TP
+.B --dtend=STRING
+Specify either the end date or due date of an event. The following date
+format needs to be used:
+.B "%Y-%m-%d %H:%M:%S"
+e.g: 2007-06-01 14:59:00
+When no
+.B dtend
+parameter is specified, default value is set to
+.B dtstart
+This is only meaningful with
+.B --sendappointment
+and
+.B --sendtask
+
+.TP
+.B --force
+Add appointment to the calendar, even if it would overlap with
+an existing appointment. This is only meaningful with
+.B --sendappointment
+
+.TP
+.B --private
+Mark the appointment as private event. This is only meaningful with
+.B --sendappointment
+
+.TP
+.B --busystatus=STRING
+Set the busy status of an appointment. Possible values are FREE,
+TENTATIVE, BUSY or OUTOFOFFICE. This is only meaningful with
+.B --sendappointment
+
+.TP
+.B --label=STRING
+Set the type of appointment. Possible values are NONE, IMPORTANT,
+BUSINESS, PERSONAL, VACATION, MUST_ATTEND, TRAVEL_REQUIRED,
+NEEDS_PREPARATION, BIRTHDAY, ANNIVERSARY and PHONE_CALL.
+This is only meaningful with
+.B --sendappointment
+
+.TP
+.B --taskstatus=STRING
+Set the status of a task. Possible values are NOTSTARTED, PROGRESS,
+COMPLETED, WAITING, DEFERRED. This is only meaningful with
+.B --sendtask
+
+.TP
+.B --fullname=STRING
+Set the full name in a contact message. This is only meaningful with
+.B --sendcontact
+
+.TP
+.B --cardname=STRING
+Set the card name of a task or contact message. This is only meaningful with
+.B --sendcontact
+or
+.B --sendtask
+
+.TP
+.B --email=STRING
+Set the email address in a contact message. This is only meaningful with
+.B --sendcontact
+
+.TP
+.B --importance=STRING
+Set the relative importance of a task. Possible values are LOW, NORMAL
+and HIGH. This is only meaningful with
+.B --sendtask
+
+.TP
+.B --color=STRING
+Set the color of the note. The default color is Yellow. Other options
+are Blue, Green, Pink and White. This is only meaningful with
+.B --sendnote
+
+.TP
+.B --folder-name=STRING
+Set the folder name to create. This is only meaningful with 
+.B --mkdir 
+or 
+.B --rmdir
+
+.TP
+.B --folder-comment=STRING
+Set the folder comment. This is only meaningful with
+.B --mkdir
+
+.TP
+.B --update=STRING
+.TP
+.B -u
+Change (update) an existing item, rather than creating a new one. This
+is only meaningful with
+.B --sendtask
+, 
+.B --sendnote
+,
+.B --sendappointment
+and
+.B --sendcontact
+
+.TP
+.B --ocpf-file=STRING
+Specify the file to load OCPF data from. This is only meaningful with
+.B --ocpf-sender
+and
+.B --ocpf-syntax
+
+.TP
+.B --dump-data
+Display raw format data associated with the operation. You normally only
+need this when debugging.
+
+.TP
+.B --debug-level=LEVEL
+Display debugging information at the specified level (or higher). Level
+10 is a lot of debug information.
+
+
+.SH EXAMPLES
+
+.B Fetching emails:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000 --fetchmail
+.fi
+
+.B Fetch emails and store attachments:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000 --fetchmail --storemail=test
+.fi
+
+All attachments from any mails will be stored in the test
+directory. If the specified directory does not exist, it will
+automatically be created. Note that if the attachment name
+is not unique amongst all emails, some attachments may be 
+overwritten. 
+
+
+.B Send a basic email:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000 
+                 --to="Adm,jker" --cc=Paul --bcc=Bill 
+                 --subject="It is working"
+                 --body="This is a sample body" --sendmail
+.fi
+
+A mail with UTF8 (text only) content will be sent with the following recipients:
+
+to = Administrator and jkerihuel
+
+cc = Paul
+
+bcc = Bill
+
+
+.B Send an inline HTML email:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000
+                 --to=Adm --subject="Inline HTML sample email"
+                 --html-inline="<body bgcolor=yellow><h1>My first HTML email</h1></body>"
+                 --sendmail
+.fi
+
+Administrator will receive a mail with HTML body - yellow background and a title.
+
+
+.B Send a HTML mail using a file:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000
+                 --to=Adm --subject="HTML file email"
+                 --html-file=/tmp/myfile.html
+                 --sendmail
+.fi
+
+The content of /tmp/myfile.html will be used to fill the HTML body. If
+the HTML file exceed a fixed size (0x4000 bytes), then PR_HTML content
+will be sent using MAPI streams.
+
+
+.B Send email with attachments:
+.nf
+openchangeclient --database=/tmp/profiles.ldb --profile=2000
+                 --to=Adm --subject="Attachments"
+                 --attachments="/tmp/file1.jpg;/tmp/file2.jpg;tmp/file2.jpg"
+                 --body="These are sample attachments"
+                 --sendmail
+.fi
+
+The example above will send a UTF8 body mail to Administrator and
+attach file1,jpg, file2.jpg and file3.jpg to the email.
+
+.B Display the users in the address book
+.nf
+openchangeclient --userlist
+.fi
+
+.B Fetch calendar items:
+.nf
+openchangeclient --fetch-items=Appointment
+.fi
+
+
+.B Fetch contact items:
+.nf
+openchangeclient --fetch-items=Contact
+.fi
+
+
+.B Fetch task items:
+.nf
+openchangeclient --fetch-items=Task
+.fi
+
+
+.B Create appointment:
+.nf
+openchangeclient --sendappointment --dtstart="2007-06-01 22:00:00" \\
+                 --dtend="2007-06-01 22:35:00"                     \\
+                 --busystatus=FREE                                 \\
+                 --location="Home"                                 \\
+                 --subject="Check the Junk folder"
+.fi
+
+
+.B Create Task:
+.nf
+openchangeclient --sendtask --dtstart="2008-11-01 18:00:00"        \\
+                 --cardname="openchangeclient" --importance=HIGH   \\
+                 --taskstatus=COMPLETED --body="my new task"
+.fi
+
+
+.B Create contact:
+.nf
+openchangeclient --sendcontact --cardname="openchangeclient"       \\
+                 --fullname="OpenChange Client 3rd"                \\
+                 --email="openchangeclient at nonexistentdomain.com"  
+.fi
+
+.B Create folder:
+.nf
+openchangeclient --mkdir --folder-name="openchange"		   \\
+		 --folder-comment="comment"
+.fi
+
+This example will create a generic folder named openchange under the
+Inbox folder.
+
+.B Delete folder:
+.nf
+openchangeclient --rmdir --folder-name="openchange"
+.fi
+
+This example will delete the generic folder named openchange under
+Inbox folder.
+
+.B List Mailbox hierarchy:
+.nf
+openchangeclient --mailbox
+.fi
+
+.SH AUTHOR
+Julien Kerihuel <j.kerihuel at openchange dot org>

Added: trunk/openchange/doc/man/man1/openchangepfadmin.1
===================================================================
--- trunk/openchange/doc/man/man1/openchangepfadmin.1	                        (rev 0)
+++ trunk/openchange/doc/man/man1/openchangepfadmin.1	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,267 @@
+.\" OpenChange Project Tools Man Pages
+.\"
+.\" This manpage is Copyright (C) 2007 Julien Kerihuel;
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii openchangepfadmin.1
+.\"
+.TH OPENCHANGEPFADMIN 1 2007-11-14 "OpenChange libmapi 0.8" "OpenChange Users' Manual"
+
+.SH NAME
+openchangepfadmin \- Exchange users and Public Folder administration tool
+
+.SH SYNOPSIS
+.nf
+openchangepfadmin [-?] [-?|--help] [--usage] [-f|--database PATH] [-p|--profile PROFILE]
+    [-P|--password PASSWORD] [--apassword=PASSWORD] [--adesc=DESCRIPTION] [--acomment=COMMENT]
+    [--afullname=NAME] [--list] [--mkdir] [--rmdir] [--comment=COMMENT] [--dirclass=CLASS]
+    [--adduser=USERNAME] [--rmuser=USERNAME] [--addright=RIGHT] [--rmright] [--modright=RIGHT]
+    [--debuglevel=LEVEL] [--dump-data] [--folder=FOLDER] [--username=USERNAME]
+.fi
+
+.SH DESCRIPTION
+openchangepfadmin is a administrative command line tool designed to
+facilitate user management related operations (create, delete, modify)
+on a remote Exchange server and manage public folder store and
+permissions.
+
+.SH COMMANDS
+
+.TP
+.B --adduser=USERNAME
+Create a Exchange user with the username specified by USERNAME
+
+.TP
+.B --rmuser=USERNAME
+Delete the Exchange user account specified by USERNAME
+
+.TP
+.B --list
+List Public Folder hierarchy (IPM_SUBTREE)
+
+.TP
+.B --mkdir
+Create a folder in the Public Folder store
+
+.TP
+.B --rmdir
+Delete a folder in the Public Folder store
+
+.TP
+.B --addright=RIGHT
+Add permission and roles for a user on a Public Folder directory. 
+
+.TP
+.B --modright=RIGHT
+Modify permissions and roles for a user on a Public Folder directory
+
+.TP
+.B --rmright
+Delete permissions and roles for a specific user
+
+
+.SH OPTIONS
+
+.TP
+.B --database=DATABASE
+.TP
+.B -f
+Set the MAPI profile database. If no database is specified, then
+openchangeclient tries to load the default one:
+.B $HOME/.openchange/profiles.ldb
+
+.TP
+.B --profile=PROFILE
+.TP
+.B -p
+Set the profile to use. If a profile is not specified, and one of the
+profiles has been set as the default in the profile database (for
+example, using mapiprofile -S), then that default profile will be
+used.
+
+.TP
+.B --password
+.TP
+.B -P
+Set the password for the profile to use. This can be omitted if the
+password is stored in the profile.
+
+.TP
+.B --apassword=PASSWORD
+Define the password to set for the user specified with --adduser. If
+no password is explicitely supplied, openchangepfadmin will arbitrary
+set a random one.
+
+.TP
+.B --adesc=DESCRIPTION
+This command can only be used with --adduser and specifies a
+description for this account
+
+.TP
+.B --acomment=COMMENT
+This command can only be used with --adduser and specifies a comment
+for this account.
+
+.TP
+.B --afullname=NAME
+This command can only be used with --adduser and specifies the user
+full name for this account.
+
+.TP
+.B --comment=COMMENT
+This command can only be used with --mkdir and specifies a comment for
+the folder.
+
+.TP
+.B --dirclass=CLASS
+This command can only be used with --mkdir and specifies the container
+class of the directory we want to create. Possible values are:
+IPF.Appointment, IPF.Contact, IPF.Journal, IPF.Note, IPF.StickyNote,
+IPF.Task, IPF.Post
+
+.TP
+.B --folder=FOLDER
+This command can only be used with --addright, --modright and
+--rmright. Specify the folder where permissions and roles have to be
+changed.
+
+.TP
+.B --username=USERNAME
+This command can only be used with --addright, --modright and
+--rmright. Specify the username we want to change permissions and
+roles for.
+
+.TP
+.B --dump-data
+Dump the hex data. This is only required for debugging or educational purposes.
+
+.TP
+.B --debuglevel LEVEL
+.TP
+.B -d
+Set the debug level.
+
+.SH EXAMPLES
+
+.B Creating user
+.nf
+openchangepfadmin --adduser=linuxowner --apassword=linuxowner   \\
+                    --adesc="Linux Owner Test account"          \\
+		    --afullname="Linux Owner"
+    mapiadmin_user_add       : MAPI_E_SUCCESS (0x0)
+username: linuxowner
+password: linuxowner
+.fi
+
+Creates a user account with username and password set to linuxowner.
+
+.B Deleting user:
+.nf
+openchangepfadmin --rmuser=linuxowner
+    mapiadmin_user_del       : MAPI_E_SUCCESS (0x0)
+.fi
+
+.B Create Public Folder:
+.nf
+openchangepfadmin --mkdir --folder=public_events --dirclass=IPF.Appointment
+.fi
+
+Creates a folder in the Public Folder store named public_events with a
+container class set to Appointment. This folder will display calendar
+items.
+
+.B Delete Public Folder:
+.nf
+openchangepfadmin --rmdir --folder=public_events
+.fi
+
+.B List Public Folder hierarchy:
+.nf
+openchangepfadmin --list
+.fi
+
+.B Add Permission:
+.nf
+openchangepfadmin --username=linuxowner --folder=public_events \\
+                    --addright=RoleOwner
+Permission RoleOwner added for linuxowner on folder public_events
+.fi
+
+.B Modify Permission
+.nf
+openchangepfadmin --username=Anonymous --folder=public_events \\
+  		    --modright=RoleNone
+Permission changed to RoleNone for Anonymous on folder appointment
+.fi
+
+Note that you can only change permissions for a user already listed in
+the ACL table.
+
+.SH NOTE
+Permissions and Roles possible values are:
+.IP "\(bu" 2
+RightsNone                    
+.IP "\(bu" 2
+RightsReadItems               
+.IP "\(bu" 2
+RightsCreateItems             
+.IP "\(bu" 2
+RightsEditOwn                 
+.IP "\(bu" 2
+RightsDeleteOwn               
+.IP "\(bu" 2
+RightsEditAll
+.IP "\(bu" 2    
+RightsDeleteAll
+.IP "\(bu" 2
+RightsCreateSubfolders
+.IP "\(bu" 2
+RightsFolderOwner
+.IP "\(bu" 2
+RightsFolderContact
+.IP "\(bu" 2
+RoleNone
+.IP "\(bu" 2
+RoleReviewer
+.IP "\(bu" 2
+RoleContributor
+.IP "\(bu" 2
+RoleNoneditingAuthor
+.IP "\(bu" 2
+RoleAuthor
+.IP "\(bu" 2
+RoleEditor
+.IP "\(bu" 2
+RolePublishAuthor
+.IP "\(bu" 2
+RolePublishEditor
+.IP "\(bu" 2
+RightsAll
+.IP "\(bu" 2
+RoleOwner			
+
+.SH SEE ALSO
+AddUserPermission, ModifyUserPermission, RemoveUserPermission
+
+.SH AUTHOR
+Julien Kerihuel <j.kerihuel at openchange dot org>

Added: trunk/openchange/doc/man/man3/mapidump.3
===================================================================
--- trunk/openchange/doc/man/man3/mapidump.3	                        (rev 0)
+++ trunk/openchange/doc/man/man3/mapidump.3	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,47 @@
+.\" OpenChange Project Libraries Man Pages
+.\"
+.\" This manpage is Copyright (C) 2007 Julien Kerihuel;
+.\"
+.\" Permission is granted to make and distribute verbatim copies of this
+.\" manual provided the copyright notice and this permission notice are
+.\" preserved on all copies.
+.\"
+.\" Permission is granted to copy and distribute modified versions of this
+.\" manual under the conditions for verbatim copying, provided that the
+.\" entire resulting derived work is distributed under the terms of a
+.\" permission notice identical to this one.
+.\" 
+.\" Since the OpenChange and Samba4 libraries are constantly changing, this
+.\" manual page may be incorrect or out-of-date.  The author(s) assume no
+.\" responsibility for errors or omissions, or for damages resulting from
+.\" the use of the information contained herein.  The author(s) may not
+.\" have taken the same level of care in the production of this manual,
+.\" which is licensed free of charge, as they might when working
+.\" professionally.
+.\" 
+.\" Formatted or processed versions of this manual, if unaccompanied by
+.\" the source, must acknowledge the copyright and authors of this work.
+.\"
+.\" Process this file with
+.\" groff -man -Tascii mapidump.3
+.\"
+.TH MAPIDUMP 3 2007-04-23 "OpenChange libmapi 0.2" "OpenChange Programmer's Manual"
+.SH NAME
+mapidump API \- dump MAPI data and object on stdout
+.SH SYNOPSIS
+.nf
+.B #include <libmapi/libmapi.h>
+.sp
+.BI "void mapidump_SPropValue(struct SPropValue " lpProp ", const char *" sep ");"
+.BI "void mapidump_SPropTagArray(struct SPropTagArray *" proptags ");"
+.BI "void mapidump_SRow(struct SRow *" aRow ", const char *" sep ");"
+.BI "void mapidump_Recipients(const char **" usernames ", struct SRowSet *" rowset ", struct FlagList *" flaglist ");"
+.BI "void mapidump_message(struct mapi_SPropValue_array *" properties ");"
+.fi
+.SH DESCRIPTION
+These functions dumps MAPI data structures and high level objects on stdout. The
+.IR sep
+parameters describes a parameter used in output format.
+
+.SH AUTHOR
+Julien Kerihuel <j.kerihuel at openchange dot org>

Added: trunk/openchange/exchange.idl
===================================================================
--- trunk/openchange/exchange.idl	                        (rev 0)
+++ trunk/openchange/exchange.idl	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,3699 @@
+#include "idl_types.h"
+
+cpp_quote("#include <gen_ndr/ndr_misc.h>")
+
+/*
+   http://support.microsoft.com/default.aspx?scid=KB;en-us;q159298
+   Any UUID starting with:
+   A4 - store
+   F5 - directory
+ */
+
+[
+  uuid("99e64010-b032-11d0-97a4-00c04fd6551d"),
+  pointer_default(unique),
+  version(3.0)
+] interface exchange_store_admin3
+{
+	void ec_store_admin3_dummy();
+}
+
+
+[
+  uuid("89742ace-a9ed-11cf-9c0c-08002be7ae86"),
+  pointer_default(unique),
+  version(2.0)
+] interface exchange_store_admin2
+{
+	void ec_store_admin2_dummy();
+}
+
+[
+  uuid("a4f1db00-ca47-1067-b31e-00dd010662da"),
+  pointer_default(unique),
+  version(1.0)
+] interface exchange_store_admin1
+{
+	void ec_store_admin1_dummy();
+}
+
+
+[
+  uuid("1544f5e0-613c-11d1-93df-00c04fd7bd09"),
+  endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:[]"),
+  pointer_default(unique),
+  version(1.0),
+  helpstring("Exchange 2003 Directory Request For Response")
+] interface exchange_ds_rfr
+{
+
+#include "mapitags_enum.h"
+#include "mapicodes_enum.h"
+
+	/*****************/
+	/* Function 0x00 */
+	MAPISTATUS RfrGetNewDSA(
+		[in]                                    uint32  ulFlags,
+		[in,string,charset(DOS)]                uint8   *pUserDN,
+		[in,out,unique,string,charset(DOS)]     uint8   **ppszUnused,
+		[in,out,unique,string,charset(DOS)]     uint8   **ppszServer
+		);
+	
+	/*****************/
+	/* Function 0x01 */
+	MAPISTATUS RfrGetFQDNFromLegacyDN(
+		[in]							uint32	ulFlags,
+		[in,range(10,1024)]					uint32	cbMailboxServerDN,
+		[in,string,charset(DOS),size_is(cbMailboxServerDN)]	uint8	*szMailboxServerDN,
+		[out,ref,string,charset(DOS)]				uint8	**ppszServerFQDN
+		);
+}
+
+[
+  uuid("f930c514-1215-11d3-99a5-00a0c9b61b04"),
+  helpstring("System Attendant Cluster Interface"),
+  pointer_default(unique),
+  version(1.0)
+] interface exchange_sysatt_cluster
+{
+	void sysatt_cluster_dummy();
+}
+
+/*
+[83d72bf0-0d89-11ce-b13f-00aa003bac6c] MS Exchange
+System Attendant Private Interface
+*/
+
+[
+  uuid("469d6ec0-0d87-11ce-b13f-00aa003bac6c"),
+  pointer_default(unique),
+  helpstring("Exchange 5.5 System Attendant Request for Response")
+] interface exchange_system_attendant
+{
+	void sysatt_dummy();
+}
+
+[
+  uuid("9e8ee830-4559-11ce-979b-00aa005ffebe"),
+  pointer_default(unique),
+  version(2.0),
+  helpstring("Exchange 5.5 MTA")
+] interface exchange_mta
+{
+	/*****************/
+	/* Function 0x00 */
+	void MtaBind();
+
+	/*****************/
+	/* Function 0x01 */
+	void MtaBindAck();
+}
+
+[
+  uuid("f5cc59b4-4264-101a-8c59-08002b2f8426"),
+  pointer_default(unique),
+  version(21.0),
+  helpstring("Exchange 5.5 DRS")
+] interface exchange_drs
+{
+	/*****************/
+	/* Function 0x00 */
+	void ds_abandon();
+
+	/*****************/
+	/* Function 0x01 */
+	void ds_add_entry();
+
+	void ds_bind();
+	void ds_compare();
+	void ds_list();
+	void ds_modify_entry();
+	void ds_modify_rdn();
+	void ds_read();
+	void ds_receive_result();
+	void ds_remove_entry();
+	void ds_search();
+	void ds_unbind();
+	void ds_wait();
+	void dra_replica_add();
+	void dra_replica_delete();
+	void dra_replica_synchronize();
+	void dra_reference_update();
+	void dra_authorize_replica();
+	void dra_unauthorize_replica();
+	void dra_adopt();
+	void dra_set_status();
+	void dra_modify_entry();
+	void dra_delete_subref();
+}
+
+[
+  uuid("f5cc5a7c-4264-101a-8c59-08002b2f8426"),
+  version(21.0),
+  pointer_default(unique),
+  helpstring("Exchange 5.5 XDS")
+] interface exchange_xds
+{
+	void xds_dummy();
+}
+
+[
+  uuid("38a94e72-a9bc-11d2-8faf-00c04fa378ff"),
+  pointer_default(unique),
+  version(1.0)
+] interface exchange_mta_qadmin
+{
+	void exchange_mta_qadmin();
+}
+
+
+[
+  uuid("0e4a0156-dd5d-11d2-8c2f-00c04fb6bcde"),
+  pointer_default(unique),
+  version(1.0)
+] interface exchange_store_information
+{
+	void exchange_store_information_dummy();
+}
+
+[
+  uuid("f5cc5a18-4264-101a-8c59-08002b2f8426"),
+  endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:[]"),
+  pointer_default(unique),
+  version(56.0),
+  helpstring("Exchange 5.5 Name Service Provider")
+] interface exchange_nsp
+{
+
+#define	PT_UNSPECIFIED	0x0000
+#define	PT_NULL		0x0001
+#define	PT_I2		0x0002
+#define	PT_LONG		0x0003
+#define	PT_R4		0x0004
+#define	PT_DOUBLE	0x0005
+#define	PT_CURRENCY	0x0006
+#define	PT_APPTIME	0x0007
+#define	PT_ERROR	0x000a /* means the given attr contains no value */
+#define	PT_BOOLEAN	0x000b
+#define	PT_OBJECT	0x000d
+#define	PT_I8		0x0014
+#define	PT_STRING8	0x001e
+#define	PT_UNICODE	0x001f
+#define	PT_SYSTIME	0x0040
+#define	PT_CLSID       	0x0048
+#define	PT_SVREID	0x00fb
+#define	PT_SRESTRICT	0x00fd
+#define	PT_ACTIONS	0x00fe
+#define	PT_BINARY	0x0102
+/* Multi-valued properties */
+#define	PT_MV_I2       	0x1002
+#define	PT_MV_LONG     	0x1003
+#define	PT_MV_R4       	0x1004
+#define	PT_MV_DOUBLE   	0x1005
+#define	PT_MV_CURRENCY 	0x1006
+#define	PT_MV_APPTIME  	0x1007
+#define	PT_MV_I8       	0x1014
+#define	PT_MV_STRING8	0x101e
+#define	PT_MV_TSTRING	0x101e
+#define	PT_MV_UNICODE	0x101f
+#define	PT_MV_SYSTIME	0x1040
+#define	PT_MV_CLSID	0x1048
+#define	PT_MV_BINARY	0x1102
+
+	typedef [v1_enum] enum {
+		SortTypeDisplayName		= 0x00000000,
+		SortTypePhoneticDisplayName	= 0x00000003,
+		SortTypeDisplayName_RO		= 0x000003E8,
+		SortTypeDisplayName_W		= 0x000003E9
+	} TableSortOrders;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableSortOrders	SortType;
+		uint32		ContainerID;
+		uint32		CurrentRec;
+		uint32		Delta;
+		uint32		NumPos;
+		uint32		TotalRecs;
+		uint32		CodePage;
+		uint32		TemplateLocale;
+		uint32		SortLocale;
+	} STAT;
+
+	typedef struct {
+		uint8 ab[16];
+	} FlatUID_r;
+
+	typedef struct {
+		FlatUID_r	*lpguid;
+		uint32		ulReserved;
+		uint32		lID;
+	} PropertyName_r;
+
+	typedef struct {
+		[range(0,100000)] uint32		cNames;
+		[size_is(cNames)] PropertyName_r	aNames[];
+	} PropertyNameSet_r;
+
+	typedef struct {
+		[range(0,100000)] uint32			cValues;
+		[string,size_is(cValues),charset(DOS)] uint8	**lppszA;
+	} StringArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32		       	Count;
+		[string,size_is(Count),charset(DOS)] uint8     	*Strings[];
+	} StringsArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32			cValues;
+		[string,size_is(cValues),charset(UTF16)] uint16	**lppszW;
+	} WStringArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32		       	Count;
+		[string,size_is(Count),charset(UTF16)] uint16  	*Strings[];
+	} WStringsArray_r;
+
+	typedef struct {
+		[range(0,100001)] uint32       				cValues;
+		[size_is(cValues+1),length_is(cValues)] MAPITAGS	aulPropTag[];
+	} SPropTagArray;
+
+	typedef [public] struct {
+		[range(0,2097152)] uint32      	cb;
+		[size_is(cb)] uint8		*lpb;
+	} Binary_r;
+
+	typedef [public] struct {
+		uint32 dwLowDateTime;
+		uint32 dwHighDateTime;
+	} FILETIME;
+
+	typedef struct {
+		[range(0,100000)] uint32	cValues;
+		[size_is(cValues)] uint16	*lpi;
+	} ShortArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32	cValues;
+		[size_is(cValues)] uint32	*lpl; 
+	} LongArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32	cValues;
+		[size_is(cValues)] Binary_r	*lpbin;
+	} BinaryArray_r;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		[range(0,100000)]uint32		cValues;
+		[size_is(cValues)] FlatUID_r	**lpguid; 
+	} FlatUIDArray_r;
+
+	typedef struct {
+		[range(0,100000)] uint32	cValues;
+		[size_is(cValues)] FILETIME	*lpft;
+	} DateTimeArray_r;
+
+	typedef [switch_type(uint32)] union {
+		[case(PT_I2)]			uint16			i;
+		[case(PT_LONG)]			uint32			l;
+		[case(PT_DOUBLE)]		dlong			dbl;
+		[case(PT_BOOLEAN)]		uint8			b;
+		[case(PT_I8)]			dlong			d;
+		[case(PT_STRING8)][unique][string,charset(DOS)] uint8	*lpszA;
+		[case(PT_BINARY)]		Binary_r       		bin;
+		[case(PT_UNICODE)][string,charset(UTF16)] uint16	*lpszW;
+		[case(PT_CLSID)]		FlatUID_r      		*lpguid;
+		[case(PT_SYSTIME)]		FILETIME		ft;
+		[case(PT_ERROR)]		MAPISTATUS		err;
+		[case(PT_MV_I2)]		ShortArray_r		MVi;
+		[case(PT_MV_LONG)]		LongArray_r		MVl;
+		[case(PT_MV_STRING8)]		StringArray_r		MVszA;
+		[case(PT_MV_BINARY)]		BinaryArray_r		MVbin;
+		[case(PT_MV_CLSID)]		FlatUIDArray_r		MVguid;
+		[case(PT_MV_UNICODE)]		WStringArray_r		MVszW;
+		[case(PT_MV_SYSTIME)]		DateTimeArray_r		MVft;
+		[case(PT_NULL)]			uint32			null;
+		[case(PT_OBJECT)]		uint32			object;
+	} SPropValue_CTR;
+
+	typedef [public]struct {
+		MAPITAGS ulPropTag;
+		uint32 dwAlignPad;
+		[switch_is(ulPropTag & 0xFFFF)] SPropValue_CTR value; 
+	} SPropValue;
+	
+	typedef struct {
+		uint32			       	ulAdrEntryPad;
+		[range(0,100000)] uint32       	cValues;
+		[size_is(cValues)]SPropValue	*lpProps;
+	} SRow;
+
+
+	typedef [public] struct {
+		[range(0,100000)] uint32	cRows;
+		[size_is(cRows)] SRow		aRow[];
+	} SRowSet;
+	
+	typedef struct {
+		[range(0,100000)] uint32		cRes;
+		[size_is(cRes)] Restriction_r		*lpRes;
+	} AndRestriction_r;
+
+	typedef struct {
+		[range(0,100000)] uint32		cRes;
+		[size_is(cRes)] Restriction_r		*lpRes;
+	} OrRestriction_r;
+
+	typedef struct {
+		Restriction_r				*lpRes;
+	} NotRestriction_r;
+
+	typedef struct {
+		uint32					ulFuzzyLevel;
+		MAPITAGS       				ulPropTag;
+		SPropValue				*lpProp;
+	} ContentRestriction_r;
+
+	typedef struct {
+		uint32					relop;
+		MAPITAGS				ulPropTag;
+		SPropValue				*lpProp;
+	} PropertyRestriction_r;
+
+	typedef struct {
+		uint32					relop;
+		MAPITAGS				ulPropTag1;
+		MAPITAGS				ulPropTag2;
+	} ComparePropsRestriction_r;
+
+	typedef struct {
+		uint32					relMBR;
+		MAPITAGS				ulPropTag;
+		uint32					ulMask;
+	} BitMaskRestriction_r;
+
+	typedef struct {
+		uint32					relop;
+		MAPITAGS				ulPropTag;
+		uint32					cb;
+	} SizeRestriction_r;
+
+	typedef struct {
+		uint32					ulReserved1;
+		MAPITAGS				ulPropTag;
+		uint32					ulReserved2;
+	} ExistRestriction_r;
+
+	typedef struct {
+		uint32					ulSubObject;
+		Restriction_r				*lpRes;
+	} SubRestriction_r;
+
+	typedef [v1_enum] enum {
+		RES_AND			= 0x0,
+		RES_OR			= 0x1,
+		RES_NOT			= 0x2,
+		RES_CONTENT		= 0x3,
+		RES_PROPERTY		= 0x4,
+		RES_COMPAREPROPS	= 0x5,
+		RES_BITMASK		= 0x6,
+		RES_SIZE		= 0x7,
+		RES_EXIST		= 0x8,
+		RES_SUBRESTRICTION	= 0x9,
+		RES_COMMENT		= 0xA
+	} RestrictionType_r;
+
+	typedef [switch_type(uint32)] union {
+		[case(RES_AND)]			AndRestriction_r		resAnd;
+		[case(RES_OR)]			OrRestriction_r			resOr;
+		[case(RES_NOT)]			NotRestriction_r		resNot;
+		[case(RES_CONTENT)]		ContentRestriction_r		resContent;
+		[case(RES_PROPERTY)]		PropertyRestriction_r		resProperty;
+		[case(RES_COMPAREPROPS)]	ComparePropsRestriction_r	resCompareProps;
+		[case(RES_BITMASK)]		BitMaskRestriction_r		resBitMask;
+		[case(RES_SIZE)]		SizeRestriction_r		resSize;
+		[case(RES_EXIST)]		ExistRestriction_r		resExist;
+		[case(RES_SUBRESTRICTION)]	SubRestriction_r		resSub;
+	} RestrictionUnion_r;
+
+	typedef [public] struct _Restriction_r{
+		RestrictionType_r      			rt;
+		[switch_is(rt)] RestrictionUnion_r	res;
+	} Restriction_r;
+
+	/*****************/
+	/* Function 0x00 */
+	typedef [bitmap32bit] bitmap {
+		fAnonymousLogin	= 0x00000020
+	} NspiBind_dwFlags;
+
+	MAPISTATUS NspiBind(
+		[in] NspiBind_dwFlags	dwFlags,
+		[in] STAT		*pStat,
+		[in,out,unique] GUID   	*mapiuid,
+		[out] policy_handle    	*handle
+		);
+
+	/*****************/
+	/* Function 0x01 */
+	MAPISTATUS NspiUnbind(
+		[in, out] policy_handle	*handle,
+		[in] uint32	       	Reserved
+		);
+
+	/*****************/
+	/* Function 0x02 */
+	MAPISTATUS NspiUpdateStat(
+		[in] policy_handle	*handle,
+		[in] uint32		Reserved,
+		[in,out] STAT		*pStat,
+		[in,out,unique] uint32	*plDelta
+		);
+
+	/*****************/
+	/* Function 0x03 */
+	typedef [bitmap32bit] bitmap {
+		fSkipObjects	= 0x00000001,
+		fEphID		= 0x00000002
+	} NspiQueryRows_dwFlags;
+
+	MAPISTATUS NspiQueryRows(
+		[in]					policy_handle			*handle,
+		[in]					NspiQueryRows_dwFlags		dwFlags,
+		[in,out]				STAT				*pStat,
+		[in,range(0,100000)]			uint32				dwETableCount,
+ 		[in,unique,size_is(dwETableCount)]	uint32				*lpETable,
+		[in]					uint32				Count,
+		[in,unique]    				SPropTagArray			*pPropTags,
+		[out]					SRowSet				**ppRows
+		);
+
+	/*****************/
+	/* Function 0x04 */
+	MAPISTATUS NspiSeekEntries(
+		[in]		policy_handle	*handle,
+		[in]		uint32		Reserved,
+		[in,out]	STAT		*pStat,
+		[in]		SPropValue     	*pTarget,
+		[in,unique]	SPropTagArray	*lpETable,
+		[in,unique]	SPropTagArray	*pPropTags,
+		[out]		SRowSet		**pRows
+		);
+
+	/*****************/
+	/* Function 0x05 */
+	MAPISTATUS NspiGetMatches(
+		[in]		policy_handle	*handle,
+		[in]		uint32		Reserved,
+		[in,out]	STAT		*pStat,
+		[in][unique]	SPropTagArray	*pReserved,
+		[in]		uint32	       	Reserved2,
+		[in][unique]	Restriction_r	*Filter,
+ 		[in][unique]	PropertyName_r	*lpPropName,
+		[in]		uint32		ulRequested,
+		[out]		SPropTagArray	**ppOutMIds,
+		[in][unique]	SPropTagArray	*pPropTags,
+		[out]      	SRowSet		**ppRows
+		);
+
+	/*****************/
+	/* Function 0x06 */
+	MAPISTATUS NspiResortRestriction(
+		[in] policy_handle	*handle,
+		[in] uint32		Reserved,
+		[in,out] STAT		*pStat,
+		[in] SPropTagArray	*pInMIds,
+		[in,out] SPropTagArray	**ppMIds
+		);
+
+	/*****************/
+	/* Function 0x07 */
+	MAPISTATUS NspiDNToMId(
+		[in] policy_handle	*handle,
+		[in] uint32		Reserved,
+		[in] StringsArray_r	*pNames,
+		[out] SPropTagArray	**ppMIds
+		);
+
+	/*****************/
+	/* Function 0x08 */
+	MAPISTATUS NspiGetPropList(
+		[in] policy_handle	*handle,
+		[in] uint32		dwFlags,
+		[in] uint32		dwMId,
+		[in] uint32		CodePage,
+		[out] SPropTagArray	**ppPropTags
+		);
+
+	/*****************/
+	/* Function 0x09 */
+	MAPISTATUS NspiGetProps(
+		[in]   	policy_handle			*handle,
+		[in]   	uint32				dwFlags,
+		[in]	STAT				*pStat,
+		[in,unique] SPropTagArray		*pPropTags,
+		[out]	SRow				**ppRows
+		);
+
+	/*****************/
+	/* Funcion 0xa   */
+	MAPISTATUS NspiCompareMIds(
+		[in] policy_handle     	*handle,
+		[in] uint32	       	Reserved,
+		[in] STAT	       	*pStat,
+		[in] uint32	       	MId1,
+		[in] uint32	       	MId2,
+		[out] uint32	       	*plResult
+		);
+
+	/*****************/
+	/* Function 0xb  */
+	MAPISTATUS NspiModProps(
+		[in] policy_handle		*handle,
+		[in] uint32			Reserved,
+		[in] STAT			*pStat,
+		[in,unique] SPropTagArray	*pPropTags,
+		[in] SRow			*pRow
+		);
+
+	/*****************/
+	/* Function 0x0c */
+	typedef [bitmap32bit] bitmap {
+		NspiAddressCreationTemplates	= 0x00000002,
+		NspiUnicodeStrings		= 0x00000004
+	} NspiGetSpecialTable_dwFlags;
+
+	MAPISTATUS NspiGetSpecialTable(
+		[in] policy_handle			*handle,
+		[in] NspiGetSpecialTable_dwFlags       	dwFlags,
+		[in] STAT				*pStat,
+ 		[in,out] uint32				*lpVersion,
+ 		[out] SRowSet				**ppRows
+		);
+
+	/*******************/
+	/* Function 0x0d   */
+	typedef [bitmap32bit] bitmap {
+		TI_TEMPLATE		= 0x00000001,
+		TI_SCRIPT		= 0x00000004,
+		TI_EMT			= 0x00000010,
+		TI_HELPFILE_NAME	= 0x00000020,
+		TI_HELPFILE_CONTENTS	= 0x00000040
+	} TI_dwFlags;
+
+	MAPISTATUS NspiGetTemplateInfo(
+		[in] policy_handle			*handle,
+		[in] TI_dwFlags				dwFlags,
+		[in] uint32				ulType,
+		[in,unique,string,charset(DOS)] uint8	*pDN,
+		[in] uint32				dwCodePage,
+		[in] uint32				dwLocaleID,
+		[out] SRow				**ppData
+		);
+
+	/*******************/
+	/* Function 0x0e   */
+	MAPISTATUS NspiModLinkAtt(
+		[in] policy_handle			*handle,
+		[in] uint32				dwFlags,
+		[in] uint32				ulPropTag,
+		[in] uint32				MId,
+		[in] BinaryArray_r			*lpEntryIds
+		);
+
+	/*************************************/
+	/* Function 0x0f: Not used on wire   */
+	MAPISTATUS NspiDeleteEntries(
+		[in] policy_handle			*Reserved1,
+		[in] uint32				Reserved2,
+		[in] uint32				Reserved3,
+		[in] BinaryArray_r			*Reserved4
+		);
+
+	/*******************/
+	/* Function 0x10   */
+	typedef [bitmap32bit] bitmap {
+		NspiUnicodeProptypes	= 0x80000000
+	} NspiQueryColumns_dwFlags;
+
+	MAPISTATUS NspiQueryColumns(
+		[in] policy_handle			*handle,
+		[in] uint32				Reserved,
+		[in] NspiQueryColumns_dwFlags		dwFlags,
+		[out] SPropTagArray      		**ppColumns
+		);
+
+	/*******************/
+	/* Function 0x11   */
+	MAPISTATUS NspiGetNamesFromIDs(
+		[in] policy_handle			*handle,
+		[in] uint32				Reserved,
+		[in,unique] FlatUID_r			*lpGuid,
+		[in,unique] SPropTagArray		*pPropTags,
+		[out] SPropTagArray			**ppReturnedPropTags,
+		[out] PropertyNameSet_r			**ppNames
+		);
+
+	/*******************/
+	/* Function 0x12   */
+	MAPISTATUS NspiGetIDsFromNames(
+		[in] policy_handle			*handle,
+		[in] uint32				Reserved,
+		[in] uint32				dwFlags,
+		[in,range(0,100000)] uint32		cPropNames,
+		[in,size_is(cPropNames)] PropertyName_r	**ppNames,
+		[out] SPropTagArray			**ppPropTags
+		);
+
+	/*****************/
+	/* Function 0x13 */
+	MAPISTATUS NspiResolveNames(
+		[in] policy_handle		*handle,
+		[in] uint32			Reserved,
+		[in] STAT			*pStat,
+		[in,unique] SPropTagArray	*pPropTags,
+ 		[in] StringsArray_r		*paStr,
+		[out] SPropTagArray		**ppMIds,
+		[out] SRowSet			**ppRows
+	);
+
+	/*****************/
+	/* Function 0x14 */
+	MAPISTATUS NspiResolveNamesW(
+		[in] policy_handle		*handle,
+		[in] uint32			Reserved,
+		[in] STAT			*pStat,
+		[in,unique] SPropTagArray      	*pPropTags,
+		[in] WStringsArray_r       	*paWStr,
+		[out] SPropTagArray		**ppMIds,
+		[out] SRowSet			**ppRows
+		);
+}
+
+[
+  uuid("a4f1db00-ca47-1067-b31f-00dd010662da"),
+  pointer_default(unique),
+  endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:"),
+  //version(0.81),
+  version(5308416),
+  helpstring("Exchange 5.5 EMSMDB")
+] interface exchange_emsmdb
+{
+	/*****************/
+	/* Function 0x00 */
+
+	MAPISTATUS EcDoConnect(
+ 		[out]				policy_handle	*handle,
+                [in,string,charset(DOS)]	uint8		szUserDN[],
+		[in]				uint32		ulFlags,
+		[in]				uint32		ulConMod,
+		[in]				uint32		cbLimit,
+		[in]				uint32		ulCpid,
+		[in]				uint32		ulLcidString,
+		[in]				uint32		ulLcidSort,
+		[in]				uint32		ulIcxrLink,
+		[in]				uint16		usFCanConvertCodePages,
+		[out]				uint32		*pcmsPollsMax,
+		[out]				uint32		*pcRetry,
+		[out]				uint32		*pcmsRetryDelay,
+		[out]				uint32		*picxr,
+                [out,unique,string,charset(DOS)]uint8		*szDNPrefix,
+                [out,unique,string,charset(DOS)]uint8		*szDisplayName,
+                [out]				uint16          rgwServerVersion[3],
+		[in,out]       			uint16          rgwClientVersion[3],
+                [in,out]			uint32		*pullTimeStamp
+		);
+
+	/*****************/
+	/* Function 0x01 */
+	MAPISTATUS EcDoDisconnect(
+		[in,out]   policy_handle   *handle
+		);
+
+	/*****************/
+	/* Function 0x02 */
+
+	/*
+	  EcDoRpc opnums
+	*/
+
+	typedef [public, enum8bit, flag(NDR_PAHEX)] enum 
+		{
+			MAPI_STORE	= 0x1,
+			MAPI_ADDRBOOK	= 0x2,
+			MAPI_FOLDER	= 0x3,
+			MAPI_ABCONT	= 0x4,
+			MAPI_MESSAGE	= 0x5,
+			MAPI_MAILUSER	= 0x6, /* Individual Recipient */
+			MAPI_ATTACH	= 0x7,
+			MAPI_DISTLIST	= 0x8,
+			MAPI_PROFSECT	= 0x9,
+			MAPI_STATUS	= 0xA,
+			MAPI_SESSION	= 0xB,
+			MAPI_FORMINFO	= 0xC
+		} MAPI_OBJTYPE;
+
+	typedef [public, v1_enum, flag(NDR_PAHEX)] enum 
+		{
+			RightsNone		= 0x00000000,
+			RightsReadItems		= 0x00000001,
+			RightsCreateItems	= 0x00000002,
+			RightsEditOwn		= 0x00000008,
+			RightsDeleteOwn		= 0x00000010,
+			RightsEditAll		= 0x00000020,
+			RightsDeleteAll		= 0x00000040,
+			RightsCreateSubfolders	= 0x00000080,
+			RightsFolderOwner	= 0x00000100,
+			RightsFolderContact	= 0x00000200,
+			RoleNone		= 0x00000400,
+			RoleReviewer		= 0x00000401,
+			RoleContributor		= 0x00000402,
+			RoleNoneditingAuthor	= 0x00000413,
+			RoleAuthor		= 0x0000041B,
+			RoleEditor		= 0x0000047B,
+			RolePublishAuthor	= 0x0000049B,
+			RolePublishEditor	= 0x000004FB,
+			RightsAll		= 0x000005FB,
+			RoleOwner		= 0x000007FB
+	       	} ACLRIGHTS;
+
+	typedef [public, enum8bit, flag(NDR_PAHEX)] enum
+		{
+			op_MAPI_Release				= 0x1,
+			op_MAPI_OpenFolder			= 0x2,
+			op_MAPI_OpenMessage			= 0x3,
+			op_MAPI_GetHierarchyTable		= 0x4,
+			op_MAPI_GetContentsTable		= 0x5,
+			op_MAPI_CreateMessage			= 0x6,
+			op_MAPI_GetProps			= 0x7,
+			op_MAPI_GetPropsAll			= 0x8,
+			op_MAPI_GetPropList			= 0x9,
+			op_MAPI_SetProps			= 0xa,
+			op_MAPI_DeleteProps			= 0xb,
+			op_MAPI_SaveChangesMessage		= 0xc,
+			op_MAPI_RemoveAllRecipients		= 0xd,
+			op_MAPI_ModifyRecipients		= 0xe,
+			op_MAPI_ReadRecipients			= 0xf,
+			op_MAPI_ReloadCachedInformation		= 0x10,
+			op_MAPI_SetMessageReadFlag		= 0x11,
+			op_MAPI_SetColumns			= 0x12,
+			op_MAPI_SortTable			= 0x13,
+			op_MAPI_Restrict			= 0x14,
+			op_MAPI_QueryRows			= 0x15,
+			op_MAPI_GetStatus			= 0x16,
+			op_MAPI_QueryPosition			= 0x17,
+			op_MAPI_SeekRow				= 0x18,
+			op_MAPI_SeekRowBookmark			= 0x19,
+			op_MAPI_SeekRowApprox			= 0x1a,
+			op_MAPI_CreateBookmark			= 0x1b,
+			op_MAPI_CreateFolder			= 0x1c,
+			op_MAPI_DeleteFolder			= 0x1d,
+			op_MAPI_DeleteMessages			= 0x1e,
+			op_MAPI_GetMessageStatus		= 0x1f,
+			op_MAPI_SetMessageStatus		= 0x20,
+			op_MAPI_GetAttachmentTable		= 0x21,
+			op_MAPI_OpenAttach			= 0x22,
+			op_MAPI_CreateAttach			= 0x23,
+			op_MAPI_DeleteAttach			= 0x24,
+			op_MAPI_SaveChangesAttachment  		= 0x25,
+			op_MAPI_SetReceiveFolder		= 0x26,
+			op_MAPI_GetReceiveFolder		= 0x27,
+			op_MAPI_RegisterNotification   		= 0x29,
+			op_MAPI_Notify				= 0x2a,
+			op_MAPI_OpenStream			= 0x2b,
+			op_MAPI_ReadStream			= 0x2c,
+			op_MAPI_WriteStream			= 0x2d,
+			op_MAPI_SeekStream			= 0x2e,
+			op_MAPI_SetStreamSize			= 0x2f,
+			op_MAPI_SetSearchCriteria		= 0x30,
+			op_MAPI_GetSearchCriteria		= 0x31,
+			op_MAPI_SubmitMessage			= 0x32,
+			op_MAPI_MoveCopyMessages		= 0x33,
+			op_MAPI_AbortSubmit			= 0x34,
+			op_MAPI_MoveFolder			= 0x35,
+			op_MAPI_CopyFolder			= 0x36,
+			op_MAPI_QueryColumnsAll			= 0x37,
+			op_MAPI_Abort				= 0x38,
+			op_MAPI_CopyTo				= 0x39,
+			op_MAPI_CopyToStream			= 0x3a,
+			op_MAPI_GetTable			= 0x3e,
+			op_MAPI_GetRulesTable			= 0x3f,
+			op_MAPI_ModifyTable			= 0x40,
+			op_MAPI_ModifyRules			= 0x41,
+			op_MAPI_GetOwningServers		= 0x42,
+			op_MAPI_LongTermIdFromId		= 0x43,
+			op_MAPI_IdFromLongTermId		= 0x44,
+			op_MAPI_PublicFolderIsGhosted		= 0x45,
+			op_MAPI_OpenEmbeddedMessage		= 0x46,
+			op_MAPI_SetSpooler			= 0x47,
+			op_MAPI_SpoolerLockMessage		= 0x48,
+			op_MAPI_AddressTypes			= 0x49,
+			op_MAPI_TransportSend			= 0x4a,
+			op_MAPI_FastTransferSourceGetBuffer	= 0x4e,
+			op_MAPI_FindRow				= 0x4f,
+			op_MAPI_Progress			= 0x50,
+			op_MAPI_GetNamesFromIDs			= 0x55,
+			op_MAPI_GetIDsFromNames			= 0x56,
+			op_MAPI_EmptyFolder			= 0x58,
+			op_MAPI_ExpandRow			= 0x59,
+			op_MAPI_CollapseRow			= 0x5a,
+			op_MAPI_CommitStream			= 0x5d,
+			op_MAPI_GetStreamSize			= 0x5e,
+			op_MAPI_QueryNamedProperties		= 0x5f,
+			op_MAPI_GetPerUserLongTermIds		= 0x60,
+			op_MAPI_GetPerUserGuid			= 0x61,
+			op_MAPI_ReadPerUserInformation		= 0x63,
+			op_MAPI_SetReadFlags			= 0x66,
+			op_MAPI_CopyProperties			= 0x67,
+			op_MAPI_GetReceiveFolderTable		= 0x68,
+			op_MAPI_GetCollapseState		= 0x6b,
+			op_MAPI_SetCollapseState		= 0x6c,
+			op_MAPI_GetTransportFolder		= 0x6d,
+			op_MAPI_Pending				= 0x6e,
+			op_MAPI_RegisterOptions			= 0x6f,
+			op_MAPI_SyncConfigure			= 0x70,
+			op_MAPI_SyncImportMessageChange		= 0x72,
+			op_MAPI_SyncImportHierarchyChange	= 0x73,
+			op_MAPI_SyncImportDeletes		= 0x74,
+			op_MAPI_SyncUploadStateStreamBegin	= 0x75,
+			op_MAPI_SyncUploadStateStreamContinue	= 0x76,
+			op_MAPI_SyncUploadStateStreamEnd	= 0x77,
+			op_MAPI_SyncImportMessageMove		= 0x78,
+			op_MAPI_SetPropertiesNoReplicate	= 0x79,
+			op_MAPI_DeletePropertiesNoReplicate	= 0x7a,
+			op_MAPI_GetStoreState			= 0x7b,
+			op_MAPI_SyncOpenCollector		= 0x7e,
+			op_MAPI_GetLocalReplicaIds		= 0x7f,
+			op_MAPI_SyncImportReadStateChanges	= 0x80,
+			op_MAPI_ResetTable			= 0x81,
+			op_MAPI_SyncGetTransferState		= 0x82,
+			op_MAPI_OpenPublicFolderByName		= 0x87,
+			op_MAPI_SetSyncNotificationGuid		= 0x88,
+			op_MAPI_FreeBookmark			= 0x89,
+			op_MAPI_Logon				= 0xfe,
+			/****** custom MAPI opnum for mapiproxy ******/
+			op_MAPI_proxypack			= 0xa5
+		} MAPI_OPNUM;
+
+
+	typedef [public,noprint,flag(NDR_NOALIGN)] struct {
+		uint16				cb;
+		[flag(NDR_BUFFERS)]uint8	lpb[cb];
+	} SBinary_short;
+
+	typedef [public] struct {
+		uint32 cValues;
+		uint32 lpl[cValues]; 
+	} mapi_MV_LONG_STRUCT;
+
+	typedef [public] struct {
+		astring lppszA;
+	} mapi_LPSTR;
+
+	typedef [public] struct {
+		uint32 cValues;
+		mapi_LPSTR strings[cValues]; 
+	} mapi_SLPSTRArray;
+
+	typedef struct {
+		[flag(STR_NULLTERM)] string lppszW;
+	} mapi_LPWSTR;
+
+	typedef struct {
+		uint32 cValues;
+		mapi_LPWSTR strings[cValues];
+	} mapi_SPLSTRArrayW;
+	
+	typedef [public] struct {
+		uint32		cValues;
+		SBinary_short	bin[cValues];
+	} mapi_SBinaryArray;
+
+	typedef struct {
+		uint32		cValues;
+		GUID		lpguid[cValues];
+	} mapi_SGuidArray;
+
+	/******* part of the no-pointer deep recursion hack *******/
+	typedef [nopull,nopush,noprint,flag(NDR_NOALIGN)] struct {
+		uint8 wrap[0x8000];
+	} mapi_SRestriction_wrap;
+
+	typedef [nopush,nopull,noprint,flag(NDR_NOALIGN)] struct {
+		uint8	wrap[0x8000];
+	} mapi_SPropValue_wrap;
+
+	typedef [nopush,nopull,noprint,flag(NDR_NOALIGN)] struct {
+		uint8	wrap[0x8000];
+	} mapi_SPropValue_array_wrap;
+	/**********************************************************/	
+
+	typedef [enum8bit] enum {
+		ActionType_OP_MOVE		= 0x1,
+		ActionType_OP_COPY		= 0x2,
+		ActionType_OP_REPLY		= 0x3,
+		ActionType_OP_OOF_REPLY		= 0x4,
+		ActionType_OP_DEFER_ACTION	= 0x5,
+		ActionType_OP_BOUNCE		= 0x6,
+		ActionType_OP_FORWARD		= 0x7,
+		ActionType_OP_DELEGATE		= 0x8,
+		ActionType_OP_TAG		= 0x9,
+		ActionType_OP_DELETE		= 0xA,
+		ActionType_OP_MARK_AS_READ	= 0xB
+	} ActionType;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		FolderInThisStore;
+		SBinary_short		StoreEID;
+		SBinary_short		FolderEID;
+	} MoveCopy_Action;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			ReplyTemplateFID;
+		hyper			ReplyTemplateMID;
+		GUID			ReplyTemplateGUID;			
+	} ReplyOOF_Action;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				Reserved;
+		mapi_SPropValue_array_wrap	PropertyValue;
+	} RecipientBlock;
+
+	typedef [flag(NDR_NOALIGN)] enum {
+		BOUNCE_MESSAGE_TOO_LARGE	= 0x0000000d,
+		BOUNCE_MESSAGE_NOT_DISPLAYED	= 0x0000001f,
+		BOUNCE_MESSAGE_DENIED		= 0x00000026
+	} BounceCode;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16			RecipientCount;
+		RecipientBlock		RecipientBlock[RecipientCount];
+	} ForwardDelegate_Action;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(ActionType_OP_MOVE)]		MoveCopy_Action			MoveAction;
+		[case(ActionType_OP_COPY)]		MoveCopy_Action			CopyAction;
+		[case(ActionType_OP_REPLY)]		ReplyOOF_Action			ReplyAction;
+		[case(ActionType_OP_OOF_REPLY)]		ReplyOOF_Action			ReplyOOFAction;
+		[case(ActionType_OP_DEFER_ACTION)][flag(NDR_REMAINING)] DATA_BLOB	DeferAction;
+		[case(ActionType_OP_BOUNCE)]		BounceCode			BounceCode;
+		[case(ActionType_OP_TAG)]		mapi_SPropValue_wrap	       	PropValue;
+		[case(ActionType_OP_FORWARD)]		ForwardDelegate_Action		ForwardAction;
+		[case(ActionType_OP_DELEGATE)]		ForwardDelegate_Action		DelegateAction;
+		[case(ActionType_OP_DELETE)];
+		[case(ActionType_OP_MARK_AS_READ)];
+	} ActionData;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		ActionType				ActionType;
+		uint32					ActionFlavor;
+		uint32					ActionFlags;
+		[switch_is(ActionType)] ActionData	ActionDataBuffer;
+	} ActionBlockData;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16					ActionLength;
+		[subcontext(0),subcontext_size(ActionLength),flag(NDR_REMAINING)] ActionBlockData ActionBlockData;
+	} ActionBlock;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		count;
+		ActionBlock	ActionBlock[count];
+	} RuleAction;
+
+	typedef [public,nodiscriminant,flag(NDR_NOALIGN)] union {
+		[case(PT_I2)]		uint16			i;
+		[case(PT_LONG)]     	uint32			l;
+		[case(PT_DOUBLE)]	dlong			dbl;
+		[case(PT_ERROR)]       	uint32			err;
+		[case(PT_BOOLEAN)]	uint8			b;
+		[case(PT_I8)]		dlong			d;
+		[case(PT_STRING8)]	astring			lpszA;
+		[case(PT_UNICODE)][flag(STR_NULLTERM)] string	lpszW;
+		[case(PT_SYSTIME)]	FILETIME		ft;
+		[case(PT_CLSID)]	GUID			lpguid;
+ 		[case(PT_SRESTRICT)]	mapi_SRestriction_wrap 	Restrictions;
+		[case(PT_ACTIONS)]	RuleAction		RuleAction;
+  		[case(PT_BINARY)]	SBinary_short		bin;
+		[case(PT_SVREID)]      	SBinary_short		bin;
+		[case(PT_MV_LONG)]	mapi_MV_LONG_STRUCT	MVl;	
+		[case(PT_MV_STRING8)]	mapi_SLPSTRArray	MVszA;
+		[case(PT_MV_UNICODE)]	mapi_SPLSTRArrayW	MVszW;
+		[case(PT_MV_CLSID)]	mapi_SGuidArray		MVguid;
+		[case(PT_MV_BINARY)]	mapi_SBinaryArray      	MVbin;
+	} mapi_SPropValue_CTR;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		MAPITAGS ulPropTag;
+		[switch_is(ulPropTag & 0xFFFF)] mapi_SPropValue_CTR value; 
+	} mapi_SPropValue;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint16					cValues;
+		[flag(NDR_REMAINING)]mapi_SPropValue	lpProps[cValues];
+	} mapi_SPropValue_array;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16					cValues;
+		MAPITAGS				aulPropTag[cValues];
+	} mapi_SPropTagArray;
+
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		ROW_ADD		=	0x1,
+		ROW_MODIFY	=	0x2,
+		ROW_REMOVE	=	0x4
+	} ulRowFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulRowFlags				ulRowFlags;
+		mapi_SPropValue_array			lpProps;
+	} mapi_SRow;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					padding;
+		uint16					cEntries;
+		mapi_SRow				aEntries[cEntries];
+	} mapi_SRowList;
+
+	/**************************/
+	/* EcDoRpc Function 0x1   */
+	typedef [nopush,nopull,flag(NDR_NOALIGN)] struct {
+	} Release_req;
+
+	typedef [nopush,nopull,flag(NDR_NOALIGN)] struct {
+	} Release_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x2   */
+	typedef [enum8bit] enum {
+		OpenModeFlags_Folder		= 0x0,
+		OpenModeFlags_SoftDeleted	= 0x4
+	} OpenFolder_OpenModeFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				handle_idx;
+		hyper				folder_id;
+ 		OpenFolder_OpenModeFlags	OpenModeFlags;
+	} OpenFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		ServerCount;
+		uint16		CheapServerCount;
+		astring		Servers[ServerCount];
+	} OpenFolder_Replicas;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)] OpenFolder_Replicas	Replicas;
+	} IsGhosted;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		       	       	HasRules;
+		boolean8			       	IsGhosted;
+		[switch_is(IsGhosted)] IsGhosted	Ghost;
+	} OpenFolder_repl;
+	
+	/**************************/
+	/* EcDoRpc Function 0x3   */
+	typedef [enum8bit] enum {
+		StringType_NONE			= 0x0,
+		StringType_EMPTY		= 0x1,
+		StringType_STRING8		= 0x2,
+		StringType_UNICODE_REDUCED	= 0x3,
+		StringType_UNICODE		= 0x4
+	} StringType;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)];
+		[case(0x2)] astring			lpszA;
+		[case(0x3)] astring			lpszW_reduced;
+		[case(0x4)] [flag(STR_NULLTERM)] string	lpszW;
+	} String;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		StringType			StringType;
+		[switch_is(StringType)] String	String;
+	} TypedString;
+
+	typedef [bitmap8bit] bitmap {
+		/* 0x0 means Read Only */
+		ReadWrite	= 0x1,
+		Create		= 0x3
+	} OpenMessage_OpenModeFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				handle_idx;
+		uint16				CodePageId;
+		hyper				FolderId;
+		OpenMessage_OpenModeFlags	OpenModeFlags;
+		hyper				MessageId;
+	} OpenMessage_req;
+
+	typedef [v1_enum, flag(NDR_PAHEX)] enum {
+		CP_USASCII	= 0x04E4,
+		CP_UNICODE	= 0x04B0,
+		CP_JAUTODETECT	= 0xC6F4,
+		CP_KAUTODETECT	= 0xC705,
+		CP_ISO2022JPESC = 0xC42D,
+		CP_ISO2022JPSIO	= 0xC42E
+	} CODEPAGEID;
+
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		MAPI_ORIG		= 0x0,
+		MAPI_TO			= 0x1,
+		MAPI_CC			= 0x2,
+		MAPI_BCC		= 0x3
+	} ulRecipClass;
+
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		SINGLE_RECIPIENT	= 0x0,
+		DISTRIBUTION_LIST	= 0x1
+	} addr_type;
+
+	typedef  [flag(NDR_NOALIGN)]struct {
+		uint8		organization_length;
+		addr_type	addr_type;
+		astring		username;
+	} RecipExchange;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} RecipSMTP;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)] RecipExchange	EXCHANGE;
+		[case(0xA)] RecipSMTP		SMTP;
+		[default];
+	} recipient_type;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x400)] astring				lpszA;
+		[case(0x600)][flag(STR_NULLTERM)] string	lpszW;
+		[default];
+	} recipient_SimpleDisplayName;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x20)] astring				lpszA;
+		[case(0x220)][flag(STR_NULLTERM)] string	lpszW;
+		[default];
+	} recipient_TransmittableDisplayName;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x10)] astring				lpszA;
+		[case(0x210)][flag(STR_NULLTERM)] string	lpszW;
+		[default];
+	} recipient_DisplayName;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x8)] astring				lpszA;
+		[case(0x208)][flag(STR_NULLTERM)] string	lpszW;
+		[default];
+	} recipient_EmailAddress;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16									RecipientFlags;
+		[switch_is(RecipientFlags & 0xA)]   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;
+		uint16									prop_count;
+		uint8									layout;
+		[flag(NDR_REMAINING)] DATA_BLOB						prop_values;
+	} RecipientRow;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulRecipClass	RecipClass;
+		CODEPAGEID	codepage;
+		[subcontext(2)] RecipientRow	RecipientRow;
+	} OpenMessage_recipients;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		HasNamedProperties;
+		TypedString		SubjectPrefix;
+		TypedString		NormalizedSubject;
+		uint16			RecipientCount;
+		mapi_SPropTagArray	RecipientColumns;
+		uint8			RowCount;
+		OpenMessage_recipients	recipients[RowCount];
+	} OpenMessage_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x4   */
+	typedef [bitmap8bit] bitmap {
+		TableFlags_Depth			= 0x4,
+		TableFlags_DeferredErrors		= 0x8,
+		TableFlags_NoNotifications		= 0x10,
+		TableFlags_SoftDeletes			= 0x20,
+		TableFlags_UseUnicode			= 0x40,
+		TableFlags_SuppressNotifications	= 0x80
+	} TableFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		TableFlags	TableFlags;
+	} GetHierarchyTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		RowCount;
+	} GetHierarchyTable_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x5   */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		TableFlags	TableFlags;
+	} GetContentsTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		RowCount;
+	} GetContentsTable_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x6   */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		uint16		CodePageId;
+		hyper		FolderId;
+		boolean8	AssociatedFlag;
+	} CreateMessage_req;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)] hyper	MessageId;
+	} CreateMessage_MessageId;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8						HasMessageId;
+		[switch_is(HasMessageId)] CreateMessage_MessageId	MessageId;
+	} CreateMessage_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x7  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertySizeLimit;
+		uint16		WantUnicode;
+		uint16		prop_count;
+		MAPITAGS	properties[prop_count];
+	} GetProps_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		layout;
+		[flag(NDR_REMAINING)] DATA_BLOB prop_data;
+	} GetProps_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x8  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertySizeLimit;
+		uint16		WantUnicode;
+	} GetPropsAll_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		mapi_SPropValue_array	properties;
+	} GetPropsAll_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x9  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetPropList_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		count;
+		MAPITAGS	tags[count];
+	} GetPropList_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xa  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	  	uint32		index; 		/* index into array of property tags */
+		MAPITAGS	property_tag;	/* property for which there was an error */
+		MAPISTATUS	error_code; 	/* the error that occurred for this property */
+	} PropertyProblem;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		[subcontext(2)] mapi_SPropValue_array values;
+	} SetProps_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];		
+	} SetProps_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xb  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		count;
+		MAPITAGS	tags[count];
+	} DeleteProps_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];
+	} DeleteProps_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xc  */
+	typedef [enum8bit] enum {
+		KeepOpenReadOnly	= 0x9,
+		KeepOpenReadWrite	= 0xA,
+		ForceSave		= 0xC
+	} SaveFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		uint8		SaveFlags;
+	} SaveChangesMessage_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		hyper		MessageId;
+	} SaveChangesMessage_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xd  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		ulReserved;
+	} RemoveAllRecipients_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+
+	} RemoveAllRecipients_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xe  */
+
+	/* 
+	 * MODRECIP_NULL and INVALID are not part of the msdn flags
+	 * but are added for printing support 
+	 */
+	typedef [enum8bit,flag(NDR_PAHEX)] enum {
+		MODRECIP_NULL		= 0x0,
+		MODRECIP_INVALID	= 0x1,
+		MODRECIP_ADD		= 0x2,
+		MODRECIP_MODIFY		= 0x4,
+		MODRECIP_REMOVE		= 0x8
+	} modrecip;
+
+	typedef [flag(NDR_NOALIGN)]struct {
+		uint32		idx;
+		ulRecipClass	RecipClass;		
+		[subcontext(2),flag(NDR_REMAINING)] RecipientRow RecipientRow;
+	} ModifyRecipientRow;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		uint16				prop_count;
+ 		MAPITAGS			properties[prop_count];
+		uint16				cValues;
+		ModifyRecipientRow     		RecipientRow[cValues];
+	} ModifyRecipients_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+
+	} ModifyRecipients_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xf  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		RowId;
+		uint16		ulReserved;
+	} ReadRecipients_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32				RowId;
+		ulRecipClass			RecipientType;
+		uint16				CodePageId;
+		uint16				ulReserved;
+		[subcontext(2)] RecipientRow	RecipientRow;
+	} ReadRecipientRow;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		uint8			RowCount;
+ 		ReadRecipientRow	RecipientRows[RowCount];
+	} ReadRecipients_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x10 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulRecipClass		RecipientType;
+		uint16			CodePageId;
+		uint16			Reserved;
+		uint16			RecipientRowSize;
+		[subcontext(0),subcontext_size(RecipientRowSize),flag(NDR_REMAINING)]RecipientRow      	RecipientRow;
+	} OpenRecipientRow;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		Reserved;
+	} ReloadCachedInformation_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		HasNamedProperties;
+		TypedString		SubjectPrefix;
+		TypedString		NormalizedSubject;
+		uint16			RecipientCount;
+		uint16			ColumnCount;
+		MAPITAGS		RecipientColumns[ColumnCount];
+		uint8			RowCount;
+		OpenRecipientRow	RecipientRows[RowCount];
+	} ReloadCachedInformation_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x11 */
+
+	typedef [bitmap8bit] bitmap {
+		SUPPRESS_RECEIPT	= 0x01,
+		CLEAR_READ_FLAG		= 0x04,
+		MAPI_DEFERRED_ERRORS	= 0x08,
+		GENERATE_RECEIPT_ONLY	= 0x10,
+		CLEAR_RN_PENDING	= 0x20,
+	       	CLEAR_NRN_PENDING	= 0x40
+	} MSGFLAG_READ;
+
+	/* TODO: there is a variation that can provide "client data" here */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				handle_idx;
+		MSGFLAG_READ			flags;
+		[flag(NDR_REMAINING)] DATA_BLOB clientdata;
+	} SetMessageReadFlag_req;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)] uint8	LogonId;
+	} SetMessageReadFlag_LogonId;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)] uint8	ClientData[24];
+	} SetMessageReadFlag_ClientData;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8							ReadStatusChanged;
+		[switch_is(ReadStatusChanged)] SetMessageReadFlag_LogonId	LogonId;
+		[switch_is(ReadStatusChanged)] SetMessageReadFlag_ClientData	ClientData;
+	} SetMessageReadFlag_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x12 */
+	typedef [enum8bit] enum {
+		SetColumns_TBL_SYNC	= 0x0,
+		SetColumns_TBL_ASYNC	= 0x1
+	} SetColumnsFlags;
+	
+	typedef [enum8bit] enum {
+		TBLSTAT_COMPLETE	= 0x0,
+		TBLSTAT_SORTING		= 0x9,
+		TBLSTAT_SORT_ERROR	= 0xA,
+		TBLSTAT_SETTING_COLS	= 0xB,
+		TBLSTAT_SETCOL_ERROR	= 0xD,
+		TBLSTAT_RESTRICTING	= 0xE,
+		TBLSTAT_RESTRICT_ERROR	= 0xF
+	} TableStatus;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SetColumnsFlags	SetColumnsFlags;
+		uint16		prop_count;
+		MAPITAGS	properties[prop_count];
+	} SetColumns_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableStatus	TableStatus;
+	} SetColumns_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x13  */
+        typedef [enum8bit, flag(NDR_PAHEX)] enum {
+                TBL_ASYNC = 0x1,
+                TBL_BATCH = 0x2
+        } TBL_FLAGS;
+	
+        typedef [enum8bit, flag(NDR_PAHEX)] enum {
+                TABLE_SORT_ASCEND = 0x0,
+                TABLE_SORT_COMBINE = 0x1,
+                TABLE_SORT_DESCEND = 0x2
+        } TABLE_SORT;
+
+        typedef [public, flag(NDR_NOALIGN)] struct _SSortOrder{
+                MAPITAGS ulPropTag;
+                TABLE_SORT ulOrder;
+        } SSortOrder;
+
+	typedef [public, flag(NDR_NOALIGN)] struct _SSortOrderSet {
+ 		uint16		cSorts;
+ 		uint16		cCategories;
+ 		uint16		cExpanded;
+		SSortOrder	aSort[cSorts];
+	} SSortOrderSet;
+
+        typedef [flag(NDR_NOALIGN)] struct {
+		uint8		SortTableFlags;
+		SSortOrderSet	lpSortCriteria;
+        } SortTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableStatus	TableStatus;
+	} SortTable_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x14  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16			cRes;
+   		mapi_SRestriction_and	res[cRes];
+	} mapi_SAndRestriction;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16	cRes;
+    		mapi_SRestriction_or	res[cRes];
+	} mapi_SOrRestriction;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		mapi_SRestriction_wrap	res;
+	} mapi_SNotRestriction;
+
+ 	typedef [noprint, bitmap32bit] bitmap {
+		FL_FULLSTRING		= 0x00000,
+	       	FL_SUBSTRING		= 0x00001,
+		FL_PREFIX		= 0x00002,
+		FL_IGNORECASE		= 0x10000,
+		FL_IGNORENONSPACE	= 0x20000,
+		FL_LOOSE		= 0x40000
+	} fuzzyLevel;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		fuzzyLevel	fuzzy;
+		MAPITAGS	ulPropTag;
+		mapi_SPropValue	lpProp;
+	} mapi_SContentRestriction;
+
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		BMR_EQZ = 0x0,
+		BMR_NEZ = 0x1
+	} relMBR;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		relMBR		relMBR;
+		MAPITAGS	ulPropTag;
+		uint32		ulMask;
+	} mapi_SBitmaskRestriction;
+
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		RELOP_LT = 0x0,		/* <  */
+		RELOP_LE = 0x1,		/* <= */
+		RELOP_GT = 0x2,		/* >  */
+		RELOP_GE = 0x3,		/* >= */
+		RELOP_EQ = 0x4,		/* == */
+		RELOP_NE = 0x5,		/* != */
+		RELOP_RE = 0x6		/* LIKE (Regular expression) */
+	} CompareRelop;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		CompareRelop	relop;
+		MAPITAGS	ulPropTag;
+		uint32		size;
+	} mapi_SSizeRestriction;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		relop;
+		MAPITAGS	ulPropTag;
+		mapi_SPropValue	lpProp;
+	} mapi_SPropertyRestriction;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		CompareRelop   	relop;
+		MAPITAGS	ulPropTag1;
+		MAPITAGS	ulPropTag2;
+	} mapi_SCompareProps;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		MAPITAGS	ulPropTag;
+	} mapi_SExistRestriction;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		MAPITAGS	       	ulSubObject;
+  		mapi_SRestriction_sub  	res[ulSubObject - ulSubObject + 1]; /* nasty hack - generates fake pointer */
+	} mapi_SSubRestriction;
+
+	typedef [nopush,nopull,noprint,nodiscriminant] union {
+		[case(0x0)];
+		[case(0x1)] mapi_SRestriction_comment *res;
+	} RestrictionVariable;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				TaggedValuesCount;
+		mapi_SPropValue			TaggedValues[TaggedValuesCount];
+		boolean8			RestrictionPresent;
+		[switch_is(RestrictionPresent)] RestrictionVariable Restriction;
+	} mapi_SCommentRestriction;
+
+	typedef [public,nodiscriminant] union {
+		[case(RES_AND)]			mapi_SAndRestriction		resAnd;
+		[case(RES_OR)]			mapi_SOrRestriction		resOr;
+ 		[case(RES_NOT)]			mapi_SNotRestriction		resNot;
+		[case(RES_CONTENT)]		mapi_SContentRestriction	resContent;
+		[case(RES_PROPERTY)]		mapi_SPropertyRestriction	resProperty;
+		[case(RES_COMPAREPROPS)]	mapi_SCompareProps		resCompareProps;
+		[case(RES_BITMASK)]		mapi_SBitmaskRestriction	resBitmask;
+		[case(RES_SIZE)]		mapi_SSizeRestriction		resSize;
+		[case(RES_EXIST)]		mapi_SExistRestriction		resExist;
+		[case(RES_SUBRESTRICTION)]	mapi_SSubRestriction		resSub;
+		[case(RES_COMMENT)]		mapi_SCommentRestriction	resComment;
+		[default];
+	} mapi_SRestriction_CTR;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint8 rt;
+		[switch_is(rt)] mapi_SRestriction_CTR res;
+	} mapi_SRestriction;
+
+	typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction {
+		uint8 rt;
+		[switch_is(rt)] mapi_SRestriction_CTR res;
+	} mapi_SRestriction_and;
+
+	typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction {
+		uint8 rt;
+		[switch_is(rt)] mapi_SRestriction_CTR res;
+	} mapi_SRestriction_or;
+
+	typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction {
+		uint8 rt;
+		[switch_is(rt)] mapi_SRestriction_CTR res;
+	} mapi_SRestriction_sub;
+
+	typedef [public,flag(NDR_NOALIGN)] struct _mapi_SRestriction {
+		uint8 rt;
+		[switch_is(rt)] mapi_SRestriction_CTR res;
+	} mapi_SRestriction_comment;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8 handle_idx;
+		[subcontext(2)] mapi_SRestriction  restrictions;
+	} Restrict_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableStatus	TableStatus;
+	} Restrict_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x15  */
+	typedef [enum8bit] enum {
+		TBL_ADVANCE		= 0x0,
+		TBL_NOADVANCE		= 0x1,
+		TBL_ENABLEPACKEDBUFFERS = 0x2
+	} QueryRowsFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		QueryRowsFlags	QueryRowsFlags;
+		uint8		ForwardRead;
+		uint16		RowCount;
+	} QueryRows_req;
+
+	typedef [nopush,nopull,flag(NDR_NOALIGN)] struct {
+		uint8		Origin;
+		uint16		RowCount;
+		[flag(NDR_REMAINING)]DATA_BLOB	RowData;
+	} QueryRows_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x16  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetStatus_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableStatus	TableStatus;
+	} GetStatus_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x17  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} QueryPosition_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32	Numerator;
+		uint32	Denominator;
+	} QueryPosition_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x18  */
+	typedef [enum8bit] enum {
+		BOOKMARK_BEGINNING	= 0x0,
+		BOOKMARK_CURRENT	= 0x1,
+		BOOKMARK_END		= 0x2,
+		BOOKMARK_USER		= 0x3
+	} BOOKMARK;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		BOOKMARK	origin;
+		int32		offset;
+		boolean8	WantRowMovedCount;
+	} SeekRow_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	HasSoughtLess;
+		uint32		RowsSought;
+	} SeekRow_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x19  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	Bookmark;
+		uint32		RowCount;
+		boolean8	WantRowMovedCount;
+	} SeekRowBookmark_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	RowNoLongerVisible;
+		boolean8	HasSoughtLess;
+		uint32		RowsSought;
+	} SeekRowBookmark_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x1a  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		ulNumerator;
+		uint32		ulDenominator;
+	} SeekRowApprox_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SeekRowApprox_repl;
+	
+	/**************************/
+	/* EcDoRpc Function 0x1b  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} CreateBookmark_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	bookmark;
+	} CreateBookmark_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x1c  */
+	typedef [enum8bit] enum {
+		FOLDER_GENERIC	= 0x1,
+		FOLDER_SEARCH	= 0x2
+	} FOLDER_TYPE;
+
+	typedef [enum8bit] enum {
+		MAPI_FOLDER_ANSI       	= 0x0,
+		MAPI_FOLDER_UNICODE    	= 0x1
+	} FOLDER_STRING;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(MAPI_FOLDER_ANSI)] astring			lpszA;
+		[case(MAPI_FOLDER_UNICODE)][flag(STR_NULLTERM)] string	lpszW;
+	} LPTSTR;
+
+	typedef [enum16bit] enum {
+		NONE		= 0x0000,
+		OPEN_IF_EXISTS	= 0x0001
+	} FOLDER_FLAGS;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				handle_idx;
+		FOLDER_TYPE			ulFolderType;
+		FOLDER_STRING			ulType;
+		FOLDER_FLAGS	       		ulFlags;
+		[switch_is(ulType)] LPTSTR	FolderName;
+		[switch_is(ulType)] LPTSTR	FolderComment;
+	} CreateFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8				HasRules;
+		boolean8				IsGhosted;
+		[switch_is(IsGhosted)] IsGhosted	Ghost;
+	} CreateFolder_GhostInfo;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)];
+		[case(0x1)] CreateFolder_GhostInfo	GhostInfo;
+	} CreateFolder_GhostUnion;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper							folder_id;
+		boolean8						IsExistingFolder;
+		[switch_is(IsExistingFolder)]	CreateFolder_GhostUnion	GhostUnion;
+	} CreateFolder_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x1d  */
+	typedef [bitmap8bit] bitmap {
+		DEL_MESSAGES		= 0x1,
+		DEL_FOLDERS		= 0x4,
+		DELETE_HARD_DELETE	= 0x10
+	} DeleteFolderFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		DeleteFolderFlags      	DeleteFolderFlags;
+		hyper			FolderId;
+	} DeleteFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		PartialCompletion;
+	} DeleteFolder_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x1e  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	WantAsynchronous;
+		boolean8	NotifyNonRead;
+		uint16		cn_ids;
+		hyper		message_ids[cn_ids];
+	} DeleteMessages_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	PartialCompletion;
+	} DeleteMessages_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x1f  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		msgid;
+	} GetMessageStatus_req;
+
+	/**************************/
+	/* EcDoRpc Function 0x20  */
+	typedef [bitmap32bit] bitmap {
+		MSGSTATUS_HIGHLIGHTED		= 0x1,
+		MSGSTATUS_TAGGED		= 0x2,
+		MSGSTATUS_HIDDEN		= 0x4,
+	        MSGSTATUS_DELMARKED		= 0x8,
+		MSGSTATUS_REMOTE_DOWNLOAD	= 0x1000,
+		MSGSTATUS_REMOTE_DELETE		= 0x2000
+	} ulMessageStatus;
+
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		msgid;
+		uint32		ulNewStatus;
+		ulMessageStatus	ulNewStatusMask;
+	} SetMessageStatus_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulMessageStatus	ulOldStatus;
+	} SetMessageStatus_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x21  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		TableFlags	TableFlags;
+	} GetAttachmentTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {		
+	} GetAttachmentTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x22 */
+	typedef [enum8bit] enum {
+		OpenAttachmentFlags_ReadOnly	= 0x0,
+		OpenAttachmentFlags_ReadWrite	= 0x1,
+		OpenAttachmentFlags_BestAccess	= 0x3
+	} OpenAttachmentFlags;
+
+  	typedef [flag(NDR_NOALIGN)] struct {
+		uint8			handle_idx;
+		OpenAttachmentFlags	OpenAttachmentFlags;
+		uint32			AttachmentID;
+	} OpenAttach_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} OpenAttach_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x23 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8	handle_idx;
+	} CreateAttach_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32	AttachmentID;
+	} CreateAttach_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x24 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		AttachmentID;
+	} DeleteAttach_req;
+
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} DeleteAttach_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x25 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		SaveFlags	SaveFlags;
+	} SaveChangesAttachment_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SaveChangesAttachment_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x26 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		fid;
+		astring		lpszMessageClass;
+	} SetReceiveFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetReceiveFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x27 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		astring		MessageClass;
+	} GetReceiveFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		folder_id;
+		astring		MessageClass;
+	} GetReceiveFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x29 */
+	typedef [bitmap16bit] bitmap {
+		fnevCriticalError		= 0x0001,
+		fnevNewMail			= 0x0002,
+		fnevObjectCreated		= 0x0004,
+		fnevObjectDeleted		= 0x0008,
+		fnevObjectModified		= 0x0010,
+		fnevObjectMoved			= 0x0020,
+		fnevObjectCopied		= 0x0040,
+		fnevSearchComplete		= 0x0080,
+		fnevTableModified		= 0x0100,
+		fnevStatusObjectModified	= 0x0200,
+		fnevReserved			= 0x0400,
+		fnevTbit       			= 0x1000,
+		fnevUbit			= 0x2000,
+		fnevSbit			= 0x4000,
+		fnevMbit			= 0x8000
+	} NotificationFlags;
+
+	typedef [nodiscriminant,flag(NDR_NOALIGN)] union {
+		[case(0x0)] hyper	ID;
+		[case(0x1)];
+	} hyperbool;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					handle_idx;
+		NotificationFlags			NotificationFlags;
+		boolean8				WantWholeStore;
+		[switch_is(WantWholeStore)] hyperbool	FolderId;
+		[switch_is(WantWholeStore)] hyperbool	MessageId;
+	} RegisterNotification_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} RegisterNotification_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2a */
+	typedef [bitmap32bit] bitmap {
+		MSGFLAG_READ		= 0x1,
+		MSGFLAG_UNMODIFIED	= 0x2,
+		MSGFLAG_SUBMIT		= 0x4,
+		MSGFLAG_UNSENT		= 0x8,
+		MSGFLAG_HASATTACH	= 0x10,
+		MSGFLAG_FROMME		= 0x20,
+		MSGFLAG_ASSOCIATED	= 0x40,
+		MSGFLAG_RESEND		= 0x80,
+		MSGFLAG_RN_PENDING	= 0x100,
+	        MSGFLAG_NRN_PENDING	= 0x200
+	} MsgFlags;
+
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)] astring			lpszA;
+		[case(0x1)][flag(STR_NULLTERM)] string	lpszW;
+	} MessageClass;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID		DatabaseGUID;
+		uint8		GlobalCounter[6];
+	} GID;
+
+	typedef [enum16bit] enum {
+		TABLE_CHANGED		=	0x1,
+		TABLE_ROW_ADDED		=	0x3,
+		TABLE_ROW_DELETED	=	0x4,
+		TABLE_ROW_MODIFIED	=	0x5,
+		TABLE_RESTRICT_DONE	=	0x7
+	} RichTableNotificationType;
+
+	/* NewMailNotification: case 0x2 and 0x8002 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+		MsgFlags				MessageFlags;
+		boolean8				UnicodeFlag;
+		[switch_is(UnicodeFlag)] MessageClass	MessageClass;
+	} NewMailNotification;
+
+	/* FolderCreatedNotification: case 0x4 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					ParentFID;
+		uint16					TagCount;
+		MAPITAGS				Tags[TagCount];
+	} FolderCreatedNotification;
+
+	/* FolderDeletedNotification: case 0x8 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					ParentFID;
+	} FolderDeletedNotification;
+
+	/* FolderModifiedNotification: case 0x10 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		uint16			TagCount;
+		MAPITAGS		Tags[TagCount];
+	} FolderModifiedNotification_10;
+
+	/* FolderMoveCopyNotification: case 0x20 and 0x40 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		hyper			ParentFID;
+		hyper			OldFID;
+		hyper			OldParentFID;
+	} FolderMoveCopyNotification;
+
+	/* SearchCompleteNotification: case 0x80 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+	} SearchCompleteNotification;
+
+	/* HierarchyTable: case 0x100 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+		hyper				InsertAfterFID;
+		[subcontext(2)] DATA_BLOB	Columns;
+	} HierarchyRowAddedNotification;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+	} HierarchyRowDeletedNotification;
+	
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+		hyper				InsertAfterFID;
+		[subcontext(2)] DATA_BLOB	Columns;
+	} HierarchyRowModifiedNotification;
+
+	typedef [nodiscriminant] union {
+		[case(TABLE_ROW_ADDED)] HierarchyRowAddedNotification		HierarchyRowAddedNotification;
+		[case(TABLE_ROW_DELETED)] HierarchyRowDeletedNotification	HierarchyRowDeletedNotification;
+		[case(TABLE_ROW_MODIFIED)] HierarchyRowModifiedNotification	HierarchyRowModifiedNotification;
+		[default];
+	} HierarchyTableChangeUnion;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		RichTableNotificationType				TableEvent;
+		[switch_is(TableEvent)] HierarchyTableChangeUnion	HierarchyTableChangeUnion;
+	} HierarchyTableChange;
+
+	/* IcsNotification: case 0x200 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8       		HierChanged;
+		uint32			GIDCount;
+		GID			GID[GIDCount];
+	} IcsNotification;
+
+	/* FolderModifiedNotification: case 0x1010 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		uint16			TagCount;
+		MAPITAGS		Tags[TagCount];
+		uint32			TotalMessageCount;
+	} FolderModifiedNotification_1010;
+
+	/* FolderModifiedNotification: case 0x2010 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		uint16			TagCount;
+		MAPITAGS		Tags[TagCount];
+		uint32			UnreadMessageCount;
+	} FolderModifiedNotification_2010;
+
+	/* FolderModifiedNotification: case 0x3010 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		uint16			TagCount;
+		MAPITAGS		Tags[TagCount];
+		uint32			TotalMessageCount;
+		uint32			UnreadMessageCount;
+	} FolderModifiedNotification_3010;
+
+	/* MessageCreatedNotification: case 0x8004 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+		uint16					TagCount;
+		MAPITAGS				Tags[TagCount];
+	} MessageCreatedNotification;
+
+	/* MessageDeletedNotification: case 0x8008 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+	} MessageDeletedNotification;
+
+	/* MessageModifiedNotification: case 0x8010 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+		uint16					TagCount;
+		MAPITAGS				Tags[TagCount];
+	} MessageModifiedNotification;
+
+	/* MessageMoveCopyNotification: case 0x8020 and 0x8040 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FID;
+		hyper			MID;
+		hyper			OldFID;
+		hyper			OldMID;
+	} MessageMoveCopyNotification;	
+
+	/* ContentsTableChange: case 0x8100 and 0xc100 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+		hyper				MID;
+		uint32				Instance;
+		hyper				InsertAfterFID;
+		hyper				InsertAfterMID;
+		uint32				InsertAfterInstance;
+		[subcontext(2)] DATA_BLOB	Columns;
+	} ContentsRowAddedNotification;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+		hyper				MID;
+		uint32				Instance;
+	} ContentsRowDeletedNotification;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper				FID;
+		hyper				MID;
+		uint32				Instance;
+		hyper				InsertAfterFID;
+		hyper				InsertAfterMID;
+		uint32				InsertAfterInstance;
+		[subcontext(2)] DATA_BLOB	Columns;
+	} ContentsRowModifiedNotification;
+
+	typedef [nodiscriminant] union {
+		[case(TABLE_ROW_ADDED)] ContentsRowAddedNotification		ContentsRowAddedNotification;
+		[case(TABLE_ROW_DELETED)] ContentsRowDeletedNotification	ContentsRowDeletedNotification;
+		[case(TABLE_ROW_MODIFIED)] ContentsRowModifiedNotification	ContentsRowModifiedNotification;
+		[default];
+	} ContentsTableChangeUnion;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		RichTableNotificationType				TableEvent;
+		[switch_is(TableEvent)] ContentsTableChangeUnion	ContentsTableChangeUnion;
+	} ContentsTableChange;
+
+	/* SearchMessageRemovedNotification: case 0xc008 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+		hyper					SearchFID;
+	} SearchMessageRemovedNotification;
+
+	/* SearchMessageModifiedNotification: 0xc010 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper					FID;
+		hyper					MID;
+		hyper					SearchFID;
+		uint16					TagCount;
+		MAPITAGS				Tags[TagCount];
+	} SearchMessageModifiedNotification;
+
+	typedef [nodiscriminant] union {
+		[case(0x0002)] NewMailNotification			NewMailNotification;
+		[case(0x0004)] FolderCreatedNotification		FolderCreatedNotification;
+		[case(0x0008)] FolderDeletedNotification		FolderDeletedNotification;
+		[case(0x0010)] FolderModifiedNotification_10		FolderModifiedNotification_10;
+		[case(0x0020)] FolderMoveCopyNotification		FolderMoveNotification;
+		[case(0x0040)] FolderMoveCopyNotification		FolderCopyNotification;
+		[case(0x0080)] SearchCompleteNotification		SearchCompleteNotification;
+		[case(0x0100)] HierarchyTableChange			HierarchyTableChange;
+		[case(0x0200)] IcsNotification				IcsNotification;
+		[case(0x1010)] FolderModifiedNotification_1010		FolderModifiedNotification_1010;
+		[case(0x2010)] FolderModifiedNotification_2010		FolderModifiedNotification_2010;
+		[case(0x3010)] FolderModifiedNotification_3010		FolderModifiedNotification_3010;
+ 		[case(0x8002)] NewMailNotification			NewMessageNotification;
+		[case(0x8004)] MessageCreatedNotification		MessageCreatedNotification;
+		[case(0x8008)] MessageDeletedNotification		MessageDeletedNotification;
+		[case(0x8010)] MessageModifiedNotification		MessageModifiedNotification;
+		[case(0x8020)] MessageMoveCopyNotification		MessageMoveNotification;
+		[case(0x8040)] MessageMoveCopyNotification		MessageCopyNotification;
+		[case(0x8100)] ContentsTableChange			ContentsTableChange;
+		[case(0xc008)] SearchMessageRemovedNotification		SearchMessageRemovedNotification;
+		[case(0xc010)] SearchMessageModifiedNotification	SearchMessageModifiedNotification;
+		[case(0xc100)] ContentsTableChange			SearchTableChange;
+	} NotificationData;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32						NotificationHandle;
+		uint8						LogonId;
+		NotificationFlags				NotificationType;
+		[switch_is(NotificationType)] NotificationData	NotificationData;
+	} Notify_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2b */
+	typedef [enum8bit] enum {
+		OpenStream_ReadOnly	= 0x0,
+		OpenStream_ReadWrite	= 0x1,
+		OpenStream_Create	= 0x2,
+		OpenStream_BestAccess	= 0x3
+	} OpenStream_OpenModeFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				handle_idx;
+		MAPITAGS			PropertyTag;
+		OpenStream_OpenModeFlags       	OpenModeFlags;
+	} OpenStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		StreamSize;
+	} OpenStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2c */
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0xBABE)] uint32	value;
+		[default];
+	} MaximumByteCount;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16						ByteCount;
+		[switch_is(ByteCount)]	MaximumByteCount	MaximumByteCount;
+	} ReadStream_req;
+
+	typedef [flag(NDR_ALIGN2)] struct {
+		[subcontext(2), flag(NDR_REMAINING)] DATA_BLOB data;
+	} ReadStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2d */
+	typedef [flag(NDR_NOALIGN)] struct {
+		[subcontext(2), flag(NDR_REMAINING)] DATA_BLOB	data;
+	} WriteStream_req;
+
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		WrittenSize;
+	} WriteStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2e */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		Origin;
+		hyper		Offset;
+	} SeekStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		NewPosition;
+	} SeekStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x2f */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		SizeStream;
+	} SetStreamSize_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetStreamSize_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x30 */
+	typedef [bitmap32bit, flag(NDR_PAHEX)] bitmap {
+		STOP_SEARCH			= 0x00000001,
+		RESTART_SEARCH			= 0x00000002,
+		RECURSIVE_SEARCH		= 0x00000004,
+		SHALLOW_SEARCH			= 0x00000008,
+		FOREGROUND_SEARCH		= 0x00000010,
+		BACKGROUND_SEARCH		= 0x00000020,
+	        CONTENT_INDEXED_SEARCH		= 0x00010000,
+		NON_CONTENT_INDEXED_SEARCH	= 0x00020000,
+		STATIC_SEARCH			= 0x00040000
+	} SearchFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		[subcontext(2)] mapi_SRestriction	res;
+		uint16					FolderIdCount;
+		hyper					FolderIds[FolderIdCount];
+		SearchFlags				SearchFlags;
+	} SetSearchCriteria_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetSearchCriteria_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x31 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	UseUnicode;
+		boolean8	IncludeRestriction;
+		boolean8	IncludeFolders;
+	} GetSearchCriteria_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		[subcontext(2)] mapi_SRestriction	res;
+ 		uint8					unknown;
+		uint16					FolderIdCount;
+		hyper					FolderIds[FolderIdCount];
+		SearchFlags				SearchFlags;
+	} GetSearchCriteria_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x32 */
+	typedef [enum8bit] enum {
+		None		= 0x0,	/* None */
+		PreProcess	= 0x1,	/* Needs to be preprocessed by the server */
+		NeedsSpooler	= 0x2	/* Is to be processed by a client spooler */
+	} SubmitFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SubmitFlags    	SubmitFlags;
+	} SubmitMessage_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SubmitMessage_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x33 */
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		uint8		handle_idx;
+ 		uint16		count;
+ 		hyper		message_id[count];
+		boolean8	WantAsynchronous;
+		boolean8	WantCopy;
+	} MoveCopyMessages_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8       	PartialCompletion;
+	} MoveCopyMessages_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x34 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		FolderId;
+		hyper		MessageId;
+	} AbortSubmit_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} AbortSubmit_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x35 */
+	typedef [nodiscriminant, flag(NDR_NOALIGN)] union {
+		[case(0x0)] astring			lpszA;
+		[case(0x1)][flag(STR_NULLTERM)] string	lpszW;
+	} Folder_name;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					handle_idx;
+		boolean8				WantAsynchronous;
+		boolean8				UseUnicode;
+		hyper					FolderId;
+		[switch_is(UseUnicode)] Folder_name	NewFolderName;
+	} MoveFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8				PartialCompletion;
+	} MoveFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x36 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					handle_idx;
+		boolean8				WantAsynchronous;
+		boolean8				WantRecursive;
+		boolean8				UseUnicode;
+		hyper					FolderId;
+		[switch_is(UseUnicode)] Folder_name	NewFolderName;
+	} CopyFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8				PartialCompletion;
+	} CopyFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x37 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} QueryColumnsAll_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyTagCount;
+		MAPITAGS	PropertyTags[PropertyTagCount];
+	} QueryColumnsAll_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x38 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} Abort_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TableStatus	TableStatus;
+	} Abort_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x39 */
+	typedef [bitmap8bit] bitmap {
+		CopyFlagsMove		= 0x1,	/* Move properties */
+		CopyFlagsNoOverwrite	= 0x2	/* Do not overwrite existing properties */
+	} CopyFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8			handle_idx;
+		boolean8		WantAsynchronous;
+		boolean8		WantSubObjects;
+		CopyFlags		CopyFlags;
+		mapi_SPropTagArray	ExcludedTags;
+	} CopyTo_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];
+	} CopyTo_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x3a */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		hyper		ByteCount;
+	} CopyToStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		ReadByteCount;
+		hyper		WrittenByteCount;
+	} CopyToStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x3e */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		uint8		padding;
+	} GetTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x3f */
+	typedef [bitmap8bit] bitmap {
+		RulesTableFlags_Unicode	= 0x40
+	} RulesTableFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		RulesTableFlags	TableFlags;
+	} GetRulesTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetRulesTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x40 */
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		mapi_SRowList		rowList;
+	} ModifyTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		[flag(NDR_REMAINING)] DATA_BLOB remaining;
+	} ModifyTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x41 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulRowFlags     		RulesDataFlags;
+		mapi_SPropValue_array	PropertyValues;
+	} RulesData;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		ModifyRulesFlags;
+		uint16		RulesCount;
+ 		RulesData	RulesData[RulesCount];
+	} ModifyRules_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} ModifyRules_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x42 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		FolderId;
+	} GetOwningServers_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		OwningServersCount;
+		uint16		CheapServersCount;
+		astring		OwningServers[OwningServersCount];
+	} GetOwningServers_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x43 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper	Id;
+	} LongTermIdFromId_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID	DatabaseGuid;
+		uint8	GlobalCounter[6];
+		uint16	padding;
+	} LongTermId;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		LongTermId	LongTermId;
+	} LongTermIdFromId_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x44 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		LongTermId	LongTermId;
+	} IdFromLongTermId_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		Id;
+	} IdFromLongTermId_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x45 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		FolderId;
+	} PublicFolderIsGhosted_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8				IsGhosted;
+		[switch_is(IsGhosted)] IsGhosted	Ghost;
+	} PublicFolderIsGhosted_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x46 */
+	typedef [enum8bit, flag(NDR_PAHEX)] enum {
+		MAPI_READONLY   = 0x0,
+		MAPI_READWRITE	= 0x1,
+		MAPI_CREATE	= 0x2
+	} OpenEmbeddedMessage_OpenModeFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					handle_idx;
+		uint16					CodePageId;
+		OpenEmbeddedMessage_OpenModeFlags	OpenModeFlags;
+	} OpenEmbeddedMessage_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		       	Reserved;
+		hyper		       	MessageId;
+		boolean8	       	HasNamedProperties;
+		TypedString	       	SubjectPrefix;
+		TypedString	       	NormalizedSubject;
+		uint16		       	RecipientCount;
+		uint16		       	ColumnCount;
+		MAPITAGS	       	RecipientColumns[ColumnCount];
+		uint8		       	RowCount;
+		OpenRecipientRow       	RecipientRows[RowCount];
+	} OpenEmbeddedMessage_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x47 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetSpooler_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetSpooler_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x48 */
+	typedef [enum8bit] enum {
+		LockState_1stLock      	= 0x0,
+		LockState_1stUnlock	= 0x1,
+		LockState_1stFinished	= 0x2
+	} LockState;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		MessageId;
+		LockState	LockState;
+	} SpoolerLockMessage_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SpoolerLockMessage_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x49 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} AddressTypes_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16 		cValues;
+		uint16 		size;
+		mapi_LPSTR	transport[cValues];
+	} AddressTypes_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x4a  */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} TransportSend_req;
+
+	typedef [nodiscriminant] union {
+		[case(0x0)] mapi_SPropValue_array	lpProps;
+		[case(0x1)];
+	} TransportSend_lpProps;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8						NoPropertiesReturned;
+		[switch_is(NoPropertiesReturned)] TransportSend_lpProps	properties;
+	} TransportSend_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x4e  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		BufferSize;
+	} FastTransferSourceGetBuffer_req;
+
+	typedef [enum16bit] enum {
+		TransferStatus_Error	= 0x0,
+		TransferStatus_Partial	= 0x1,
+		TransferStatus_NoRoom	= 0x2,
+		TransferStatus_Done	= 0x3
+	} TransferStatus;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		TransferStatus	TransferStatus;
+		uint16		InProgressCount;
+		uint16		TotalStepCount;
+		uint8		Reserved;
+		uint16		TransferBufferSize;
+		[subcontext(0),subcontext_size(TransferBufferSize),flag(NDR_REMAINING)] DATA_BLOB TransferBuffer;
+	} FastTransferSourceGetBuffer_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x4f  */
+	typedef [enum8bit] enum {
+		DIR_FORWARD  = 0x0,
+		DIR_BACKWARD = 0x1
+	} FindRow_ulFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		FindRow_ulFlags	ulFlags;
+  		[subcontext(2)] mapi_SRestriction res;
+		BOOKMARK	origin;
+		SBinary_short	bookmark;
+	} FindRow_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		RowNoLongerVisible;
+	  	uint8		HasRowData;
+		[flag(NDR_NOALIGN)] DATA_BLOB row;
+	} FindRow_repl;
+
+	/**************************/
+	/* EcDoRpc Function 0x50  */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	WantCancel;
+	} Progress_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		CompletedTaskCount;
+		uint32		TotalTaskCount;
+	} Progress_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x55 */
+	typedef [enum8bit] enum {
+		MNID_ID = 0,
+		MNID_STRING = 1
+	} ulKind;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8				NameSize;
+		[flag(STR_NULLTERM)] string	Name;
+	} mapi_name;
+
+	typedef [nodiscriminant] union {
+		[case(MNID_ID)] uint32		lid;
+		[case(MNID_STRING)] mapi_name	lpwstr;
+	} Kind;
+	
+	typedef [flag(NDR_NOALIGN)] struct {
+		ulKind				ulKind;
+		GUID				lpguid;
+		[switch_is(ulKind)] Kind	kind;
+	} MAPINAMEID;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		MAPITAGS	ulPropTag;
+	} GetNamesFromIDs_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		count;
+		MAPINAMEID	nameid[count];
+	} GetNamesFromIDs_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x56 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		ulFlags;
+		uint16		count;
+		MAPINAMEID	nameid[count];
+	} GetIDsFromNames_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		count;
+		uint16		propID[count];
+	} GetIDsFromNames_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x58 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	WantAsynchronous;
+		boolean8	WantDeleteAssociated;
+	} EmptyFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	PartialCompletion;
+	} EmptyFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x59 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		MaxRowCount;
+		hyper		CategoryId;
+	} ExpandRow_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		ExpandedRowCount;
+		uint16		RowCount;
+		[flag(NDR_REMAINING)]DATA_BLOB  RowData;
+	} ExpandRow_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x5a */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		CategoryId;
+	} CollapseRow_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		CollapsedRowCount;
+	} CollapseRow_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x5d */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} CommitStream_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} CommitStream_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x5e */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetStreamSize_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		StreamSize;
+	} GetStreamSize_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x5f */
+	typedef [bitmap8bit] bitmap {
+		NoStrings	= 0x01,
+		NoIds	        = 0x02
+	} QueryFlags;
+
+	typedef [nodiscriminant] union {
+		[case(0x0)];
+	  	[case(0x1)] GUID guid;
+	} QueryNamedProperties_guid;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		QueryFlags		QueryFlags;
+		boolean8		HasGuid;
+		[switch_is(HasGuid)]	QueryNamedProperties_guid PropertyGuid;
+	} QueryNamedProperties_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		IdCount;
+		uint16		PropertyIds[IdCount];
+		MAPINAMEID	PropertyNames[IdCount];
+	} QueryNamedProperties_repl;
+  
+	/*************************/
+	/* EcDoRpc Function 0x60 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID	DatabaseGuid;
+	} GetPerUserLongTermIds_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		LongTermIdCount;
+		LongTermId	LongTermIds[LongTermIdCount];
+	} GetPerUserLongTermIds_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x61 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		LongTermId	LongTermId;
+	} GetPerUserGuid_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID		DatabaseGuid;
+	} GetPerUserGuid_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x63 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		FolderId[24];
+		boolean8	WhatIfChanged;
+		uint32		DataOffset;
+		uint16		MaxDataSize;
+	} ReadPerUserInformation_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	HasFinished;
+		uint16		DataSize;
+		[subcontext(0), subcontext_size(DataSize), flag(NDR_REMAINING)] DATA_BLOB Data;
+	} ReadPerUserInformation_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x66 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	WantAsynchronous;
+	  	MSGFLAG_READ	ReadFlags;
+	  	uint16		MessageIdCount;
+	  	hyper		MessageIds[MessageIdCount];
+	} SetReadFlags_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8	PartialCompletion;
+	} SetReadFlags_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x67 */
+	typedef [flag(NDR_NOALIGN)] struct {
+ 		uint8			handle_idx;
+		boolean8		WantAsynchronous;
+	  	CopyFlags		CopyFlags;
+		mapi_SPropTagArray	PropertyTags;
+	} CopyProperties_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];
+	} CopyProperties_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x68 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		unknown;
+		hyper		fid;
+		astring		lpszMessageClass;
+		FILETIME	modiftime;
+	} ReceiveFolder;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetReceiveFolderTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		cValues;
+		ReceiveFolder	entries[cValues];
+	} GetReceiveFolderTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x6b */
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		RowId;
+	  	uint32		RowInstanceNumber;
+	} GetCollapseState_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	CollapseState;
+	} GetCollapseState_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x6c */
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	CollapseState;
+	} SetCollapseState_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	bookmark;
+	} SetCollapseState_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x6d */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetTransportFolder_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		FolderId;
+	} GetTransportFolder_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x6e */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16	SessionIndex;
+	} Pending_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x6f */
+	typedef [enum8bit,flag(NDR_NOALIGN)] enum {
+		OPTION_TYPE_RECIPIENT	= 0x1,
+		OPTION_TYPE_MESSAGE	= 0x2
+	} OPTIONDATA_ulFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		astring			transport;
+		OPTIONDATA_ulFlags     	type;
+	} RegisterOptions_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		OPTIONDATA_ulFlags     	ulFlags;
+		DATA_BLOB		data;
+	} RegisterOptions_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x70 */
+	typedef [enum8bit] enum {
+		Contents	= 0x1,
+		Hierarchy	= 0x2
+	} SynchronizationType;
+
+	typedef [bitmap8bit] bitmap {
+		SendOptions_Unicode		= 0x1,
+		SendOptions_ForUpload		= 0x3,
+		SendOptions_RecoverMode		= 0x4,
+		SendOptions_ForceUnicode	= 0x8,
+		SendOptions_Partial		= 0x10
+	} SendOptions;
+
+	typedef [bitmap16bit] bitmap {
+		SynchronizationFlag_Unicode			= 0x1,
+		SynchronizationFlag_NoDeletions			= 0x2,
+		SynchronizationFlag_NoSoftDeletions		= 0x4,
+	       	SynchronizationFlag_ReadState			= 0x8,
+	       	SynchronizationFlag_FAI				= 0x10,
+	       	SynchronizationFlag_Normal			= 0x20,
+	       	SynchronizationFlag_OnlySpecifiedProperties	= 0x80,
+	       	SynchronizationFlag_NoForeignIdentifiers	= 0x100,
+	       	SynchronizationFlag_Reserved			= 0x1000,
+	       	SynchronizationFlag_BestBody			= 0x2000,
+	       	SynchronizationFlag_IgnoreSpecifiedOnFAI	= 0x4000,
+	       	SynchronizationFlag_Progress			= 0x8000
+	} SynchronizationFlag;
+
+	typedef [bitmap32bit] bitmap {
+		Eid			= 0x00000001,
+		MessageSize		= 0x00000002,
+		Cn			= 0x00000004,
+	        OrderByDeliveryTime	= 0x00000008
+	} SynchronizationExtraFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8					handle_idx;
+		SynchronizationType			SynchronizationType;
+		SendOptions				SendOptions;
+		SynchronizationFlag			SynchronizationFlag;
+		uint16					RestrictionSize;
+ 		[subcontext(0),subcontext_size(RestrictionSize),flag(NDR_REMAINING)] DATA_BLOB	RestrictionData;
+		SynchronizationExtraFlags		SynchronizationExtraFlags;
+		mapi_SPropTagArray			PropertyTags;
+	} SyncConfigure_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncConfigure_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x72 */
+	typedef [bitmap8bit] bitmap {
+		ImportFlag_Associated		= 0x10,
+	       	ImportFlag_FailOnConflict	= 0x40
+	} ImportFlag;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8			handle_idx;
+		ImportFlag		ImportFlag;
+		mapi_SPropValue_array	PropertyValues;
+	} SyncImportMessageChange_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		MessageId;
+	} SyncImportMessageChange_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x73 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		mapi_SPropValue_array	HierarchyValues;
+		mapi_SPropValue_array	PropertyValues;
+	} SyncImportHierarchyChange_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FolderId;
+	} SyncImportHierarchyChange_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x74 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8		IsHierarchy;
+		mapi_SPropValue_array	PropertyValues;
+	} SyncImportDeletes_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncImportDeletes_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x75 */
+	typedef [v1_enum,flag(NDR_PAHEX)] enum {
+		PidTagIdsetGiven	= 0x40170003,
+		PidTagCnsetSeen		= 0x67960102,
+		PidTagCnsetSeenFAI	= 0x67da0102,
+		PidTagCnsetRead		= 0x67d20102
+	} StateProperty;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		StateProperty		StateProperty;
+		uint32			TransferBufferSize;
+	} SyncUploadStateStreamBegin_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncUploadStateStreamBegin_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x76 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32			StreamDataSize;
+		uint8			StreamData[StreamDataSize];
+	} SyncUploadStateStreamContinue_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncUploadStateStreamContinue_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x77 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncUploadStateStreamEnd_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncUploadStateStreamEnd_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x78 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		SourceFolderIdSize;
+		uint8		SourceFolderId[SourceFolderIdSize];
+		uint32		SourceMessageIdSize;
+		uint8		SourceMessageId[SourceMessageIdSize];
+		uint32		PredecessorChangeListSize;
+		uint8		PredecessorChangeList[PredecessorChangeListSize];
+		uint32		DestinationMessageIdSize;
+		uint8		DestinationMessageId[DestinationMessageIdSize];
+		uint32		ChangeNumberSize;
+		uint8		ChangeNumber[ChangeNumberSize];
+	} SyncImportMessageMove_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper		MessageId;
+	} SyncImportMessageMove_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x79 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		[subcontext(2)] mapi_SPropValue_array	values;
+	} SetPropertiesNoReplicate_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];
+	} SetPropertiesNoReplicate_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x7a */
+	typedef [flag(NDR_NOALIGN)] struct {
+		mapi_SPropTagArray	PropertyTags;
+	} DeletePropertiesNoReplicate_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		PropertyProblemCount;
+		PropertyProblem	PropertyProblem[PropertyProblemCount];
+	} DeletePropertiesNoReplicate_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x7b */
+	typedef [public,bitmap32bit] bitmap {
+		STORE_HAS_SEARCHES		= 0x010000000
+	} StoreState;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} GetStoreState_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		StoreState	StoreState;
+	} GetStoreState_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x7e */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		boolean8	IsContentsCollector;
+	} SyncOpenCollector_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncOpenCollector_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x7f */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint32		IdCount;
+	} GetLocalReplicaIds_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID		ReplGuid;
+		uint8		GlobalCount[6];
+	} GetLocalReplicaIds_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x80 */
+// 	typedef [flag(NDR_NOALIGN)] struct {
+// 		uint16		MessageSize;
+// 		uint8		MessageId[MessageSize];
+// 		boolean8	MarkAsRead;
+// 	} MessageReadStates;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint16		MessageReadStateSize;
+		[subcontext(0),subcontext_size(MessageReadStateSize),flag(NDR_REMAINING)] DATA_BLOB MessageStates;
+	} SyncImportReadStateChanges_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncImportReadStateChanges_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x81 */
+	typedef [flag(NDR_NOALIGN)] struct {
+	} ResetTable_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} ResetTable_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x82 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+	} SyncGetTransferState_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SyncGetTransferState_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x87 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		handle_idx;
+		asclstr		name;
+	} OpenPublicFolderByName_req; 
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		boolean8				HasRules;
+		boolean8				IsGhosted;
+		[switch_is(IsGhosted)] IsGhosted	Ghost;
+	} OpenPublicFolderByName_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x88 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		GUID	NotificationGuid;
+	} SetSyncNotificationGuid_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} SetSyncNotificationGuid_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0x89 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	bookmark;
+	} FreeBookmark_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+	} FreeBookmark_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xFE */
+	typedef [public,bitmap8bit] bitmap {
+		LogonPrivate	= 0x1,
+		UnderCover	= 0x2,
+		Ghosted		= 0x4,
+		SpIProcess	= 0x8
+	} LogonFlags;
+
+	typedef [public,bitmap32bit] bitmap {
+		PUBLIC				= 0x2,
+		HOME_LOGON			= 0x4,
+		TAKE_OWNERSHIP			= 0x8,
+		ALTERNATE_SERVER		= 0x100,
+		IGNORE_HOME_MDB			= 0x200,
+		NO_MAIL				= 0x400,
+		USE_PER_MDB_REPLID_MAPPING	= 0x010000000
+	} OpenFlags;
+
+	typedef [enum8bit] enum {
+		DayOfWeek_Sunday	= 0x0,
+		DayOfWeek_Monday	= 0x1,
+		DayOfWeek_Tuesday	= 0x2,
+		DayOfWeek_Wednesday	= 0x3,
+		DayOfWeek_Thursday	= 0x4,
+		DayOfWeek_Friday	= 0x5,
+		DayOfWeek_Saturday	= 0x6
+	} DayOfWeek;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		uint8		Seconds;
+		uint8		Minutes;
+		uint8		Hour;
+		DayOfWeek	DayOfWeek;
+		uint8		Day;
+		uint8		Month;
+		uint16		Year;
+	} LogonTime;
+
+	typedef [bitmap8bit] bitmap {
+		ResponseFlags_Reserved		= 0x1,
+		ResponseFlags_OwnerRight	= 0x2,
+		ResponseFlags_SendAsRight	= 0x4,
+		ResponseFlags_OOF		= 0x10
+	} ResponseFlags;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FolderIds[13];
+		uint16			ReplId;
+		GUID			Guid;
+		GUID			PerUserGuid;
+	} store_pf;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		hyper			FolderIds[13];
+		ResponseFlags		ResponseFlags;
+		GUID			MailboxGuid;
+		uint16			ReplId;
+		GUID			ReplGUID;
+		LogonTime		LogonTime;
+		hyper			GwartTime;
+		StoreState		StoreState;
+	} store_mailbox;
+
+	typedef [nodiscriminant] union {
+ 		[case(0x0)]		store_pf	store_pf;
+		[case(LogonPrivate)]	store_mailbox	store_mailbox;
+	} LogonType;
+
+	typedef [nopush,flag(NDR_NOALIGN)] struct {
+		LogonFlags	LogonFlags;
+		OpenFlags	OpenFlags;
+		StoreState	StoreState;
+		ascstr3		EssDN;
+	} Logon_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		LogonFlags				LogonFlags;
+		[switch_is(LogonFlags)] LogonType	LogonType;
+	} Logon_repl;
+
+	/*************************/
+	/* EcDoRpc Function 0xA5 */
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	bin;
+	} proxypack_req;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		SBinary_short	bin;
+	} proxypack_repl;
+
+	typedef [public, nodiscriminant] union {
+		[case(op_MAPI_Release)] Release_req mapi_Release;
+		[case(op_MAPI_OpenFolder)] OpenFolder_req mapi_OpenFolder;
+		[case(op_MAPI_OpenMessage)] OpenMessage_req mapi_OpenMessage;
+		[case(op_MAPI_GetHierarchyTable)] GetHierarchyTable_req mapi_GetHierarchyTable;
+		[case(op_MAPI_GetContentsTable)] GetContentsTable_req mapi_GetContentsTable;
+		[case(op_MAPI_CreateMessage)] CreateMessage_req mapi_CreateMessage;
+		[case(op_MAPI_GetProps)] GetProps_req mapi_GetProps;
+		[case(op_MAPI_GetPropsAll)] GetPropsAll_req mapi_GetPropsAll;
+		[case(op_MAPI_GetPropList)] GetPropList_req mapi_GetPropList;
+		[case(op_MAPI_SetProps)] SetProps_req mapi_SetProps;
+		[case(op_MAPI_DeleteProps)] DeleteProps_req mapi_DeleteProps;
+		[case(op_MAPI_SaveChangesMessage)] SaveChangesMessage_req mapi_SaveChangesMessage;
+		[case(op_MAPI_SetMessageReadFlag)] SetMessageReadFlag_req mapi_SetMessageReadFlag;
+		[case(op_MAPI_ReloadCachedInformation)] ReloadCachedInformation_req mapi_ReloadCachedInformation;
+		[case(op_MAPI_SetColumns)] SetColumns_req mapi_SetColumns;
+		[case(op_MAPI_SortTable)] SortTable_req mapi_SortTable;
+		[case(op_MAPI_Restrict)] Restrict_req mapi_Restrict;
+		[case(op_MAPI_RemoveAllRecipients)] RemoveAllRecipients_req mapi_RemoveAllRecipients;
+		[case(op_MAPI_ModifyRecipients)] ModifyRecipients_req mapi_ModifyRecipients;
+		[case(op_MAPI_ReadRecipients)] ReadRecipients_req mapi_ReadRecipients;
+		[case(op_MAPI_QueryRows)] QueryRows_req mapi_QueryRows;
+		[case(op_MAPI_GetStatus)] GetStatus_req mapi_GetStatus;
+		[case(op_MAPI_QueryPosition)] QueryPosition_req mapi_QueryPosition;
+		[case(op_MAPI_SeekRow)] SeekRow_req mapi_SeekRow;
+		[case(op_MAPI_SeekRowBookmark)] SeekRowBookmark_req mapi_SeekRowBookmark;
+		[case(op_MAPI_SeekRowApprox)] SeekRowApprox_req mapi_SeekRowApprox;
+		[case(op_MAPI_CreateBookmark)] CreateBookmark_req mapi_CreateBookmark;
+		[case(op_MAPI_CreateFolder)] CreateFolder_req mapi_CreateFolder;
+		[case(op_MAPI_DeleteFolder)] DeleteFolder_req mapi_DeleteFolder;
+		[case(op_MAPI_DeleteMessages)] DeleteMessages_req mapi_DeleteMessages;
+		[case(op_MAPI_GetMessageStatus)] GetMessageStatus_req mapi_GetMessageStatus;
+		[case(op_MAPI_SetMessageStatus)] SetMessageStatus_req mapi_SetMessageStatus;
+		[case(op_MAPI_GetAttachmentTable)] GetAttachmentTable_req mapi_GetAttachmentTable;
+		[case(op_MAPI_OpenAttach)] OpenAttach_req mapi_OpenAttach;
+		[case(op_MAPI_CreateAttach)] CreateAttach_req mapi_CreateAttach;
+		[case(op_MAPI_DeleteAttach)] DeleteAttach_req mapi_DeleteAttach;
+		[case(op_MAPI_SaveChangesAttachment)] SaveChangesAttachment_req mapi_SaveChangesAttachment;
+		[case(op_MAPI_SetReceiveFolder)] SetReceiveFolder_req mapi_SetReceiveFolder;
+		[case(op_MAPI_GetReceiveFolder)] GetReceiveFolder_req mapi_GetReceiveFolder;
+		[case(op_MAPI_RegisterNotification)] RegisterNotification_req mapi_RegisterNotification;
+		[case(op_MAPI_OpenStream)] OpenStream_req mapi_OpenStream;
+		[case(op_MAPI_ReadStream)] ReadStream_req mapi_ReadStream;
+		[case(op_MAPI_WriteStream)] WriteStream_req mapi_WriteStream;
+		[case(op_MAPI_SeekStream)] SeekStream_req mapi_SeekStream;
+		[case(op_MAPI_SetStreamSize)] SetStreamSize_req mapi_SetStreamSize;
+		[case(op_MAPI_SetSearchCriteria)] SetSearchCriteria_req mapi_SetSearchCriteria;
+		[case(op_MAPI_GetSearchCriteria)] GetSearchCriteria_req mapi_GetSearchCriteria;
+		[case(op_MAPI_SubmitMessage)] SubmitMessage_req mapi_SubmitMessage;
+		[case(op_MAPI_MoveCopyMessages)] MoveCopyMessages_req mapi_MoveCopyMessages;
+		[case(op_MAPI_AbortSubmit)] AbortSubmit_req mapi_AbortSubmit;
+		[case(op_MAPI_MoveFolder)] MoveFolder_req mapi_MoveFolder;
+		[case(op_MAPI_CopyFolder)] CopyFolder_req mapi_CopyFolder;
+		[case(op_MAPI_QueryColumnsAll)] QueryColumnsAll_req mapi_QueryColumnsAll;
+		[case(op_MAPI_Abort)] Abort_req mapi_Abort;
+		[case(op_MAPI_CopyTo)] CopyTo_req mapi_CopyTo;
+		[case(op_MAPI_CopyToStream)] CopyToStream_req mapi_CopyToStream;
+		[case(op_MAPI_GetTable)] GetTable_req mapi_GetTable;
+		[case(op_MAPI_GetRulesTable)] GetRulesTable_req mapi_GetRulesTable;
+		[case(op_MAPI_ModifyTable)] ModifyTable_req mapi_ModifyTable;
+		[case(op_MAPI_ModifyRules)] ModifyRules_req mapi_ModifyRules;
+		[case(op_MAPI_GetOwningServers)] GetOwningServers_req mapi_GetOwningServers;
+		[case(op_MAPI_LongTermIdFromId)] LongTermIdFromId_req mapi_LongTermIdFromId;
+		[case(op_MAPI_IdFromLongTermId)] IdFromLongTermId_req mapi_IdFromLongTermId;
+		[case(op_MAPI_PublicFolderIsGhosted)] PublicFolderIsGhosted_req mapi_PublicFolderIsGhosted;
+		[case(op_MAPI_OpenEmbeddedMessage)] OpenEmbeddedMessage_req mapi_OpenEmbeddedMessage;
+		[case(op_MAPI_SetSpooler)] SetSpooler_req mapi_SetSpooler;
+		[case(op_MAPI_SpoolerLockMessage)] SpoolerLockMessage_req mapi_SpoolerLockMessage;
+		[case(op_MAPI_AddressTypes)] AddressTypes_req mapi_AddressTypes;
+		[case(op_MAPI_TransportSend)] TransportSend_req mapi_TransportSend;
+		[case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_req mapi_FastTransferSourceGetBuffer;
+		[case(op_MAPI_FindRow)] FindRow_req mapi_FindRow;
+		[case(op_MAPI_Progress)] Progress_req mapi_Progress;
+		[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_req mapi_GetNamesFromIDs;
+		[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_req mapi_GetIDsFromNames;
+		[case(op_MAPI_EmptyFolder)] EmptyFolder_req mapi_EmptyFolder;
+		[case(op_MAPI_ExpandRow)] ExpandRow_req mapi_ExpandRow;
+		[case(op_MAPI_CollapseRow)] CollapseRow_req mapi_CollapseRow;
+		[case(op_MAPI_CommitStream)] CommitStream_req mapi_CommitStream;
+		[case(op_MAPI_GetStreamSize)] GetStreamSize_req mapi_GetStreamSize;
+		[case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_req mapi_QueryNamedProperties;
+		[case(op_MAPI_GetPerUserLongTermIds)] GetPerUserLongTermIds_req mapi_GetPerUserLongTermIds;
+		[case(op_MAPI_GetPerUserGuid)] GetPerUserGuid_req mapi_GetPerUserGuid;
+		[case(op_MAPI_ReadPerUserInformation)] ReadPerUserInformation_req mapi_ReadPerUserInformation;
+		[case(op_MAPI_SetReadFlags)] SetReadFlags_req mapi_SetReadFlags;
+		[case(op_MAPI_CopyProperties)] CopyProperties_req mapi_CopyProperties;
+		[case(op_MAPI_GetReceiveFolderTable)] GetReceiveFolderTable_req mapi_GetReceiveFolderTable;
+		[case(op_MAPI_GetCollapseState)] GetCollapseState_req mapi_GetCollapseState;
+		[case(op_MAPI_SetCollapseState)] SetCollapseState_req mapi_SetCollapseState;
+		[case(op_MAPI_GetTransportFolder)] GetTransportFolder_req mapi_GetTransportFolder;
+		[case(op_MAPI_RegisterOptions)] RegisterOptions_req mapi_RegisterOptions;
+		[case(op_MAPI_SyncConfigure)] SyncConfigure_req mapi_SyncConfigure;
+		[case(op_MAPI_SyncImportMessageChange)] SyncImportMessageChange_req mapi_SyncImportMessageChange;
+		[case(op_MAPI_SyncImportHierarchyChange)] SyncImportHierarchyChange_req mapi_SyncImportHierarchyChange;
+		[case(op_MAPI_SyncImportDeletes)] SyncImportDeletes_req mapi_SyncImportDeletes;
+		[case(op_MAPI_SyncUploadStateStreamBegin)] SyncUploadStateStreamBegin_req mapi_SyncUploadStateStreamBegin;
+		[case(op_MAPI_SyncUploadStateStreamContinue)] SyncUploadStateStreamContinue_req mapi_SyncUploadStateStreamContinue;
+		[case(op_MAPI_SyncUploadStateStreamEnd)] SyncUploadStateStreamEnd_req mapi_SyncUploadStateStreamEnd;
+		[case(op_MAPI_SyncImportMessageMove)] SyncImportMessageMove_req mapi_SyncImportMessageMove;
+		[case(op_MAPI_SetPropertiesNoReplicate)] SetPropertiesNoReplicate_req mapi_SetPropertiesNoReplicate;
+		[case(op_MAPI_DeletePropertiesNoReplicate)] DeletePropertiesNoReplicate_req mapi_DeletePropertiesNoReplicate;
+		[case(op_MAPI_GetStoreState)] GetStoreState_req mapi_GetStoreState;
+		[case(op_MAPI_SyncOpenCollector)] SyncOpenCollector_req mapi_SyncOpenCollector;
+		[case(op_MAPI_GetLocalReplicaIds)] GetLocalReplicaIds_req mapi_GetLocalReplicaIds;
+		[case(op_MAPI_SyncImportReadStateChanges)] SyncImportReadStateChanges_req mapi_SyncImportReadStateChanges;
+		[case(op_MAPI_ResetTable)] ResetTable_req mapi_ResetTable;
+		[case(op_MAPI_SyncGetTransferState)] SyncGetTransferState_req mapi_SyncGetTransferState;
+		[case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_req mapi_OpenPublicFolderByName;
+		[case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_req mapi_SetSyncNotificationGuid;
+		[case(op_MAPI_FreeBookmark)] FreeBookmark_req mapi_FreeBookmark;
+		[case(op_MAPI_Logon)] Logon_req mapi_Logon;
+		[case(op_MAPI_proxypack)] proxypack_req mapi_proxypack;
+	} EcDoRpc_MAPI_REQ_UNION;
+
+	typedef [public, nodiscriminant] union {
+ 		[case(op_MAPI_Release)] Release_repl mapi_Release;
+		[case(op_MAPI_OpenFolder)] OpenFolder_repl mapi_OpenFolder;
+		[case(op_MAPI_OpenMessage)] OpenMessage_repl mapi_OpenMessage;
+		[case(op_MAPI_GetHierarchyTable)] GetHierarchyTable_repl mapi_GetHierarchyTable;
+		[case(op_MAPI_GetContentsTable)] GetContentsTable_repl mapi_GetContentsTable;
+		[case(op_MAPI_CreateMessage)] CreateMessage_repl mapi_CreateMessage;
+		[case(op_MAPI_GetProps)] GetProps_repl mapi_GetProps;
+		[case(op_MAPI_GetPropsAll)] GetPropsAll_repl mapi_GetPropsAll;
+		[case(op_MAPI_GetPropList)] GetPropList_repl mapi_GetPropList;
+		[case(op_MAPI_SetProps)] SetProps_repl mapi_SetProps;
+		[case(op_MAPI_DeleteProps)] DeleteProps_repl mapi_DeleteProps;
+		[case(op_MAPI_SaveChangesMessage)] SaveChangesMessage_repl mapi_SaveChangesMessage;
+		[case(op_MAPI_RemoveAllRecipients)] RemoveAllRecipients_repl mapi_RemoveAllRecipients;
+		[case(op_MAPI_ModifyRecipients)] ModifyRecipients_repl mapi_ModifyRecipients;
+		[case(op_MAPI_ReadRecipients)] ReadRecipients_repl mapi_ReadRecipients;
+		[case(op_MAPI_SetMessageReadFlag)] SetMessageReadFlag_repl mapi_SetMessageReadFlag;
+		[case(op_MAPI_ReloadCachedInformation)] ReloadCachedInformation_repl mapi_ReloadCachedInformation;
+		[case(op_MAPI_SetColumns)] SetColumns_repl mapi_SetColumns;
+		[case(op_MAPI_SortTable)] SortTable_repl mapi_SortTable;
+		[case(op_MAPI_Restrict)] Restrict_repl mapi_Restrict;
+		[case(op_MAPI_QueryRows)] QueryRows_repl mapi_QueryRows;
+		[case(op_MAPI_GetStatus)] GetStatus_repl mapi_GetStatus;
+		[case(op_MAPI_QueryPosition)] QueryPosition_repl mapi_QueryPosition;
+		[case(op_MAPI_SeekRow)] SeekRow_repl mapi_SeekRow;
+		[case(op_MAPI_SeekRowBookmark)] SeekRowBookmark_repl mapi_SeekRowBookmark;
+		[case(op_MAPI_SeekRowApprox)] SeekRowApprox_repl mapi_SeekRowApprox;
+		[case(op_MAPI_CreateBookmark)] CreateBookmark_repl mapi_CreateBookmark;
+		[case(op_MAPI_CreateFolder)] CreateFolder_repl mapi_CreateFolder;
+		[case(op_MAPI_DeleteFolder)] DeleteFolder_repl mapi_DeleteFolder;
+		[case(op_MAPI_DeleteMessages)] DeleteMessages_repl mapi_DeleteMessages;
+		[case(op_MAPI_SetMessageStatus)] SetMessageStatus_repl mapi_SetMessageStatus;
+		[case(op_MAPI_GetAttachmentTable)] GetAttachmentTable_repl mapi_GetAttachmentTable;
+		[case(op_MAPI_OpenAttach)] OpenAttach_repl mapi_OpenAttach;
+		[case(op_MAPI_CreateAttach)] CreateAttach_repl mapi_CreateAttach;
+		[case(op_MAPI_DeleteAttach)] DeleteAttach_repl mapi_DeleteAttach;
+		[case(op_MAPI_SaveChangesAttachment)] SaveChangesAttachment_repl mapi_SaveChangesAttachment;
+		[case(op_MAPI_SetReceiveFolder)] SetReceiveFolder_repl mapi_SetReceiveFolder;
+		[case(op_MAPI_GetReceiveFolder)] GetReceiveFolder_repl mapi_GetReceiveFolder;
+		[case(op_MAPI_RegisterNotification)] RegisterNotification_repl mapi_RegisterNotification;
+		[case(op_MAPI_Notify)] Notify_repl mapi_Notify;
+		[case(op_MAPI_OpenStream)] OpenStream_repl mapi_OpenStream;
+		[case(op_MAPI_ReadStream)] ReadStream_repl mapi_ReadStream;
+		[case(op_MAPI_WriteStream)] WriteStream_repl mapi_WriteStream;
+		[case(op_MAPI_SeekStream)] SeekStream_repl mapi_SeekStream;
+		[case(op_MAPI_SetStreamSize)] SetStreamSize_repl mapi_SetStreamSize;
+		[case(op_MAPI_SetSearchCriteria)] SetSearchCriteria_repl mapi_SetSearchCriteria;
+		[case(op_MAPI_GetSearchCriteria)] GetSearchCriteria_repl mapi_GetSearchCriteria;
+		[case(op_MAPI_SubmitMessage)] SubmitMessage_repl mapi_SubmitMessage;
+		[case(op_MAPI_MoveCopyMessages)] MoveCopyMessages_repl mapi_MoveCopyMessages;
+		[case(op_MAPI_AbortSubmit)] AbortSubmit_repl mapi_AbortSubmit;
+		[case(op_MAPI_MoveFolder)] MoveFolder_repl mapi_MoveFolder;
+		[case(op_MAPI_CopyFolder)] CopyFolder_repl mapi_CopyFolder;
+		[case(op_MAPI_QueryColumnsAll)] QueryColumnsAll_repl mapi_QueryColumnsAll;
+		[case(op_MAPI_Abort)] Abort_repl mapi_Abort;
+		[case(op_MAPI_CopyTo)] CopyTo_repl mapi_CopyTo;
+		[case(op_MAPI_CopyToStream)] CopyToStream_repl mapi_CopyToStream;
+		[case(op_MAPI_GetTable)] GetTable_repl mapi_GetTable;
+		[case(op_MAPI_GetRulesTable)] GetRulesTable_repl mapi_GetRulesTable;
+		[case(op_MAPI_ModifyTable)] ModifyTable_repl mapi_ModifyTable;
+		[case(op_MAPI_ModifyRules)] ModifyRules_repl mapi_ModifyRules;
+		[case(op_MAPI_GetOwningServers)] GetOwningServers_repl mapi_GetOwningServers;
+		[case(op_MAPI_LongTermIdFromId)] LongTermIdFromId_repl mapi_LongTermIdFromId;
+		[case(op_MAPI_IdFromLongTermId)] IdFromLongTermId_repl mapi_IdFromLongTermId;
+		[case(op_MAPI_PublicFolderIsGhosted)] PublicFolderIsGhosted_repl mapi_PublicFolderIsGhosted;
+		[case(op_MAPI_OpenEmbeddedMessage)] OpenEmbeddedMessage_repl mapi_OpenEmbeddedMessage;
+		[case(op_MAPI_SetSpooler)] SetSpooler_repl mapi_SetSpooler;
+		[case(op_MAPI_SpoolerLockMessage)] SpoolerLockMessage_repl mapi_SpoolerLockMessage;
+		[case(op_MAPI_AddressTypes)] AddressTypes_repl mapi_AddressTypes;
+		[case(op_MAPI_TransportSend)] TransportSend_repl mapi_TransportSend;
+		[case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_repl mapi_FastTransferSourceGetBuffer;
+		[case(op_MAPI_FindRow)] FindRow_repl mapi_FindRow;
+		[case(op_MAPI_Progress)] Progress_repl mapi_Progress;
+		[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_repl mapi_GetNamesFromIDs;
+		[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_repl mapi_GetIDsFromNames;
+		[case(op_MAPI_EmptyFolder)] EmptyFolder_repl mapi_EmptyFolder;
+		[case(op_MAPI_ExpandRow)] ExpandRow_repl mapi_ExpandRow;
+		[case(op_MAPI_CollapseRow)] CollapseRow_repl mapi_CollapseRow;
+		[case(op_MAPI_CommitStream)] CommitStream_repl mapi_CommitStream;
+		[case(op_MAPI_GetStreamSize)] GetStreamSize_repl mapi_GetStreamSize;
+		[case(op_MAPI_QueryNamedProperties)] QueryNamedProperties_repl mapi_QueryNamedProperties;
+		[case(op_MAPI_GetPerUserLongTermIds)] GetPerUserLongTermIds_repl mapi_GetPerUserLongTermIds;
+		[case(op_MAPI_GetPerUserGuid)] GetPerUserGuid_repl mapi_GetPerUserGuid;
+		[case(op_MAPI_ReadPerUserInformation)] ReadPerUserInformation_repl mapi_ReadPerUserInformation;
+		[case(op_MAPI_SetReadFlags)] SetReadFlags_repl mapi_SetReadFlags;
+		[case(op_MAPI_CopyProperties)] CopyProperties_repl mapi_CopyProperties;
+		[case(op_MAPI_GetReceiveFolderTable)] GetReceiveFolderTable_repl mapi_GetReceiveFolderTable;
+		[case(op_MAPI_Pending)] Pending_repl mapi_Pending;
+		[case(op_MAPI_GetCollapseState)] GetCollapseState_repl mapi_GetCollapseState;
+		[case(op_MAPI_SetCollapseState)] SetCollapseState_repl mapi_SetCollapseState;
+		[case(op_MAPI_GetTransportFolder)] GetTransportFolder_repl mapi_GetTransportFolder;
+		[case(op_MAPI_RegisterOptions)] RegisterOptions_repl mapi_RegisterOptions;
+		[case(op_MAPI_SyncConfigure)] SyncConfigure_repl mapi_SyncConfigure;
+		[case(op_MAPI_SyncImportMessageChange)] SyncImportMessageChange_repl mapi_SyncImportMessageChange;
+		[case(op_MAPI_SyncImportHierarchyChange)] SyncImportHierarchyChange_repl mapi_SyncImportHierarchyChange;
+		[case(op_MAPI_SyncImportDeletes)] SyncImportDeletes_repl mapi_SyncImportDeletes;
+		[case(op_MAPI_SyncUploadStateStreamBegin)] SyncUploadStateStreamBegin_repl mapi_SyncUploadStateStreamBegin;
+		[case(op_MAPI_SyncUploadStateStreamContinue)] SyncUploadStateStreamContinue_repl mapi_SyncUploadStateStreamContinue;
+		[case(op_MAPI_SyncUploadStateStreamEnd)] SyncUploadStateStreamEnd_repl mapi_SyncUploadStateStreamEnd;
+		[case(op_MAPI_SyncImportMessageMove)] SyncImportMessageMove_repl mapi_SyncImportMessageMove;
+		[case(op_MAPI_SetPropertiesNoReplicate)] SetPropertiesNoReplicate_repl mapi_SetPropertiesNoReplicate;
+		[case(op_MAPI_DeletePropertiesNoReplicate)] DeletePropertiesNoReplicate_repl mapi_DeletePropertiesNoReplicate;
+		[case(op_MAPI_GetStoreState)] GetStoreState_repl mapi_GetStoreState;
+		[case(op_MAPI_SyncOpenCollector)] SyncOpenCollector_repl mapi_SyncOpenCollector;
+		[case(op_MAPI_GetLocalReplicaIds)] GetLocalReplicaIds_repl mapi_GetLocalReplicaIds;
+		[case(op_MAPI_SyncImportReadStateChanges)] SyncImportReadStateChanges_repl mapi_SyncImportReadStateChanges;
+		[case(op_MAPI_ResetTable)] ResetTable_repl mapi_ResetTable;
+		[case(op_MAPI_SyncGetTransferState)] SyncGetTransferState_repl mapi_SyncGetTransferState;
+		[case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_repl mapi_OpenPublicFolderByName;
+		[case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_repl mapi_SetSyncNotificationGuid;
+		[case(op_MAPI_FreeBookmark)] FreeBookmark_repl mapi_FreeBookmark;
+		[case(op_MAPI_Logon)] Logon_repl mapi_Logon;
+		[case(op_MAPI_proxypack)] proxypack_repl mapi_proxypack;
+
+	} EcDoRpc_MAPI_REPL_UNION;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint8		opnum;
+		uint8		logon_id;
+		uint8		handle_idx;
+		[switch_is(opnum)] EcDoRpc_MAPI_REQ_UNION u;
+	} EcDoRpc_MAPI_REQ;
+
+	typedef [public,nopush,nopull,noprint,flag(NDR_NOALIGN)] struct {
+		uint8     	opnum;
+		uint8		handle_idx;
+		MAPISTATUS	error_code;
+		[switch_is(opnum)] EcDoRpc_MAPI_REPL_UNION u;
+	} EcDoRpc_MAPI_REPL;
+
+
+	/*
+	  Abstract way to represent MAPI content
+	*/
+
+  	typedef [public,nopull,nopush,noprint] struct {
+		uint32			mapi_len;	/* whole mapi_data length */
+		uint16			length;		/* content length */
+		EcDoRpc_MAPI_REQ	*mapi_req;
+		uint32			*handles;	/* handles id array */
+	} mapi_request;
+
+	typedef [public,nopull,nopush,noprint] struct {
+		uint32			mapi_len;
+		uint16			length;
+		EcDoRpc_MAPI_REPL	*mapi_repl;
+		uint32			*handles;
+	} mapi_response;
+	
+
+	[public] MAPISTATUS EcDoRpc(
+		[in,out]						policy_handle	*handle,
+		[in,out]						uint32		size,
+		[in,out]						uint32		offset,
+	  	[in] [subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	mapi_request	*mapi_request,
+		[out][subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	mapi_response	*mapi_response,
+		[in,out]						uint16		*length,
+		[in]							uint16		max_data
+		);
+
+	/*****************/
+	/* Function 0x03 */
+	void EcGetMoreRpc();
+
+	/*****************/
+	/* Function 0x04 */
+
+	/*
+	  we could directly use a NOTIFKEY structure rather than
+	  a uint8 array, but this makes the IDL more robust
+	
+	  sockaddr array is made of: 
+	   - family (unsigned short in) sa_family_t
+	   - address data sa_data[14];
+	 */
+
+	typedef struct {
+		uint16		cb;
+		uint8		ab[cb];
+	} NOTIFKEY;
+
+	MAPISTATUS EcRRegisterPushNotification(
+               [in,out] policy_handle			*handle,
+               [in] NotificationFlags			ulEventMask,
+	       [in,size_is(cbContext)] uint8		rgbContext[*],
+               [in] uint16				cbContext,
+	       [in] uint32				grbitAdviseBits,
+	       [in,size_is(cbCallbackAddress)] uint8	rgCallbackAddress[*],
+	       [in] uint16				cbCallbackAddress,
+	       [out,ref] uint32				*hNotification
+		);
+
+	/*****************/
+	/* Function 0x05 */
+	MAPISTATUS EcRUnregisterPushNotification(
+		[in,out]	policy_handle		*handle,
+		[in]		uint32			unknown[2]
+		);
+
+	/*****************/
+	/* Function 0x06 */
+	void EcDummyRpc();
+
+	/*****************/
+	/* Function 0x07 */
+	void EcRGetDCName();
+
+	/*****************/
+	/* Function 0x08 */
+	void EcRNetGetDCName();
+
+	/*****************/
+	/* Function 0x09 */
+	void EcDoRpcExt();
+
+	/*****************/
+	/* Function 0xa  */
+	MAPISTATUS EcDoConnectEx(
+		[out]				policy_handle	*handle,
+		[in,string,charset(DOS)]	uint8		szUserDN[],
+		[in]				uint32		ulFlags,
+		[in]				uint32		ulConMod,
+		[in]				uint32		cbLimit,
+		[in]				uint32		ulCpid,
+		[in]				uint32		ulLcidString,
+		[in]				uint32		ulLcidSort,
+		[in]				uint32		ulIcxrLink,
+		[in]				uint16		usFCanConvertCodePages,
+		[out]				uint32		*pcmsPollsMax,
+		[out]				uint32		*pcRetry,
+		[out]				uint32		*pcmsRetryDelay,
+		[out]				uint32		*picxr,
+		[out,unique,string,charset(DOS)]uint8		*szDNPrefix,
+		[out,unique,string,charset(DOS)]uint8		*szDisplayName,
+		[in]				uint16		rgwClientVersion[3],
+		[out]				uint16		rgwServerVersion[3],
+		[out]				uint16		rgwBestVersion[3],
+		[in,out]			uint32		*pulTimeStamp,
+		[in][subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)] DATA_BLOB rgbAuxIn,
+		[in,out][range(0x0,0x1008)]	uint32		*pcbAuxOut,
+		[in][flag(NDR_REMAINING)] DATA_BLOB data
+		);
+}
+
+[
+  uuid("c840a7dc-42c0-1a10-b4b9-08002b2fe182"),
+  pointer_default(unique),
+  helpstring("Unknown")
+] interface exchange_unknown
+{
+	void unknown_dummy();
+}
+

Added: trunk/openchange/idl_types.h
===================================================================
--- trunk/openchange/idl_types.h	                        (rev 0)
+++ trunk/openchange/idl_types.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,97 @@
+#define STR_ASCII	LIBNDR_FLAG_STR_ASCII
+#define STR_LEN4	LIBNDR_FLAG_STR_LEN4
+#define STR_SIZE4	LIBNDR_FLAG_STR_SIZE4
+#define STR_SIZE2	LIBNDR_FLAG_STR_SIZE2
+#define STR_NOTERM	LIBNDR_FLAG_STR_NOTERM
+#define STR_NULLTERM	LIBNDR_FLAG_STR_NULLTERM
+#define STR_BYTESIZE	LIBNDR_FLAG_STR_BYTESIZE
+#define STR_FIXLEN32	LIBNDR_FLAG_STR_FIXLEN32
+#define STR_FIXLEN15	LIBNDR_FLAG_STR_FIXLEN15
+#define STR_CONFORMANT  LIBNDR_FLAG_STR_CONFORMANT
+#define STR_CHARLEN	LIBNDR_FLAG_STR_CHARLEN
+#define STR_UTF8	LIBNDR_FLAG_STR_UTF8
+#define STR_LARGE_SIZE	LIBNDR_FLAG_STR_LARGE_SIZE
+
+/*
+  a UCS2 string prefixed with [size], 32 bits
+*/
+#define lstring		[flag(STR_SIZE4)] string
+
+/*
+  a null terminated UCS2 string
+*/
+#define nstring		[flag(STR_NULLTERM)] string
+
+/*
+  fixed length 32 character UCS-2 string
+*/
+#define string32	[flag(STR_FIXLEN32)] string
+
+/*
+  fixed length 16 character ascii string
+*/
+#define astring15       [flag(STR_ASCII|STR_FIXLEN15)] string
+
+/*
+  an ascii string prefixed with [offset] [length], both 32 bits
+  null terminated
+*/
+#define ascstr2		[flag(STR_ASCII|STR_LEN4)] string
+
+/*
+  an ascii string prefixed with [size], 32 bits
+*/
+#define asclstr		[flag(STR_ASCII|STR_SIZE4)] string
+
+/*
+  an ascii string prefixed with [size], 16 bits
+  null terminated
+*/
+#define ascstr3		[flag(STR_ASCII|STR_SIZE2)] string
+
+/*
+  an ascii string prefixed with [size] [offset] [length], all 32 bits
+  not null terminated
+*/
+#define ascstr_noterm	[flag(STR_NOTERM|STR_ASCII|STR_SIZE4|STR_LEN4)] string
+
+/*
+  a null terminated ascii string
+*/
+#define astring		[flag(STR_ASCII|STR_NULLTERM)] string
+
+/*
+  a null terminated UTF8 string
+*/
+#define utf8string	[flag(STR_UTF8|STR_NULLTERM)] string
+
+/*
+  a null terminated UCS2 string
+*/
+#define nstring_array	[flag(STR_NULLTERM)] string_array
+
+#define NDR_NOALIGN       LIBNDR_FLAG_NOALIGN
+#define NDR_REMAINING     LIBNDR_FLAG_REMAINING
+#define NDR_ALIGN2        LIBNDR_FLAG_ALIGN2
+#define NDR_ALIGN4        LIBNDR_FLAG_ALIGN4
+#define NDR_ALIGN8        LIBNDR_FLAG_ALIGN8
+
+/* this flag is used to force a section of IDL as little endian. It is
+   needed for the epmapper IDL, which is defined as always being LE */
+#define NDR_LITTLE_ENDIAN LIBNDR_FLAG_LITTLE_ENDIAN
+#define NDR_BIG_ENDIAN LIBNDR_FLAG_BIGENDIAN
+
+
+/*
+  these are used by the epmapper and mgmt interfaces
+*/
+#define error_status_t uint32
+#define boolean32 uint32
+#define unsigned32 uint32
+
+/*
+  this is used to control formatting of uint8 arrays
+*/
+#define NDR_PAHEX LIBNDR_PRINT_ARRAY_HEX
+
+#define bool8 uint8

Added: trunk/openchange/install-sh
===================================================================
--- trunk/openchange/install-sh	                        (rev 0)
+++ trunk/openchange/install-sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0

Added: trunk/openchange/libmapi/Doxyfile.in
===================================================================
--- trunk/openchange/libmapi/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/libmapi/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1278 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MAPI Client Libraries
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = libmapi doc/doxygen
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.h *.c *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =  *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c *_private.h
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = doc/examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed \
+		         -e '20,40s/.*\<libmapi\/proto_private.h\>//'	\
+			 -e '20,40s/.*\<gen_ndr\/ndr_exchange.h\>//'		\
+			 -e '20,40s/.*\<gen_ndr\/ndr_exchange_c.h\>//'	\
+			 -e '20,40s/.*\<gen_ndr\/ndr_misc.h\>//'		\
+			 -e '20,40s/.*\<gen_ndr\/ndr_property.h\>//'		\
+			 -e '20,40s/.*\<param.h\>//'				\
+			 -e '20,40s/.*\<core\/error.h\>//'			\
+			 -e '20,40s/.*\<credentials.h\>//'			\
+			 -e '20,40s/.*\<ldb.h\>//'				\
+			 -e '20,40s/.*\<ldb_errors.h\>//'			\
+			 -e '20,40s/.*\<libmapi\/dlinklist.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapi_nameid.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapicode.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapidump.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapitags.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapi_nameid_private.h\>//'	\
+			 -e '20,40s/.*\<libmapi\/defs_private.h\>//'		\
+			 -e '20,40s/.*\<libgen.h\>//'			\
+			 -e '20,40s/.*\<time.h\>//'				\
+			 -e '20,40s/.*\<sys\/*\>//'				\
+                         -e '20,40s/_PUBLIC_//'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/libmapi
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/libmapi/FXICS.c
===================================================================
--- trunk/openchange/libmapi/FXICS.c	                        (rev 0)
+++ trunk/openchange/libmapi/FXICS.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,114 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file FXICS.c
+
+   \brief Incremental Change Synchronization operations
+ */
+
+
+/**
+   \details Reserves a range of IDs to be used by a local replica
+
+   \param obj_store pointer on the store MAPI object
+   \param IdCount ID range length to reserve
+   \param ReplGuid pointer to the GUID structure returned by the
+   server
+   \param GlobalCount byte array that specifies the first allocated
+   field
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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 of the function parameter is
+     invalid
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+ */
+_PUBLIC_ enum MAPISTATUS GetLocalReplicaIds(mapi_object_t *obj_store, 
+					    uint32_t IdCount,
+					    struct GUID *ReplGuid,
+					    uint8_t GlobalCount[6])
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetLocalReplicaIds_req	request;
+	struct GetLocalReplicaIds_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ReplGuid, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetLocalReplicaIds");
+	size = 0;
+
+	/* Fill the GetLocalReplicaIds operation */
+	request.IdCount = IdCount;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ structure */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetLocalReplicaIds;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetLocalReplicaIds = request;
+	size += 5;
+
+	/* 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 = (uint16_t)size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* Retrieve output parameters */
+	reply = &mapi_response->mapi_repl->u.mapi_GetLocalReplicaIds;
+	*ReplGuid = reply->ReplGuid;
+	memcpy(GlobalCount, reply->GlobalCount, 6);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IABContainer.c
===================================================================
--- trunk/openchange/libmapi/IABContainer.c	                        (rev 0)
+++ trunk/openchange/libmapi/IABContainer.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,280 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+
+
+/**
+   \file IABContainer.c
+
+   \brief Provides access to address book containers -- Used to
+   perform name resolution
+*/
+
+
+/**
+   \details Resolve user names against the Windows Address Book Provider
+
+   \param session pointer to the MAPI session context
+   \param usernames list of user names to resolve
+   \param rowset resulting list of user details
+   \param props resulting list of resolved names
+   \param flaglist resulting list of resolution status (see below)
+   \param flags if set to MAPI_UNICODE then UNICODE MAPITAGS can be
+   used, otherwise only UTF8 encoded fields may be returned.
+
+   Possible flaglist values are:
+   -# MAPI_UNRESOLVED: could not be resolved
+   -# MAPI_AMBIGUOUS: resolution match more than one entry
+   -# MAPI_RESOLVED: resolution matched a single entry
+ 
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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_SESSION_LIMIT: No session has been opened on the provider
+   -# MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   -# MAPI_E_NOT_FOUND: No suitable profile database was found in the
+     path pointed by profiledb
+   -# MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+   
+   \sa MAPILogonProvider, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS ResolveNames(struct mapi_session *session,
+				      const char **usernames, 
+				      struct SPropTagArray *props, 
+				      struct SRowSet **rowset, 
+				      struct SPropTagArray **flaglist, 
+				      uint32_t flags)
+{
+	struct nspi_context	*nspi;
+	enum MAPISTATUS		retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!rowset, MAPI_E_INVALID_PARAMETER, NULL);
+
+	nspi = (struct nspi_context *)session->nspi->ctx;
+
+	switch (flags) {
+	case MAPI_UNICODE:
+		retval = nspi_ResolveNamesW(nspi, usernames, props, &rowset, &flaglist);
+		break;
+	default:
+		retval = nspi_ResolveNames(nspi, usernames, props, &rowset, &flaglist);
+		break;
+	}
+
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the global address list
+   
+   \param session pointer to the MAPI session context
+   \param SPropTagArray pointer on an array of MAPI properties we want
+   to fetch
+   \param SRowSet pointer on the rows 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
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_SESSION_LIMIT: No session has been opened on the provider
+   -# MAPI_E_INVALID_PARAMETER: if a function parameter is invalid
+   -# MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MapiLogonEx, MapiLogonProvider
+ */
+_PUBLIC_ enum MAPISTATUS GetGALTable(struct mapi_session *session,
+				     struct SPropTagArray *SPropTagArray, 
+				     struct SRowSet **SRowSet, 
+				     uint32_t count, 
+				     uint8_t ulFlags)
+{
+	struct nspi_context	*nspi;
+	struct SRowSet		*srowset;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	nspi = (struct nspi_context *)session->nspi->ctx;
+
+	if (ulFlags == TABLE_START) {
+		nspi->pStat->CurrentRec = 0;
+		nspi->pStat->Delta = 0;
+		nspi->pStat->NumPos = 0;
+		nspi->pStat->TotalRecs = 0xffffffff;
+	}
+
+	srowset = talloc_zero(session, struct SRowSet);
+	retval = nspi_QueryRows(nspi, SPropTagArray, NULL, count, &srowset);
+	*SRowSet = srowset;
+
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve Address Book information for a given recipient
+
+   \param session pointer to the MAPI session context
+   \param username pointer to the username to retrieve information from
+   \param pPropTags pointer to the property tags array to lookup
+   \param ppRowSet pointer on pointer to the results
+
+   Note that if pPropTags is NULL, then GetABNameInfo will fetch
+   the following default property tags:
+   -# PR_ADDRTYPE_UNICODE
+   -# PR_EMAIL_ADDRESS_UNICODE
+   -# PR_DISPLAY_NAME_UNICODE
+   -# PR_OBJECT_TYPE
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error. 
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   -# MAPI_E_NOT_INITIALIZED if MAPI subsystem is not initialized
+   -# MAPI_E_SESSION_LIMIT if the NSPI session is unavailable
+   -# MAPI_E_INVALID_PARAMETER if a function parameter is invalid
+   -# MAPI_E_NOT_FOUND if the username to lookup doesn't match any
+      records
+
+   \sa nspi_DNToMId, nspi_GetProps
+ */
+_PUBLIC_ enum MAPISTATUS GetABRecipientInfo(struct mapi_session *session,
+				       const char *username,
+				       struct SPropTagArray *pPropTags,
+				       struct SRowSet **ppRowSet)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct nspi_context	*nspi_ctx;
+	struct SRowSet		*SRowSet;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropTagArray	*pMId = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct StringsArray_r	pNames;
+	const char		*usernames[2];
+	char			*email = NULL;
+	bool			allocated = false;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!ppRowSet, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+
+	nspi_ctx = (struct nspi_context *)session->nspi->ctx;
+	mem_ctx = nspi_ctx->mem_ctx;
+
+	/* Step 1. Resolve the username */
+	usernames[0] = username;
+	usernames[1] = NULL;
+
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xc,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME_UNICODE,
+					  PR_ADDRTYPE_UNICODE,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_EMAIL_ADDRESS_UNICODE,
+					  PR_SEND_INTERNET_ENCODING,
+					  PR_SEND_RICH_INFO,
+					  PR_SEARCH_KEY,
+					  PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE);
+	retval = ResolveNames(session, usernames, SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+
+	if (flaglist->aulPropTag[0] != MAPI_RESOLVED) {
+		MAPIFreeBuffer(SRowSet);
+		return MAPI_E_NOT_FOUND;
+	}
+
+	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));
+	MAPIFreeBuffer(SRowSet);
+
+	/* Step 2. Map recipient DN to MId */
+	pNames.Count = 0x1;
+	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);
+	MAPIFreeBuffer((char *)pNames.Strings[0]);
+	MAPIFreeBuffer((char **)pNames.Strings);
+	OPENCHANGE_RETVAL_IF(retval, retval, pMId);
+
+	/* Step 3. Get recipient's properties */
+	if (!pPropTags) {
+		allocated = true;
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x4,
+						  PR_ADDRTYPE_UNICODE,
+						  PR_EMAIL_ADDRESS_UNICODE,
+						  PR_DISPLAY_NAME_UNICODE,
+						  PR_OBJECT_TYPE);
+	} else {
+		SPropTagArray = pPropTags;
+	}
+
+	SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = nspi_GetProps(nspi_ctx, SPropTagArray, pMId, &SRowSet);
+	if (allocated == true) {
+		MAPIFreeBuffer(SPropTagArray);
+	}
+	MAPIFreeBuffer(pMId);
+	OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+
+	*ppRowSet = SRowSet;
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMAPIContainer.c
===================================================================
--- trunk/openchange/libmapi/IMAPIContainer.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPIContainer.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,745 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+
+
+/**
+   \file IMAPIContainer.c
+
+   \brief Containers and tables related operations
+*/
+
+
+/**
+   \details Returns a pointer to a container's table object
+
+   This function takes a pointer to a container object and returns a
+   pointer to its associated contents
+
+   \param obj_container the object to get the contents of
+   \param obj_table the resulting table containing the container's
+   contents.
+   \param TableFlags flags controlling the type of table
+   \param RowCount the number of rows in the hierarchy table
+
+   TableFlags possible values:
+
+   - TableFlags_Depth (0x4): Fills the hierarchy table with containers
+   from all levels. If this flag is not set, the hierarchy table
+   contains only the container's immediate child containers.
+
+   - TableFlags_DeferredErrors (0x8): The call response can return immediately,
+   possibly before the call execution is complete and in this case the
+   ReturnValue as well the RowCount fields in the return buffer might
+   not be accurate.  Only retval reporting failure can be considered
+   valid in this case.
+
+   - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table
+   object.
+
+   - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft
+   deleted folders.
+
+   - TableFlags_UseUnicode (0x40): Requests that the columns that contain string
+   data be returned in Unicode format.
+
+   - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated
+   by this client’s actions on this Table object.
+
+   Developers can either set RowCount to a valid pointer on uint32_t
+   or set it to NULL. In this last case, GetHierarchyTable won't
+   return any value to the calling function.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, GetHierarchyTable, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetContentsTable(mapi_object_t *obj_container, mapi_object_t *obj_table,
+					  uint8_t TableFlags, uint32_t *RowCount)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetContentsTable_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_container);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetContentsTable");
+	size = 0;
+
+	/* Fill the GetContentsTable operation */
+	request.handle_idx = 0x1;
+	request.TableFlags = TableFlags;
+	size += 2;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetContentsTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetContentsTable = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_table, session);
+	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+
+	/* Retrieve RowCount if a valid pointer was set */
+	if (RowCount) {
+		*RowCount = mapi_response->mapi_repl->u.mapi_GetContentsTable.RowCount;
+	}
+	
+	/* new table */
+	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a pointer to a container's table object
+
+   This function takes a pointer to a container object and returns a
+   pointer to its associated hierarchy table
+
+   \param obj_container the object to get the contents of
+   \param obj_table the resulting table containing the container's
+   hierarchy
+   \param TableFlags flags controlling the type of table
+   \param RowCount the number of rows in the hierarchy table
+
+   TableFlags possible values:
+
+   - TableFlags_Depth (0x4): Fills the hierarchy table with containers
+   from all levels. If this flag is not set, the hierarchy table
+   contains only the container's immediate child containers.
+
+   - TableFlags_DeferredErrors (0x8): The call response can return immediately,
+   possibly before the call execution is complete and in this case the
+   ReturnValue as well the RowCount fields in the return buffer might
+   not be accurate.  Only retval reporting failure can be considered
+   valid in this case.
+
+   - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table
+   object.
+
+   - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft
+   deleted folders.
+
+   - TableFlags_UseUnicode (0x40): Requests that the columns that contain string
+   data be returned in Unicode format.
+
+   - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated
+   by this client’s actions on this Table object.
+
+   Developers can either set RowCount to a valid pointer on uint32_t
+   or set it to NULL. In this last case, GetHierarchyTable won't
+   return any value to the calling function.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, GetContentsTable, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetHierarchyTable(mapi_object_t *obj_container, mapi_object_t *obj_table,
+					   uint8_t TableFlags, uint32_t *RowCount)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetHierarchyTable_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_container);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetHierarchyTable");
+	size = 0;
+
+	/* Fill the GetHierarchyTable operation */
+	request.handle_idx = 0x1;
+	request.TableFlags = TableFlags;
+	size += 2;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetHierarchyTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetHierarchyTable = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_table, session);
+	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+	
+	/* Retrieve RowCount if a valid pointer was set */
+	if (RowCount) {
+		*RowCount = mapi_response->mapi_repl->u.mapi_GetHierarchyTable.RowCount;
+	}
+
+	/* new table */
+	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a pointer to the permission's table object.  
+
+   This function takes a pointer to a container object and returns a
+   pointer to its associated permission table
+
+   \param obj_container the object to get the contents of
+   \param obj_table the resulting table containing the container's
+   permissions
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa ModifyTable
+ */
+_PUBLIC_ enum MAPISTATUS GetTable(mapi_object_t *obj_container, mapi_object_t *obj_table)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct GetTable_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_container);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetTable");
+	size = 0;
+
+	/* Fill the GetTable operation */
+	request.handle_idx = 0x1;
+	request.padding = 0x0;
+	size += 2;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx= 0;
+	mapi_req->u.mapi_GetTable = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_table, session);
+	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+
+	/* new table */
+	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Gets the rules table of a folder
+
+   \param obj_folder the folder we want to retrieve the rules table
+   from
+   \param obj_table the rules table
+   \param TableFlags bitmask associated to the rules table
+
+   Possible values for TableFlags:
+
+   - RulesTableFlags_Unicode (0x40): Set if the client is requesting
+     that string values in the table to be returned as Unicode
+     strings.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+    \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_CALL_FAILED: A network problem was encountered during the
+     transaction  
+ */
+_PUBLIC_ enum MAPISTATUS GetRulesTable(mapi_object_t *obj_folder, 
+				       mapi_object_t *obj_table,
+				       uint8_t TableFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetRulesTable_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetRulesTable");
+	size = 0;
+
+	/* Fill the GetRulesTable operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.TableFlags = TableFlags;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetRulesTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetRulesTable = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_table, session);
+	mapi_object_set_handle(obj_table, mapi_response->handles[1]);
+
+	/* new table */
+	mapi_object_table_init((TALLOC_CTX *)session, obj_table);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+
+/**
+   \details Modify the entries of a permission table
+
+   This function takes a pointer to a table object, a list of entries
+   to modify and alter the permission table of its associated
+   container. This function can be used to add, modify or remove
+   permissions.
+
+   \param obj_table the table containing the container's permissions
+   \param rowList the list of table entries to modify
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetTable, AddUserPermission, ModifyUserPermission,
+   RemoveUserPermission
+ */
+_PUBLIC_ enum MAPISTATUS ModifyTable(mapi_object_t *obj_table, struct mapi_SRowList *rowList)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct ModifyTable_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		i, j;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!rowList, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ModifyTable");
+	size = 0;
+
+	/* Fill the GetTable operation */
+	request.rowList = *rowList;
+	request.rowList.padding = 0;
+	size += sizeof (uint8_t) + sizeof (uint16_t);
+
+	for (i = 0; i < rowList->cEntries; i++) {
+		size += sizeof (uint8_t);
+			for (j = 0; j < rowList->aEntries[i].lpProps.cValues; j++) {
+				size += get_mapi_property_size(&(rowList->aEntries[i].lpProps.lpProps[j]));
+				size += sizeof (uint32_t);
+			}
+	size += sizeof (uint16_t);
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ModifyTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx= 0;
+	mapi_req->u.mapi_ModifyTable = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Etablishes search criteria for the container
+
+   \param obj_container the object we apply search criteria on
+   \param res pointer to a mapi_SRestriction structure defining the
+   search criteria
+   \param SearchFlags bitmask of flags that controls how the search
+   is performed
+   \param lpContainerList pointer to a list of identifiers
+   representing containers to be included in the search
+
+   SearchFlags can take the following values:
+
+   - BACKGROUND_SEARCH: Search run at normal priority relative to
+     other searches. This flag is mutually exclusive with the
+     FOREGROUND_SEARCH one.
+   - FOREGROUND_SEARCH: Search run at high priority relative to other
+     searches. This flag is mutually exclusive with the
+     BACKGROUND_SEARCH one.
+   - RECURSIVE_SEARCH: The search should include the containers
+     specified in the lpContainerList parameter and all of their child
+     container. This flag is mutually exclusive with the
+     SHALLOW_SEARCH one.
+   - RESTART_SEARCH: The search should be initiated, if this is the
+     first call to SetSearchCriteria, or restarted, if the search is
+     inactive. This flag is mutually exclusive with the STOP_SEARCH
+     flag.
+   - SHALLOW_SEARCH: The search should only look in the containers
+     specified in the lpContainerList parameter for matching
+     entries. This flag is mutually exclusive with the
+     RECURSIVE_SEARCH one.
+   - STOP_SEARCH: The search should be aborted. This flag is mutually
+     exclusive with the RESTART_SEARCH one.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+     
+   \sa GetSearchCriteria
+ */
+_PUBLIC_ enum MAPISTATUS SetSearchCriteria(mapi_object_t *obj_container, 
+					   struct mapi_SRestriction *res, 
+					   uint32_t SearchFlags,
+					   mapi_id_array_t *lpContainerList)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetSearchCriteria_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_container);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetSearchCriteria");
+	size = 0;
+
+	/* Fill the SetSearchCriteria operation */
+	request.res = *res;
+	size += get_mapi_SRestriction_size(res);
+	if (lpContainerList != NULL) {
+		request.FolderIdCount = lpContainerList->count;
+		size += sizeof (uint16_t);
+
+		mapi_id_array_get(mem_ctx, lpContainerList, &request.FolderIds);
+		size += lpContainerList->count * sizeof (uint64_t);
+	} else {
+		request.FolderIdCount = 0;
+		size += sizeof (uint16_t);
+		request.FolderIds = NULL;
+	}
+	request.SearchFlags = SearchFlags;
+	size += sizeof (uint32_t);
+
+	/* add subcontext size */
+	size += sizeof (uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetSearchCriteria;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetSearchCriteria = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Obtains the search criteria for a container
+
+   \param obj_container the object we retrieve search criteria from
+   \param res pointer to a mapi_SRestriction structure defining the
+   search criteria 
+   \param SearchFlags bitmask of flags that controls how the search
+   is performed
+   \param FolderIdCount number of FolderIds entries
+   \param FolderIds pointer to a list of identifiers
+   representing containers included in the search
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+     
+   \sa SetSearchCriteria
+ */
+_PUBLIC_ enum MAPISTATUS GetSearchCriteria(mapi_object_t *obj_container,
+					   struct mapi_SRestriction *res,
+					   uint32_t *SearchFlags,
+					   uint16_t *FolderIdCount,
+					   uint64_t **FolderIds)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetSearchCriteria_req	request;
+	struct GetSearchCriteria_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SearchFlags, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!FolderIdCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!FolderIds, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_container);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetSearchCriteria");
+	size = 0;
+
+	/* Fill the GetSearchCriteria operation */
+	request.UseUnicode = 0x1;
+	request.IncludeRestriction = 0x1;
+	request.IncludeFolders = 0x1;
+	size += 3 * sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetSearchCriteria;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetSearchCriteria = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_GetSearchCriteria;
+
+	res = &reply->res;
+	*FolderIdCount = reply->FolderIdCount;
+	*FolderIds = talloc_steal((TALLOC_CTX *)session, reply->FolderIds);
+	*SearchFlags = reply->SearchFlags;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMAPIFolder.c
===================================================================
--- trunk/openchange/libmapi/IMAPIFolder.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPIFolder.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1091 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IMAPIFolder.c
+
+   \brief Folder related functions
+ */
+
+
+/**
+   \details The function creates a message in the specified folder,
+   and returns a pointer on this message.
+
+   \param obj_folder the folder to create the message in.
+   \param obj_message pointer to the newly created message.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, DeleteMessage, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS CreateMessage(mapi_object_t *obj_folder, mapi_object_t *obj_message)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct CreateMessage_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateMessage");
+	size = 0;
+
+	/* Fill the OpenFolder operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+	request.CodePageId = 0xfff;
+	size += sizeof (uint16_t);
+	request.FolderId = mapi_object_get_id(obj_folder);
+	size += sizeof (uint64_t);
+	request.AssociatedFlag = 0;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CreateMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CreateMessage = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof(mapi_handle_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, mapi_handle_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_message, session);
+	mapi_object_set_handle(obj_message, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Delete one or more messages
+
+   This function deletes one or more messages based on their ids from
+   a specified folder.
+
+   \param obj_folder the folder to delete messages from
+   \param id_messages the list of ids
+   \param cn_messages the number of messages in the id list.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, CreateMessage, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS DeleteMessage(mapi_object_t *obj_folder, mapi_id_t *id_messages,
+				       uint32_t cn_messages)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct DeleteMessages_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeleteMessages");
+	size = 0;
+
+	/* Fill the DeleteMessages operation */
+	request.WantAsynchronous = 0x0;
+	size += sizeof (uint8_t);
+	request.NotifyNonRead = 0x1;
+	size += sizeof(uint8_t);
+	request.cn_ids = (uint16_t)cn_messages;
+	size += sizeof(uint16_t);
+	request.message_ids = id_messages;
+	size += request.cn_ids * sizeof(mapi_id_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_DeleteMessages;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_DeleteMessages = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Obtain the status associated with a message
+
+   This function obtains the status associated with a message in the
+   given folder.
+
+   \param obj_folder the folder where the message is located
+   \param msgid the message ID
+   \param ulStatus the message status
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+ */
+_PUBLIC_ enum MAPISTATUS GetMessageStatus(mapi_object_t *obj_folder, 
+					  mapi_id_t msgid, 
+					  uint32_t *ulStatus)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetMessageStatus_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!msgid, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetMessageStatus");
+	size = 0;
+
+	/* Fill the GetMessageStatus operation */
+	request.msgid = msgid;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetMessageStatus;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetMessageStatus = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*ulStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the status associated with a message
+
+   This function sets the status associated with a message in the
+   given folder.
+
+   \param obj_folder the folder where the message is located
+   \param msgid the message ID
+   \param ulNewStatus the new status to be assigned
+   \param ulNewStatusMask bitmask of flags hat is applied to the new
+   status indicating the flags to be set
+   \param ulOldStatus pointer on the previous status of the message
+
+   ulNewStatusMask possible values:
+   - MSGSTATUS_DELMARKED: the message is marked for deletion
+   - MSGSTATUS_HIDDEN: the message is not to be displayed
+   - MSGSTATUS_HIGHLIGHTED: the message is to be displayed highlighted
+   - MSGSTATUS_REMOTE_DELETE: the message has been marked for deletion
+     on the remote message store without downloading to the local
+     client.
+   - MSGSTATUS_REMOTE_DOWNLOAD: the message has been marked for
+     downloading from the remote message store to the local client.
+   - MSGSTATUS_TAGGED: The message has been tagged for a
+     client-defined purpose.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+ */
+_PUBLIC_ enum MAPISTATUS SetMessageStatus(mapi_object_t *obj_folder,
+					  mapi_id_t msgid,
+					  uint32_t ulNewStatus,
+					  uint32_t ulNewStatusMask,
+					  uint32_t *ulOldStatus)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetMessageStatus_req    	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!msgid, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetMessageStatus");
+	size = 0;
+
+	/* Fill the SetMessageStatus operation */
+	request.msgid = msgid;
+	size += sizeof (uint64_t);
+
+	request.ulNewStatus = ulNewStatus;
+	size += sizeof (uint32_t);
+
+	request.ulNewStatusMask = ulNewStatusMask;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetMessageStatus;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetMessageStatus = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*ulOldStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Copy or Move a message from a folder to another
+
+   \param obj_src The source folder
+   \param obj_dst The destination folder
+   \param message_id pointer to container object for message ids.
+   \param WantCopy boolean value, defines whether the operation is a
+   copy or a move
+
+   Possible values for WantCopy:
+   -# 0: Move
+   -# 1: Copy
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS MoveCopyMessages(mapi_object_t *obj_src,
+					  mapi_object_t *obj_dst,
+					  mapi_id_array_t *message_id,
+					  bool WantCopy)
+{
+	NTSTATUS			status;
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct MoveCopyMessages_req	request;
+	struct mapi_session		*session[2];
+	uint32_t			size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+	session[0] = mapi_object_get_session(obj_src);
+	session[1] = mapi_object_get_session(obj_dst);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "MoveCopyMessages");
+	size = 0;
+
+	/* Fill the CopyMessage operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.count = message_id->count;
+	size += sizeof (uint16_t);
+
+	retval = mapi_id_array_get(mem_ctx, message_id, &(request.message_id));
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	size += request.count * sizeof (mapi_id_t);
+
+	request.WantAsynchronous = 0;
+	size += sizeof (uint8_t);
+
+	request.WantCopy = WantCopy;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_MoveCopyMessages;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_MoveCopyMessages = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Create a folder
+
+   The function creates a folder (defined with its name, comment and type)
+   within a specified folder.
+
+   \param obj_parent the folder to create the new folder in
+   \param ulFolderType the type of the folder
+   \param name the name of the new folder
+   \param comment the comment associated with the new folder
+   \param ulFlags flags associated with folder creation
+   \param obj_child pointer to the newly created folder
+
+   ulFlags possible values:
+   - MAPI_UNICODE: use UNICODE folder name and comment
+   - OPEN_IF_EXISTS: open the folder if it already exists
+
+   ulFolderType possible values:
+   - FOLDER_GENERIC
+   - FOLDER_SEARCH
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, DeleteFolder, EmptyFolder, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS CreateFolder(mapi_object_t *obj_parent, 
+				      uint8_t ulFolderType,
+				      const char *name,
+				      const char *comment, 
+				      uint32_t ulFlags,
+				      mapi_object_t *obj_child)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct CreateFolder_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!name, MAPI_E_NOT_INITIALIZED, NULL);
+	session = mapi_object_get_session(obj_parent);
+	OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Sanitify check on the folder type */
+	OPENCHANGE_RETVAL_IF((ulFolderType != FOLDER_GENERIC && 
+			ulFolderType != FOLDER_SEARCH),
+		       MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateFolder");
+	size = 0;
+
+	/* Fill the CreateFolder operation */
+	request.handle_idx = 0x1;
+	size+= sizeof(uint8_t);
+	switch (ulFlags & 0xFFFF0000) {
+	case MAPI_UNICODE:
+		request.ulType = MAPI_FOLDER_UNICODE;
+		break;
+	default:
+		request.ulType = MAPI_FOLDER_ANSI;
+		break;
+	}
+	request.ulFolderType = ulFolderType;
+	size += sizeof(uint16_t);
+	request.ulFlags = ulFlags & 0xFFFF;
+	size += sizeof(uint16_t);
+
+	switch (request.ulType) {
+	case MAPI_FOLDER_ANSI:
+		request.FolderName.lpszA = name;
+		size += strlen(name) + 1;
+		break;
+	case MAPI_FOLDER_UNICODE:
+		request.FolderName.lpszW = name;
+		size += strlen(name) * 2 + 2;
+		break;
+	}
+
+	if (comment) {
+		switch(request.ulType) {
+		case MAPI_FOLDER_ANSI:
+			request.FolderComment.lpszA = comment;
+			size += strlen(comment) + 1;
+			break;
+		case MAPI_FOLDER_UNICODE:
+			request.FolderComment.lpszW = comment;
+			size += strlen(comment) * 2 + 2;
+			break;
+		}
+	} else {
+		switch(request.ulType) {
+		case MAPI_FOLDER_ANSI:
+			request.FolderComment.lpszA = "";
+			size += 1;
+			break;
+		case MAPI_FOLDER_UNICODE:
+			request.FolderComment.lpszW = "";
+			size += 2;
+			break;
+		}
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CreateFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CreateFolder = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + (2 * sizeof(uint32_t));
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session, handle and id */
+	mapi_object_init(obj_child);
+	mapi_object_set_session(obj_child, session);
+	mapi_object_set_handle(obj_child, mapi_response->handles[1]);
+	mapi_object_set_id(obj_child, mapi_response->mapi_repl->u.mapi_CreateFolder.folder_id);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Empty the contents of a folder
+
+   This function empties (clears) the contents of a specified folder.
+
+   \param obj_folder the folder to empty
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, CreateFolder, DeleteFolder, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS EmptyFolder(mapi_object_t *obj_folder)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct EmptyFolder_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "EmptyFolder");
+	size = 0;
+
+	/* Fill the EmptyFolder operation */
+	request.WantAsynchronous = 0x0;
+	size += sizeof (uint8_t);
+
+	request.WantDeleteAssociated = 0x0;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_EmptyFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_EmptyFolder = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Delete a folder
+
+   The function deletes a specified folder.
+
+   \param obj_parent the folder containing the folder to be deleted
+   \param FolderId the ID of the folder to delete
+   \param DeleteFolderFlags control DeleteFolder operation behavior
+   \param PartialCompletion pointer on a boolean value which specify
+   whether the operation was partially completed or not
+
+   Possible values for DeleteFolderFlags are:
+   -# DEL_MESSAGES Delete all the messages in the folder
+   -# DEL_FOLDERS Delete the subfolder and all of its subfolders
+   -# DELETE_HARD_DELETE Hard delete the folder
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, CreateFolder, EmptyFolder, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS DeleteFolder(mapi_object_t *obj_parent, 
+				      mapi_id_t FolderId,
+				      uint8_t DeleteFolderFlags,
+				      bool *PartialCompletion)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct DeleteFolder_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_parent);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF((!(DeleteFolderFlags & 0x1)) &&
+			     (!(DeleteFolderFlags & 0x4)) &&
+			     (!(DeleteFolderFlags & 0x10)), 
+			     MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeleteFolder");
+	size = 0;
+
+	/* Fill the DeleteFolder operation */
+	request.DeleteFolderFlags = DeleteFolderFlags;
+	size += sizeof (uint8_t);
+	request.FolderId = FolderId;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_DeleteFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_DeleteFolder = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (PartialCompletion) {
+		*PartialCompletion = mapi_response->mapi_repl->u.mapi_DeleteFolder.PartialCompletion;
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Moves a folder
+
+   \param obj_folder the folder to move
+   \param obj_src source object where the folder to move is stored
+   \param obj_dst destination object where the folder will be moved
+   \param NewFolderName the new folder name in the destination folder
+   \param UseUnicode whether the folder name is unicode encoded or not
+
+    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, CopyFolder
+ */
+_PUBLIC_ enum MAPISTATUS MoveFolder(mapi_object_t *obj_folder,
+				    mapi_object_t *obj_src, 
+				    mapi_object_t *obj_dst,
+				    char *NewFolderName,
+				    bool UseUnicode)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct MoveFolder_req	request;
+	struct mapi_session	*session[3];
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!NewFolderName, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_folder);
+	session[1] = mapi_object_get_session(obj_src);
+	session[2] = mapi_object_get_session(obj_dst);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[2], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "MoveFolder");
+	size = 0;
+
+	/* Fill the MoveFolder operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.WantAsynchronous = 0;
+	size += sizeof (uint8_t);
+
+	request.UseUnicode = UseUnicode;
+	size += sizeof (uint8_t);
+
+	request.FolderId = mapi_object_get_id(obj_folder);
+	size += sizeof (uint64_t);
+
+	if (!request.UseUnicode) {
+		request.NewFolderName.lpszA = NewFolderName;
+		size += strlen(NewFolderName) + 1;
+	} else {
+		request.NewFolderName.lpszW = NewFolderName;
+		size += strlen(NewFolderName) * 2 + 2;
+	}
+
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_MoveFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_MoveFolder = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Copy a folder
+
+   \param obj_folder the folder to copy
+   \param obj_src source object where the folder to copy is stored
+   \param obj_dst destination object where the folder will be copied
+   \param NewFolderName the new folder name in the destination folder
+   \param UseUnicode whether the folder name is unicode encoded or not
+   \param WantRecursive whether we should copy folder's subdirectories
+   or not
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developer 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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenFolder, MoveFolder
+ */
+_PUBLIC_ enum MAPISTATUS CopyFolder(mapi_object_t *obj_folder,
+				    mapi_object_t *obj_src,
+				    mapi_object_t *obj_dst,
+				    char *NewFolderName,
+				    bool UseUnicode,
+				    bool WantRecursive)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct CopyFolder_req	request;
+	struct mapi_session	*session[3];
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!NewFolderName, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_folder);
+	session[1] = mapi_object_get_session(obj_src);
+	session[2] = mapi_object_get_session(obj_dst);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[2], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CopyFolder");
+
+	size = 0;
+
+	/* Fill the CopyFolder operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+	
+	request.WantAsynchronous = 0x0;
+	size += sizeof (uint8_t);
+
+	request.WantRecursive = WantRecursive;
+	size += sizeof (uint8_t);
+
+	request.UseUnicode = UseUnicode;
+	size += sizeof (uint8_t);
+
+	request.FolderId = mapi_object_get_id(obj_folder);
+	size += sizeof (uint64_t);
+
+	if (!request.UseUnicode) {
+		request.NewFolderName.lpszA = NewFolderName;
+		size += strlen(NewFolderName) + 1;
+	} else {
+		request.NewFolderName.lpszW = NewFolderName;
+		size += strlen(NewFolderName) * 2 + 2;
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CopyFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CopyFolder = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the Read Flags on one or more messages
+
+   \param obj_folder the folder containing the messages to change
+   \param ReadFlags a bitmap of flags controlling the changes to
+   PR_PROPERTY_FLAGS
+   \param MessageIdCount the number of messages in the MessageIds array
+   \param MessageIds an array of message ids to set Read flags for
+
+   Note that the obj_folder argument is the object corresponding to the
+   folder containing the messages (e.g. the result of CreateFolder() or
+   OpenFolder(). It is \em not the content table of that folder (unlike
+   SetMessageReadFlag().)
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetMessageReadFlags for a slightly different version, working on
+   a single message
+*/
+_PUBLIC_ enum MAPISTATUS SetReadFlags(mapi_object_t *obj_folder,
+				      uint8_t ReadFlags, 
+				      uint16_t MessageIdCount,
+				      uint64_t *MessageIds)
+{
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size;
+	struct SetReadFlags_req	request;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_request	*mapi_request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	struct mapi_response	*mapi_response;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetReadFlags");
+
+	size = 0;
+
+	/* Fill the SetReadFlags operation */
+	request.WantAsynchronous = 0;
+	size += sizeof(uint8_t);
+	request.ReadFlags = ReadFlags;
+	size += sizeof(uint8_t);
+	request.MessageIdCount = MessageIdCount;
+	size += sizeof(uint16_t);
+	request.MessageIds = MessageIds;
+	size += sizeof(uint64_t) * MessageIdCount;
+
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetReadFlags;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetReadFlags = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* TODO: parse response */
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+

Added: trunk/openchange/libmapi/IMAPIProp.c
===================================================================
--- trunk/openchange/libmapi/IMAPIProp.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPIProp.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1209 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Brad Hards 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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IMAPIProp.c
+
+   \brief Properties and named properties operations.
+ */
+
+
+/**
+   \details Returns values of one or more properties for an object
+ 
+   The function takes a pointer on the object obj, a MAPITAGS array
+   specified in mapitags, and the count of properties.  The function
+   returns associated values within the SPropValue values pointer.
+
+   The array of MAPI property tags can be filled with both known and
+   named properties.
+
+   \param obj the object to get properties on
+   \param SPropTagArray an array of MAPI property tags
+   \param lpProps the result of the query
+   \param PropCount the count of property tags
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj or SPropTagArray are null, or the
+   session context could not be obtained
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetProps(mapi_object_t *obj, 
+				  struct SPropTagArray *SPropTagArray,
+				  struct SPropValue **lpProps, uint32_t *PropCount)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct GetProps_req	request;
+	struct mapi_session	*session;
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray2 = NULL;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	enum MAPISTATUS		mapistatus;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+	bool			named = false;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetProps");
+
+	/* Named property mapping */
+	nameid = mapi_nameid_new(mem_ctx);
+	retval = mapi_nameid_lookup_SPropTagArray(nameid, SPropTagArray);
+	if (retval == MAPI_E_SUCCESS) {
+		named = true;
+		SPropTagArray2 = talloc_zero(mem_ctx, struct SPropTagArray);
+		retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray2);
+		OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);		
+		mapi_nameid_map_SPropTagArray(nameid, SPropTagArray, SPropTagArray2);
+		MAPIFreeBuffer(SPropTagArray2);
+
+	}
+	errno = 0;
+
+	/* Reset */
+	*PropCount = 0;
+	*lpProps = 0;
+	size = 0;
+
+	/* Fill the GetProps operation */
+	request.PropertySizeLimit = 0x0;
+	size += sizeof (uint16_t);
+	request.WantUnicode = 0x0;
+	size += sizeof (uint16_t);
+	request.prop_count = (uint16_t) SPropTagArray->cValues;
+	size += sizeof (uint16_t);
+	request.properties = SPropTagArray->aulPropTag;
+	size += request.prop_count * sizeof(uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetProps;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetProps = request;
+	size += 5;
+       
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF((retval && retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx);
+	
+	/* Read the SPropValue array from data blob.
+	   fixme: replace the memory context by the object one.
+	*/
+	if (named == true) {
+		mapi_nameid_unmap_SPropTagArray(nameid, SPropTagArray);
+	}
+	talloc_free(nameid);
+
+	mapistatus = emsmdb_get_SPropValue((TALLOC_CTX *)session,
+					   global_mapi_ctx->lp_ctx,
+					   &mapi_response->mapi_repl->u.mapi_GetProps.prop_data,
+					   SPropTagArray, lpProps, PropCount, 
+					   mapi_response->mapi_repl->u.mapi_GetProps.layout);
+	OPENCHANGE_RETVAL_IF(!mapistatus && (retval == MAPI_W_ERRORS_RETURNED), retval, mem_ctx);
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set one or more properties on a given object
+
+   This function sets one or more properties on a specified object.
+
+   \param obj the object to set properties on
+   \param lpProps the list of properties to set
+   \param PropCount the number of properties
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetProps, GetPropList, GetPropsAll, DeleteProps, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS SetProps(mapi_object_t *obj, struct SPropValue *lpProps, 
+				  unsigned long PropCount)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct SetProps_req	request;
+	struct mapi_session	*session;
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	unsigned long		i;
+	struct mapi_SPropValue	*mapi_props;
+	bool			named = false;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetProps");
+	size = 0;
+
+	/* Named property mapping */
+	nameid = mapi_nameid_new(mem_ctx);
+	retval = mapi_nameid_lookup_SPropValue(nameid, lpProps, PropCount);
+	if (retval == MAPI_E_SUCCESS) {
+		named = true;
+		SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+		retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray);
+		OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+		mapi_nameid_map_SPropValue(nameid, lpProps, PropCount, SPropTagArray);
+		MAPIFreeBuffer(SPropTagArray);
+	}
+	errno = 0;
+
+	/* build the array */
+	request.values.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, PropCount);
+	mapi_props = request.values.lpProps;
+	for (i = 0; i < PropCount; i++) {
+		size += cast_mapi_SPropValue(&mapi_props[i], &lpProps[i]);
+		size += sizeof(uint32_t);
+	}
+
+	request.values.cValues = PropCount;
+	size += sizeof(uint16_t);
+
+	/* add the size of the subcontext that will be added on ndr layer */
+	size += sizeof(uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetProps;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetProps = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (named == true) {
+		mapi_nameid_unmap_SPropValue(nameid, lpProps, PropCount);
+	}
+	talloc_free(nameid);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Makes permanent any changes made to an attachment since the
+   last save operation.
+
+   \param obj_parent the parent of the object to save changes for
+   \param obj_child the object to save changes for
+   \param flags the access flags to set on the saved object 
+
+   Possible flags:
+   - KeepOpenReadOnly
+   - KeepOpenReadWrite
+   - ForceSave
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetProps, ModifyRecipients, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS SaveChangesAttachment(mapi_object_t *obj_parent, 
+					       mapi_object_t *obj_child,
+					       enum SaveFlags flags)
+{
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct SaveChangesAttachment_req	request;
+	struct mapi_session			*session[2];
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size = 0;
+	TALLOC_CTX				*mem_ctx;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF((flags != 0x9) && (flags != 0xA) && (flags != 0xC), 
+		       MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_parent);
+	session[1] = mapi_object_get_session(obj_child);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SaveChangesAttachment");
+	size = 0;
+
+	/* Fill the SaveChangesAttachment operation */
+	request.handle_idx = 0x0;
+	request.SaveFlags = flags;
+	size += sizeof(uint8_t) + sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SaveChangesAttachment;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SaveChangesAttachment = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve all the properties associated with a given object
+
+   \param obj the object to retrieve properties for
+   \param proptags the resulting list of properties associated with
+   the object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetProps, GetPropsAll, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS GetPropList(mapi_object_t *obj, 
+				     struct SPropTagArray *proptags)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetPropList");
+
+	/* Reset */
+	proptags->cValues = 0;
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetPropList;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 1;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Get the repsonse */
+	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);
+		memcpy((void*)proptags->aulPropTag,
+		       (void*)mapi_response->mapi_repl->u.mapi_GetPropList.tags,
+		       size);
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve all properties and values associated with an
+   object
+
+   This function returns all the properties and and associated values
+   for a given object.
+
+   \param obj the object to get the properties for
+   \param properties the properties / values for the object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetProps, GetPropList, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetPropsAll(mapi_object_t *obj,
+				     struct mapi_SPropValue_array *properties)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct GetPropsAll_req	request;
+	struct GetPropsAll_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetPropsAll");
+	size = 0;
+
+	/* Fill the GetPropsAll operation */
+	request.PropertySizeLimit = 0;
+	size += sizeof (uint16_t);
+	request.WantUnicode = 0;
+	size += sizeof (uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetPropsAll;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetPropsAll = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_GetPropsAll;
+	properties->cValues = reply->properties.cValues;
+	properties->lpProps = talloc_steal((TALLOC_CTX *)session, reply->properties.lpProps);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Delete one or more properties from an object
+
+   \param obj the object to remove properties from
+   \param proptags the properties to remove from the given object
+       
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetProps, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS DeleteProps(mapi_object_t *obj, 
+				     struct SPropTagArray *proptags)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct DeleteProps_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeleteProps");
+	size = 0;
+
+	/* Fill the DeleteProps operation */
+	request.count = proptags->cValues;
+	size += sizeof(uint16_t);
+	request.tags = proptags->aulPropTag;
+	size += proptags->cValues * sizeof(enum MAPITAGS);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_DeleteProps;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_DeleteProps = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Deletes property values from an object without invoking
+   replication.
+
+   \param obj the object to remove properties from
+   \param proptags the properties to remove from the given object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+     \sa DeleteProps
+ */
+_PUBLIC_ enum MAPISTATUS DeletePropertiesNoReplicate(mapi_object_t *obj,
+						     struct SPropTagArray *proptags)
+{
+	TALLOC_CTX				*mem_ctx;
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct DeletePropertiesNoReplicate_req	request;
+	struct mapi_session			*session;
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeletePropertiesNoReplicate");
+	size = 0;
+
+	/* Fill the DeletePropertiesNoReplicate operation */
+	request.PropertyTags.cValues = proptags->cValues;
+	size += sizeof (uint16_t);
+	request.PropertyTags.aulPropTag = proptags->aulPropTag;
+	size += proptags->cValues * sizeof (enum MAPITAGS);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_DeletePropertiesNoReplicate;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_DeletePropertiesNoReplicate = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;	
+}
+
+
+/**
+   \details Provides the property names that correspond to one
+   or more property identifiers.
+   
+   \param obj the object we are retrieving the names from
+   \param ulPropTag the mapped property tag
+   \param count count of property names pointed to by the nameid
+   parameter returned by the server
+   \param nameid pointer to a pointer to property names returned by
+   the server
+
+   ulPropTag must be a property with type set to PT_NULL
+ 
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+  
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetIDsFromNames, QueryNamesFromIDs
+*/
+_PUBLIC_ enum MAPISTATUS GetNamesFromIDs(mapi_object_t *obj,
+					 enum MAPITAGS ulPropTag,
+					 uint16_t *count,
+					 struct MAPINAMEID **nameid)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetNamesFromIDs_req	request;
+	struct GetNamesFromIDs_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size= 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Initialization */
+	mem_ctx = talloc_named(NULL, 0, "GetNamesFromIDs");
+	size = 0;
+
+	/* Fill the GetNamesFromIDs operation */
+	request.ulPropTag = ulPropTag;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetNamesFromIDs;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetNamesFromIDs = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Fill in count */
+	reply = &mapi_response->mapi_repl->u.mapi_GetNamesFromIDs;
+	*count = reply->count;
+
+	/* Fill MAPINAMEID struct */
+	*nameid = talloc_steal((TALLOC_CTX *)session, reply->nameid);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Provides the property identifiers that correspond to one
+   or more property names.
+   
+   \param obj the object we are retrieving the identifiers from
+   \param count count of property names pointed to by the nameid
+   parameter.
+   \param nameid pointer to an array of property names
+   \param ulFlags indicates how the property identifiers should be
+   returned
+   \param proptags pointer to a pointer to an array of property tags
+   containing existing or newly assigned property
+   identifiers. Property types in this array are set to PT_NULL.
+
+   ulFlags can be set to:
+   - 0 retrieves named properties from the server
+   - MAPI_CREATE create the named properties if they don't exist on
+     the server
+
+   \note count and nameid parameter can automatically be built
+   using the mapi_nameid API.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetIDsFromNames, QueryNamesFromIDs, mapi_nameid_new
+*/
+_PUBLIC_ enum MAPISTATUS GetIDsFromNames(mapi_object_t *obj,
+					 uint16_t count,
+					 struct MAPINAMEID *nameid,
+					 uint32_t ulFlags,
+					 struct SPropTagArray **proptags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetIDsFromNames_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			i;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!count, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!proptags, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!proptags[0], MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Initialization */
+	mem_ctx = talloc_named(NULL, 0, "GetIDsFromNames");
+	size = 0;
+	
+	/* Fill the GetIDsFromNames operation */
+	request.ulFlags = ulFlags;
+	request.count = count;
+	size += sizeof (uint8_t) + sizeof (uint16_t);
+
+	request.nameid = nameid;
+	for (i = 0; i < count; i++) {
+		size += sizeof (uint8_t) + sizeof (request.nameid[i].lpguid);
+		switch (request.nameid[i].ulKind) {
+		case MNID_ID:
+			size += sizeof (request.nameid[i].kind.lid);
+			break;
+		case MNID_STRING:
+			size += strlen(request.nameid[i].kind.lpwstr.Name) * 2 + 2;
+			size += sizeof (uint8_t);
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetIDsFromNames;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetIDsFromNames = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* 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);
+	for (i = 0; i < proptags[0]->cValues; i++) {
+		proptags[0]->aulPropTag[i] = (mapi_response->mapi_repl->u.mapi_GetIDsFromNames.propID[i] << 16) | PT_UNSPECIFIED;
+	}
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Provides the property names that correspond to one or more
+   property identifiers.
+
+   \param obj the object to obtain the properties for
+   \param queryFlags A set of flags that can restrict the type of properties
+   \param guid a pointer to the GUID for the property set to fetch (null for all
+   property sets.
+   \param count count of property names pointed to by the nameid and propID
+   parameters returned by the server
+   \param propID pointer to an array of property IDs returned by the server
+   \param nameid pointer to an array of property names returned by
+   the server
+
+   \note queryFlags can be NoStrings (0x1) or NoIds (0x2), neither or both.
+   NoStrings will produce only ID properties, NoIds will produce only named
+   properties, and both will result in no output.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \sa GetNamesFromIDs
+*/
+_PUBLIC_ enum MAPISTATUS QueryNamedProperties(mapi_object_t *obj,
+					      uint8_t queryFlags,
+					      struct GUID *guid,
+					      uint16_t *count,
+					      uint16_t **propID,
+					      struct MAPINAMEID **nameid)
+{
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct QueryNamedProperties_req		request;
+	struct QueryNamedProperties_repl	*reply;
+	struct mapi_session			*session;
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size;
+	TALLOC_CTX				*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Initialization */
+	mem_ctx = talloc_named(NULL, 0, "QueryNamesFromIDs");
+	size = 0;
+
+	/* Fill the QueryNamedProperties operation */
+	request.QueryFlags = queryFlags;
+	size += sizeof (uint8_t);
+
+	if (guid) {
+		request.HasGuid = 0x1; /* true */
+		size += sizeof (uint8_t);
+		request.PropertyGuid.guid = *guid;
+		size += sizeof (struct GUID);
+	} else {
+		request.HasGuid = 0x0; /* false */
+		size += sizeof (uint8_t);
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_QueryNamedProperties;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_QueryNamedProperties = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Fill [out] parameters */
+	reply = &mapi_response->mapi_repl->u.mapi_QueryNamedProperties;
+
+	*count = reply->IdCount;
+	*propID = talloc_steal((TALLOC_CTX *)session, reply->PropertyIds);
+	*nameid = talloc_steal((TALLOC_CTX *)session, reply->PropertyNames);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Copy properties from one object to another
+
+   This function copies (or moves) specified properties from
+   one object to another.
+
+   \param obj_src the object to copy properties from
+   \param obj_dst the object to set properties on
+   \param copyFlags flags to determine whether to copy or
+   move, and whether to overwrite existing properties.
+   \param tags the list of properties to copy
+   \param problemCount (return value) number of entries in the problems array
+   \param problems (return value) array of problemCount entries.
+
+   The caller is responsible for freeing the \b problems array
+   using MAPIFreeBuffer(). If the \b problemCount pointer is NULL,
+   then the problems array will not be returned.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetProps, SetProps, DeleteProps, CopyTo, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS CopyProps(mapi_object_t *obj_src,
+				   mapi_object_t *obj_dst,
+				   struct SPropTagArray *tags,
+				   uint8_t copyFlags,
+				   uint16_t *problemCount,
+				   struct PropertyProblem **problems)
+
+{
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct CopyProperties_req	request;
+	struct mapi_session		*session[2];
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	int				i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!tags, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_src);
+	session[1] = mapi_object_get_session(obj_dst);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CopyProps");
+	size = 0;
+
+	/* Fill the CopyProperties operation */
+	request.handle_idx = 0x1;
+	size += sizeof(uint8_t);
+	request.WantAsynchronous = 0x0;
+	size += sizeof(uint8_t);
+	request.CopyFlags = copyFlags;
+	size += sizeof(uint8_t);
+	request.PropertyTags.cValues = tags->cValues;
+	size += sizeof(uint16_t);
+	request.PropertyTags.aulPropTag = tags->aulPropTag;
+	size += tags->cValues * sizeof(enum MAPITAGS);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CopyProperties;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CopyProperties = request;
+	size += 5; // sizeof( EcDoRpc_MAPI_REQ )
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) *2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	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) {
+			(*(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;
+		}
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Copy multiple properties from one object to another
+
+   This function copies (or moves) properties from one object to
+   another. Unlike CopyProperties, this function copies all properties
+   except those identified.
+
+   \param obj_src the object to copy properties from
+   \param obj_dst the object to set properties on
+   \param excludeTags the list of properties to \em not copy
+   \param copyFlags flags to determine whether to copy or
+   move, and whether to overwrite existing properties.
+   \param problemCount (return value) number of entries in the problems array
+   \param problems (return value) array of problemCount entries.
+
+   The caller is responsible for freeing the \b problems array
+   using MAPIFreeBuffer(). If the \b problemCount pointer is NULL,
+   then the problems array will not be returned.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetProps, SetProps, DeleteProps, CopyProps
+*/
+_PUBLIC_ enum MAPISTATUS CopyTo(mapi_object_t *obj_src,
+				mapi_object_t *obj_dst,
+				struct SPropTagArray *excludeTags,
+				uint8_t copyFlags,
+				uint16_t *problemCount,
+				struct PropertyProblem **problems)
+
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct CopyTo_req	request;
+	struct mapi_session	*session[2];
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	int			i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!excludeTags, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_src);
+	session[1] = mapi_object_get_session(obj_dst);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CopyProps");
+	size = 0;
+
+	/* Fill the CopyProperties operation */
+	request.handle_idx = 0x1;
+	size += sizeof(uint8_t);
+	request.WantAsynchronous = 0x0;
+	size += sizeof(uint8_t);
+	request.WantSubObjects = 0x1;
+	size += sizeof(uint8_t);
+	request.CopyFlags = copyFlags;
+	size += sizeof(uint8_t);
+	request.ExcludedTags.cValues = (uint16_t)excludeTags->cValues;
+	size += sizeof(uint16_t);
+	request.ExcludedTags.aulPropTag = excludeTags->aulPropTag;
+	size += excludeTags->cValues * sizeof(enum MAPITAGS);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CopyTo;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CopyTo = request;
+	size += 5; // sizeof( EcDoRpc_MAPI_REQ )
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) *2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (problemCount) {
+		*problemCount = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblemCount;
+		*problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount);
+		for(i=0; i < *problemCount; ++i) {
+			(*(problems[i])).index = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].index;
+			(*(problems[i])).property_tag = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].property_tag;
+			(*(problems[i])).error_code = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblem[i].error_code;
+		}
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMAPISession.c
===================================================================
--- trunk/openchange/libmapi/IMAPISession.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPISession.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,289 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IMAPISession.c
+
+   \brief Session initialization options
+ */
+
+
+/**
+   \details Open the Public Folder store
+
+   This function opens the public folder store. This allows access to
+   the public folders.
+
+   \param obj_store the result of opening the store
+   \param session pointer to the MAPI session context
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize which is required before opening the store
+   \sa GetLastError to check the result of a failed call, if necessary
+   \sa OpenMsgStore if you need access to the message store folders
+*/
+_PUBLIC_ enum MAPISTATUS OpenPublicFolder(struct mapi_session *session,
+					  mapi_object_t *obj_store)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct Logon_req	request;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_store_t	*store;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenPublicFolder");
+	size = 0;
+
+	/* Fill the Logon operation */
+ 	request.LogonFlags = 0;
+	size += sizeof (uint8_t);
+	request.OpenFlags = PUBLIC;
+	size += sizeof (uint32_t);
+	request.StoreState = 0;
+	size += sizeof (uint32_t);
+	request.EssDN = NULL;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_Logon;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_Logon = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) + 2;
+	mapi_request->length = size + 2;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* retrieve object session and handle */
+	mapi_object_set_session(obj_store, session);
+	mapi_object_set_handle(obj_store, mapi_response->handles[0]);
+
+	/* retrieve store content */
+	obj_store->private_data = talloc((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);
+
+	store->fid_pf_public_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[0];
+	store->fid_pf_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[1];
+	store->fid_pf_non_ipm_subtree = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[2];
+	store->fid_pf_EFormsRegistryRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[3];
+	store->fid_pf_FreeBusyRoot = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[4];
+	store->fid_pf_OfflineAB = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[5];
+	store->fid_pf_EFormsRegistry = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_pf.FolderIds[6];
+	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;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Open the Message Store
+
+   This function opens the main message store. This allows access to
+   the normal user folders.
+
+   \param session pointer to the MAPI session context
+   \param obj_store the result of opening the store
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize which is required before opening the store
+   \sa GetLastError to check the result of a failed call, if necessary
+   \sa OpenPublicFolder if you need access to the public folders
+*/
+_PUBLIC_ enum MAPISTATUS OpenMsgStore(struct mapi_session *session,
+				      mapi_object_t *obj_store)
+{
+	enum MAPISTATUS		retval;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL);
+
+	retval = OpenUserMailbox(session, session->profile->username, obj_store);
+
+	/* Exchange clustered case */
+	if ((retval != MAPI_E_SUCCESS) && 
+	    ((GetLastError() == ecUnknownUser) || (GetLastError() == MAPI_E_LOGON_FAILED))) {
+		errno = 0;
+		retval = OpenUserMailbox(session, NULL, obj_store);
+	}
+
+	return retval;
+}
+
+
+/**
+   \details Open another user mailbox
+
+   This function opens the main message store. This allows access to
+   the normal user folders.
+
+   \param session pointer to the MAPI session context
+   \param username name of the user's mailbox to open
+   \param obj_store the result of opening the store
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize which is required before opening the store
+   \sa GetLastError to check the result of a failed call, if necessary
+   \sa OpenPublicFolder if you need access to the public folders
+ */
+_PUBLIC_ enum MAPISTATUS OpenUserMailbox(struct mapi_session *session,
+					 const char *username,
+					 mapi_object_t *obj_store)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct Logon_req	request;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_store_t	*store;
+	char			*mailbox;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session->profile, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenMsgStore");
+	size = 0;
+
+	if (!username) {
+		mailbox = talloc_strdup(mem_ctx, session->profile->mailbox);
+	} else {
+		mailbox = talloc_asprintf(mem_ctx, "/o=%s/ou=%s/cn=Recipients/cn=%s", session->profile->org,
+					  session->profile->ou, username);
+	}
+
+	/* Fill the Logon operation */
+	request.LogonFlags = LogonPrivate;
+	size += sizeof (uint8_t);
+	request.OpenFlags = HOME_LOGON | TAKE_OWNERSHIP | NO_MAIL;
+	size += sizeof (uint32_t);
+	request.StoreState = 0;
+	size += sizeof (uint32_t);
+	request.EssDN = talloc_strdup(mem_ctx, mailbox);
+	size += strlen(request.EssDN) + 1;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_Logon;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_Logon = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) + 2;
+	mapi_request->length = size + 2;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* set object session and handle */
+	mapi_object_set_session(obj_store, session);
+	mapi_object_set_handle(obj_store, mapi_response->handles[0]);
+
+	/* retrieve store content */
+	obj_store->private_data = talloc((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);
+
+	store->fid_mailbox_root = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[0];
+	store->fid_deferred_actions = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[1];
+	store->fid_spooler_queue = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[2];
+	store->fid_top_information_store = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[3];
+	store->fid_inbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[4]; 
+	store->fid_outbox = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[5];
+	store->fid_sent_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[6];
+	store->fid_deleted_items = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[7];
+	store->fid_common_views = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[8];
+	store->fid_schedule = mapi_response->mapi_repl->u.mapi_Logon.LogonType.store_mailbox.FolderIds[9];
+	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;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMAPISupport.c
===================================================================
--- trunk/openchange/libmapi/IMAPISupport.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPISupport.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,376 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+
+
+/**
+   \file IMAPISupport.c
+
+   \brief MAPI notifications functions
+ */
+
+
+/**
+   \details Register an object to receive notifications
+ 
+   This function registers notifications on the Exchange server for an
+   object.  The function holds the notifications intended to be
+   monitored in as a bitmask.
+
+   \param obj the object to get notifications for
+   \param connection connection identifier for callabck function
+   \param NotificationFlags mask for events to provide notifications for (see
+   below)
+   \param WholeStore whether the scope for this notification is whole
+   database
+   \param notify_callback notification callback function.
+   
+   The Notification Flags can take the following values:
+   - fnevCriticalError
+   - fnevNewMail
+   - fnevObjectCreated
+   - fnevObjectDeleted
+   - fnevObjectModified
+   - fnevObjectMoved
+   - fnevObjectCopied
+   - fnevSearchComplete
+   - fnevTableModified
+   - fnevStatusObjectModified
+   - fnevReservedForMapi
+   - fnevExtended
+   
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.  
+   
+   \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_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa RegisterNotification, Unsubscribe, MonitorNotification,
+   GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS Subscribe(mapi_object_t *obj, uint32_t	*connection, 
+				   uint16_t NotificationFlags,
+				   bool WholeStore,
+				   mapi_notify_callback_t notify_callback)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct RegisterNotification_req	request;
+	struct notifications		*notification;
+	struct mapi_notify_ctx		*notify_ctx;
+	struct mapi_session		*session;
+	enum MAPISTATUS			retval;
+	NTSTATUS			status;
+	uint32_t			size = 0;
+	static uint32_t			ulConnection = 0;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!connection, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "Subscribe");
+
+	/* Fill the Subscribe operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.NotificationFlags = NotificationFlags;
+	size += sizeof (uint16_t);
+
+	request.WantWholeStore = WholeStore;
+	size += sizeof (uint8_t);
+
+	if (WholeStore == false) {
+		request.FolderId.ID = mapi_object_get_id(obj);
+		size += sizeof (uint64_t);
+
+		request.MessageId.ID = 0x0;
+		size += sizeof (uint64_t);
+	}
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_RegisterNotification;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_RegisterNotification = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	mapi_request->handles[0] = mapi_object_get_handle(obj);
+	mapi_request->handles[1] = 0xffffffff;
+
+	status = emsmdb_transaction(session->emsmdb->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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* add the notification to the list */
+	ulConnection++;
+	notify_ctx = session->notify_ctx;
+	notification = talloc_zero((TALLOC_CTX *)session, struct notifications);
+
+	notification->ulConnection = ulConnection;
+	notification->parentID = mapi_object_get_id(obj);
+	*connection = ulConnection;
+
+	/* set notification handle */
+	mapi_object_init(&notification->obj_notif);
+	mapi_object_set_handle(&notification->obj_notif, mapi_response->handles[1]);
+
+	notification->NotificationFlags = NotificationFlags;
+	notification->callback = notify_callback;
+
+	DLIST_ADD(notify_ctx->notifications, notification);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Unregister notifications on a given object.
+
+   Cancel any notification registrations associated with the notify
+   object.  This function unregisters notifications on the Exchange
+   server for the object specified with its connection number
+   ulConnection. The function will releases the notification on the
+   Exchange server and remove the entry from the internal
+   notifications list.
+
+   The function takes a callback to execute when such notification
+   occurs and returns the ulConnection identifier we can use in
+   further management.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.  
+   
+   \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_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa RegisterNotification, Subscribe, MonitorNotification,
+   GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS Unsubscribe(struct mapi_session *session, uint32_t ulConnection)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_notify_ctx	*notify_ctx;
+	struct notifications	*notification;
+
+	/* 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;
+	notification = notify_ctx->notifications;
+
+	while (notification) {
+		if (notification->ulConnection == ulConnection) {
+			retval = Release(&notification->obj_notif);
+			mapi_errstr("Release", GetLastError());
+			OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+			DLIST_REMOVE(notify_ctx->notifications, notification);
+			break;
+		}
+		notification = notification->next;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+static enum MAPISTATUS ProcessNotification(struct mapi_notify_ctx *notify_ctx, 
+					   struct mapi_response *mapi_response,
+					   void *private_data)
+{
+	struct notifications	*notification;
+	void			*NotificationData;
+	uint32_t		i;
+
+	if (!mapi_response || !mapi_response->mapi_repl) return MAPI_E_INVALID_PARAMETER;
+
+	for (i = 0; mapi_response->mapi_repl[i].opnum; i++) {
+		if (mapi_response->mapi_repl[i].opnum == op_MAPI_Notify) {
+			switch(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) {
+			case fnevNewMail:
+			case fnevMbit|fnevNewMail:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.NewMailNotification);
+				break;
+			case fnevObjectCreated:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderCreatedNotification);
+				break;
+			case fnevObjectDeleted:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderDeletedNotification);
+				break;
+			case fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_10);
+				break;
+			case fnevObjectMoved:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderMoveNotification);
+				break;
+			case fnevObjectCopied:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderCopyNotification);
+				break;			
+			case fnevSearchComplete:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchCompleteNotification);
+				break;
+			case fnevTableModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.HierarchyTableChange);
+				break;
+			case fnevStatusObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.IcsNotification);
+				break;
+			case fnevTbit|fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_1010);
+				break;
+			case fnevUbit|fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_2010);
+				break;
+			case fnevTbit|fnevUbit|fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.FolderModifiedNotification_3010);
+				break;
+			case fnevMbit|fnevObjectCreated:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageCreatedNotification);
+				break;
+			case fnevMbit|fnevObjectDeleted:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageDeletedNotification);
+				break;
+			case fnevMbit|fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageModifiedNotification);
+				break;
+			case fnevMbit|fnevObjectMoved:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageMoveNotification);
+				break;
+			case fnevMbit|fnevObjectCopied:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.MessageCopyNotification);
+				break;
+			case fnevMbit|fnevTableModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.ContentsTableChange);
+				break;
+			case fnevMbit|fnevSbit|fnevObjectDeleted:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchMessageRemovedNotification);
+				break;
+			case fnevMbit|fnevSbit|fnevObjectModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchMessageModifiedNotification);
+				break;
+			case fnevMbit|fnevSbit|fnevTableModified:
+				NotificationData = (void *)&(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationData.SearchTableChange);
+				break;			
+			default:
+				NotificationData = NULL;
+				break;
+			}
+			notification = notify_ctx->notifications;
+			while (notification->ulConnection) {
+				if (notification->NotificationFlags & mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) {
+					if (notification->callback) {
+						notification->callback(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType,
+								       (void *)NotificationData,
+								       (void *)private_data);
+					}
+				}
+				notification = notification->next;
+			}
+		}
+	}
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Wait for notifications and process them
+
+   This function indefinively 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.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.  
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa RegisterNotification, Subscribe, Unsubscribe, GetLastError
+
+   \note This code is experimental. The current implementation is
+   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)
+{
+	struct mapi_response	*mapi_response;
+	struct mapi_notify_ctx	*notify_ctx;
+	enum MAPISTATUS		retval;
+	NTSTATUS		status;
+	int			is_done;
+	int			err;
+	char			buf[512];
+	
+	/* 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;
+
+	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, private_data);
+				OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+			}
+		}
+		if (err <= 0) is_done = 1;
+	}
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMAPITable.c
===================================================================
--- trunk/openchange/libmapi/IMAPITable.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMAPITable.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1842 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Brad Hards 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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+/**
+   \file IMAPITable.c
+
+   \brief Operations on tables
+ */
+
+
+/**
+   \details Defines the particular properties and order of properties
+  to appear as columns in the table.
+ 
+  \param obj_table the table the function is setting columns for
+  \param properties the properties intended to be set
+
+  \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_W_ERROR_RETURNED: Problem encountered while trying to set
+   one or more properties
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+  \sa QueryRows, QueryColumns, SeekRow, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS SetColumns(mapi_object_t *obj_table, 
+				    struct SPropTagArray *properties)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct SetColumns_req	request;
+	struct mapi_session	*session;
+	TALLOC_CTX		*mem_ctx;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	mapi_object_table_t	*table;
+
+	/* sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetColumns");
+	size = 0;
+
+	/* Fill the SetColumns operation */
+	request.SetColumnsFlags = SetColumns_TBL_SYNC;
+	request.prop_count = properties->cValues;
+	request.properties = properties->aulPropTag;
+	size += 3 + request.prop_count * sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetColumns;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetColumns = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval && (retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx);
+
+	/* recopy property tags into table */
+	/* fixme: obj_table->private_data should be initialized during opening, not here */
+	if (obj_table->private_data == NULL) {
+		obj_table->private_data = talloc((TALLOC_CTX *)session, mapi_object_table_t);
+	}
+
+	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,
+							  enum MAPITAGS, table->proptags.cValues);
+		memcpy((void*)table->proptags.aulPropTag, (void*)properties->aulPropTag,
+		       table->proptags.cValues * sizeof(enum MAPITAGS));
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns the approximate cursor position
+ 
+   \param obj_table pointer to the table's object
+   \param Numerator pointer to the numerator of the fraction
+   identifying the table position
+   \param Denominator pointer to the denominator of the fraction
+   identifying the table position
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa QueryRows
+*/
+_PUBLIC_ enum MAPISTATUS QueryPosition(mapi_object_t *obj_table, 
+				       uint32_t *Numerator,
+				       uint32_t *Denominator)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "QueryPosition");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_QueryPosition;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	if (Numerator) {
+		*Numerator = mapi_response->mapi_repl->u.mapi_QueryPosition.Numerator;
+	}
+
+	if (Denominator) {
+		*Denominator = mapi_response->mapi_repl->u.mapi_QueryPosition.Denominator;
+	}
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a RowSet with the properties returned by the
+   server
+
+   \param obj_table the table we are requesting properties from
+   \param row_count the maximum number of rows to retrieve
+   \param flags flags to use for the query
+   \param rowSet the results
+
+   flags possible values:
+   - TBL_ADVANCE: index automatically increased from last rowcount
+   - TBL_NOADVANCE: should be used for a single QueryRows call
+   - TBL_ENABLEPACKEDBUFFERS: (not yet implemented)
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa SetColumns, QueryPosition, QueryColumns, SeekRow
+ */
+_PUBLIC_ enum MAPISTATUS QueryRows(mapi_object_t *obj_table, uint16_t row_count,
+				   enum QueryRowsFlags flags, 
+				   struct SRowSet *rowSet)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct QueryRows_req	request;
+	struct QueryRows_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_table_t	*table;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "QueryRows");
+	size = 0;
+
+	/* Fill the QueryRows operation */
+	request.QueryRowsFlags = flags;
+	/* TODO: search backwards for negative row_count */
+	request.ForwardRead = 1;
+	request.RowCount = row_count;
+	size += 4;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_QueryRows;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_QueryRows = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* table contains mapitags from previous SetColumns */
+	table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
+
+	/* TODO: handle Origin */
+	reply = &mapi_response->mapi_repl->u.mapi_QueryRows;
+	rowSet->cRows = reply->RowCount;
+	rowSet->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, rowSet->cRows);
+	emsmdb_get_SRowSet((TALLOC_CTX *)table, global_mapi_ctx->lp_ctx, rowSet, &table->proptags, &reply->RowData);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieves the set of columns defined in the current table
+   view
+
+   \param obj_table the table we are retrieving columns from
+   \param cols pointer to an array of property tags
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetColumns, QueryRows
+*/
+_PUBLIC_ enum MAPISTATUS QueryColumns(mapi_object_t *obj_table, 
+				      struct SPropTagArray *cols)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct QueryColumnsAll_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	mapi_object_table_t		*table;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "QueryColumns");
+
+	cols->cValues = 0;
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_QueryColumnsAll;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* get columns SPropTagArray */
+	table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_QueryColumnsAll;
+	cols->cValues = reply->PropertyTagCount;
+	cols->aulPropTag = talloc_array((TALLOC_CTX *)table, enum MAPITAGS, cols->cValues);
+	memcpy((void *)cols->aulPropTag, (const void *)reply->PropertyTags, cols->cValues * sizeof(enum MAPITAGS));
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Move the table cursor at a specific location
+
+   \param obj_table the table we are moving cursor on
+   \param origin the table position where we start to seek 
+   \param offset a particular offset in the table
+   \param row the position of the seeked row is returned in rows
+
+   origin possible values:
+   - BOOKMARK_BEGINNING: Beginning of the table
+   - BOOKMARK_CURRENT: Current position in the table
+   - BOKMARK_END: End of the table
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa SetColumns, QueryRows
+*/
+_PUBLIC_ enum MAPISTATUS SeekRow(mapi_object_t *obj_table, 
+				 enum BOOKMARK origin, 
+				 int32_t offset, uint32_t *row)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct SeekRow_req	request;
+	struct SeekRow_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SeekRow");
+	*row = 0;
+
+	/* Fill the SeekRow operation */
+	size = 0;
+	request.origin = origin;
+	size += 1;
+	request.offset = offset;
+	size += 4;
+	request.WantRowMovedCount = 0;
+	size += 1;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SeekRow;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SeekRow = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_SeekRow;
+	*row = reply->RowsSought;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Move the table cursor at a specific location given a
+   bookmark
+
+   \param obj_table the table we are moving cursor on
+   \param lpbkPosition the bookmarked position 
+   \param RowCount a relative number of rows to the bookmark
+   \param row the position of the seeked row is returned in rows
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or
+     beyond the last row requested
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa CreateBookmark, FreeBookmark
+ */
+_PUBLIC_ enum MAPISTATUS SeekRowBookmark(mapi_object_t *obj_table,
+					 uint32_t lpbkPosition,
+					 uint32_t RowCount,
+					 uint32_t *row)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SeekRowBookmark_req	request;
+	struct SeekRowBookmark_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	struct SBinary_short   		bin;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	retval = mapi_object_bookmark_find(obj_table, lpbkPosition, &bin);
+	OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SeekRowBookmark");
+
+	/* Fill the SeekRowBookmark operation */
+	size = 0;
+	request.Bookmark.cb = bin.cb;
+	size += sizeof (uint16_t);
+	request.Bookmark.lpb = bin.lpb;
+	size += bin.cb;
+	request.RowCount = RowCount;
+	size += sizeof (uint32_t);
+	request.WantRowMovedCount = 0x1;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SeekRowBookmark;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SeekRowBookmark = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_SeekRowBookmark;
+	*row = reply->RowsSought;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Moves the cursor to an approximate fractional position in
+   the table
+
+   \param obj_table the table we are moving cursor on
+   \param ulNumerator numerator of the fraction representing the table
+   position.
+   \param ulDenominator denominator of the fraction representing the
+   table position
+
+   - If ulDenominator is NULL, then SeekRowApprox returns
+   MAPI_E_INVALID_PARAMETER.
+   - If ulNumerator is NULL, then SeekRowApprox moves the cursor to
+     the beginning of the table. In such situation, SeekRowApprox call
+     is similar to SeekRow with BOOKMARK_BEGINNING
+   - If ulNumerator and ulDenominator have the same value, then
+     SeekRowApprox moves the cursor to the end of the table. In such
+     situation, SeekRowApprox call is similar to SeekRow with
+     BOOKMARK_END
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa SeekRow, SeekRowBookmark
+ */
+_PUBLIC_ enum MAPISTATUS SeekRowApprox(mapi_object_t *obj_table,
+				       uint32_t ulNumerator,
+				       uint32_t ulDenominator)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SeekRowApprox_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ulDenominator, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SeekRowApprox");
+	
+	/* Fill the SeekRowApprox operation */
+	size = 0;
+	request.ulNumerator = ulNumerator;
+	size += sizeof (uint32_t);
+	request.ulDenominator = ulDenominator;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SeekRowApprox;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SeekRowApprox = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Marks the table current position
+
+   \param obj_table the table we are creating a bookmark in
+   \param lpbkPosition pointer to the bookmark value. This bookmark
+   can be passed in a call to the SeekRowBookmark method
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa SeekRowBookmark, FreeBookmark
+ */
+_PUBLIC_ enum MAPISTATUS CreateBookmark(mapi_object_t *obj_table, 
+					uint32_t *lpbkPosition)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct CreateBookmark_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	mapi_object_table_t	       	*mapi_table;
+	mapi_object_bookmark_t		*bookmark;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateBookmark");	
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CreateBookmark;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_CreateBookmark;
+
+	mapi_table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!mapi_table, MAPI_E_INVALID_PARAMETER, mem_ctx);
+
+	/* Store CreateBookmark data in mapi_object_table private_data */
+	bookmark = talloc_zero((TALLOC_CTX *)mapi_table->bookmark, mapi_object_bookmark_t);
+	mapi_table->bk_last++;
+	bookmark->index = mapi_table->bk_last;
+	bookmark->bin.cb = reply->bookmark.cb;
+	bookmark->bin.lpb = talloc_array((TALLOC_CTX *)bookmark, uint8_t, reply->bookmark.cb);
+	memcpy(bookmark->bin.lpb, reply->bookmark.lpb, reply->bookmark.cb);
+
+	DLIST_ADD(mapi_table->bookmark, bookmark);
+
+	*lpbkPosition = mapi_table->bk_last;
+
+	obj_table->private_data = mapi_table;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Release the resources associated with a bookmark
+
+   \param obj_table the table the bookmark is associated to
+   \param bkPosition the bookmark to be freed
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_INVALID_BOOKMARK: The bookmark specified is invalid or
+     beyond the last row requested
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+ 
+   \sa CreateBookmark
+*/
+_PUBLIC_ enum MAPISTATUS FreeBookmark(mapi_object_t *obj_table, 
+				      uint32_t bkPosition)
+{
+	mapi_object_table_t		*table;
+	mapi_object_bookmark_t		*bookmark;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct FreeBookmark_req		request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(bkPosition > table->bk_last, MAPI_E_INVALID_BOOKMARK, NULL);
+
+	bookmark = table->bookmark;
+	OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_INVALID_BOOKMARK, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "FreeBookmark");
+
+	while (bookmark) {
+		if (bookmark->index == bkPosition) {
+			if (bookmark->index == table->bk_last) {
+				table->bk_last--;
+			}
+			size = 0;
+
+			/* Fill the FreeBookmark operation */
+			request.bookmark.cb = bookmark->bin.cb;
+			size += sizeof (uint16_t);
+			request.bookmark.lpb = bookmark->bin.lpb;
+			size += bookmark->bin.cb;
+
+			/* Fill the MAPI_REQ request */
+			mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+			mapi_req->opnum = op_MAPI_FreeBookmark;
+			mapi_req->logon_id = 0;
+			mapi_req->handle_idx = 0;
+			mapi_req->u.mapi_FreeBookmark = request;
+			size += 5;
+
+			/* 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;
+			mapi_request->mapi_req = mapi_req;
+			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);
+			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;
+			OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+			MAPIFreeBuffer(bookmark->bin.lpb);
+			DLIST_REMOVE(table->bookmark, bookmark);
+
+			talloc_free(mapi_response);
+			talloc_free(mem_ctx);
+
+			return MAPI_E_SUCCESS;
+		}
+		bookmark = bookmark->next;
+	}
+	talloc_free(mem_ctx);
+	return MAPI_E_INVALID_BOOKMARK;
+}
+
+
+/**
+   \details Order the rows of the table based on a criteria
+
+   \param obj_table the table we are ordering rows on
+   \param lpSortCriteria pointer on sort criterias to apply
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table or lpSortCriteria is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+ */
+_PUBLIC_ enum MAPISTATUS SortTable(mapi_object_t *obj_table, 
+				   struct SSortOrderSet *lpSortCriteria)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct SortTable_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpSortCriteria, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SortTable");
+
+	/* Fill the SortTable operation */
+	size = 0;
+	request.SortTableFlags = 0;
+	size += sizeof (uint8_t);
+	request.lpSortCriteria.cSorts = lpSortCriteria->cSorts;
+	size += sizeof (uint16_t);
+	request.lpSortCriteria.cCategories = lpSortCriteria->cCategories;
+	size += sizeof (uint16_t);
+	request.lpSortCriteria.cExpanded = lpSortCriteria->cExpanded;
+	size += sizeof (uint16_t);
+	request.lpSortCriteria.aSort = lpSortCriteria->aSort;
+	size += lpSortCriteria->cSorts * (sizeof (uint32_t) + sizeof (uint8_t));
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SortTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SortTable = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the size associated to a mapi SRestriction
+
+   \param res pointer on the mapi_SRestriction
+
+   \return mapi_SRestriction size
+ */
+uint32_t get_mapi_SRestriction_size(struct mapi_SRestriction *res)
+{
+	uint32_t	size;
+	uint32_t	i;
+
+	size = 0;
+
+	size += sizeof (res->rt);
+
+	switch(res->rt) {
+	case RES_AND:
+		size += sizeof (res->res.resAnd.cRes);
+		for (i = 0; i < res->res.resAnd.cRes; i++) {
+			size += get_mapi_SRestriction_size((struct mapi_SRestriction *)&(res->res.resAnd.res[i]));
+		}
+		break;
+	case RES_OR:
+		size += sizeof (res->res.resOr.cRes);
+		for (i = 0; i < res->res.resOr.cRes; i++) {
+			size += get_mapi_SRestriction_size((struct mapi_SRestriction *)&(res->res.resOr.res[i]));
+		}
+		break;
+	case RES_CONTENT:
+		size += sizeof (res->res.resContent.fuzzy);
+		size += sizeof (res->res.resContent.ulPropTag);
+		size += sizeof (res->res.resContent.lpProp.ulPropTag);
+		size += get_mapi_property_size(&(res->res.resContent.lpProp));
+		break;
+	case RES_PROPERTY:
+		size += sizeof (res->res.resProperty.relop);
+		size += sizeof (res->res.resProperty.ulPropTag);
+		size += sizeof (res->res.resProperty.lpProp.ulPropTag);
+		size += get_mapi_property_size(&(res->res.resProperty.lpProp));
+		break;
+	case RES_COMPAREPROPS:
+		size += sizeof (uint8_t);
+		size += sizeof (res->res.resCompareProps.ulPropTag1);
+		size += sizeof (res->res.resCompareProps.ulPropTag2);
+		break;
+	case RES_BITMASK:
+		size += sizeof (uint8_t);
+		size += sizeof (res->res.resBitmask.ulPropTag);
+		size += sizeof (res->res.resBitmask.ulMask);
+		break;
+	case RES_SIZE:
+		size += sizeof (uint8_t);
+		size += sizeof (res->res.resSize.ulPropTag);
+		size += sizeof (res->res.resSize.size);
+		break;
+	case RES_EXIST:
+		size += sizeof (res->res.resExist.ulPropTag);
+		break;
+	}
+	return (size);
+}
+
+/**
+   \details Removes all filters that are currently on a table
+
+   \param obj_table the table object to reset
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa Restrict
+*/
+_PUBLIC_ enum MAPISTATUS Reset(mapi_object_t *obj_table)
+{
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "Reset");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ResetTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Applies a filter to a table, reducing the row set to only
+   those rows matching the specified criteria.
+
+   \param obj_table the object we are filtering
+   \param res the filters we want to apply
+   \param TableStatus the table status result
+
+   TableStatus can either hold:
+	- TBLSTAT_COMPLETE (0x0)
+	- TBLSTAT_SORTING (0x9)
+	- TBLSTAT_SORT_ERROR (0xA)
+	- TBLSTAT_SETTING_COLS (0xB)
+	- TBLSTAT_SETCOL_ERROR (0xD)
+	- TBLSTAT_RESTRICTING (0xE)
+	- TBLSTAT_RESTRICT_ERROR (0xF)
+
+
+   Unlike MAPI, you don't pass a null restriction argument to remove 
+   the current restrictions. Use Reset() instead.
+
+   TableStatus should be set to NULL if you don't want to retrieve the
+   status of the table.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa QueryRows, Reset
+*/
+_PUBLIC_ enum MAPISTATUS Restrict(mapi_object_t *obj_table, 
+				  struct mapi_SRestriction *res,
+				  uint8_t *TableStatus)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct Restrict_req	request;
+	struct Restrict_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "Restrict");
+
+	/* Fill the Restrict operation */
+	size = 0;
+	request.handle_idx = 0;
+	size += sizeof (request.handle_idx);
+	request.restrictions = *res;
+	size += get_mapi_SRestriction_size(res);
+
+	/* add subcontext size */
+	size += sizeof (uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_Restrict;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_Restrict = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (TableStatus) {
+		reply = &mapi_response->mapi_repl->u.mapi_Restrict;
+		*TableStatus = reply->TableStatus;
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Find the next row in a table that matches specific search
+   criteria
+
+   \param obj_table the table we are searching in
+   \param res pointer on search criterias
+   \param bkOrigin bookmark identifying the row where FindRow should
+   begin
+   \param ulFlags controls the direction of the search
+   \param SRowSet the resulting row
+
+   bkOrigin can either take the value of a bookmark created with
+   CreateBookmark or any of the default values:
+   - BOOKMARK_BEGINNING
+   - BOOKMARK_CURRENT
+   - BOOKMARK_END
+
+   ulFlags can be set either to DIR_FORWARD (0x0) or DIR_BACKWARD
+   (0x1).
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or
+     beyond the last row requested.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa CreateBookmark
+ */
+_PUBLIC_ enum MAPISTATUS FindRow(mapi_object_t *obj_table, 
+				 struct mapi_SRestriction *res,
+				 uint32_t bkOrigin, uint8_t ulFlags,
+				 struct SRowSet *SRowSet)
+{
+	struct mapi_request    	*mapi_request;
+	struct mapi_response   	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct FindRow_req     	request;
+	struct FindRow_repl    	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_table_t	*table;
+	struct SBinary_short	bin;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	if (bkOrigin >= 3) {
+		retval = mapi_object_bookmark_find(obj_table, bkOrigin, &bin);
+		OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL);
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "FindRow");
+
+	/* Fill the FindRow operation */
+	size = 0;
+	request.ulFlags = ulFlags;
+	size += sizeof (uint8_t);
+	request.res = *res;
+	size += get_mapi_SRestriction_size(res);
+	request.origin = (bkOrigin > 3) ? 3 : bkOrigin;
+	size += sizeof (uint8_t);
+	if (bkOrigin >= 3) {
+		request.bookmark.cb = bin.cb;
+		request.bookmark.lpb = bin.lpb;
+		size += sizeof (uint16_t)+ bin.cb;
+	} else {
+		request.bookmark.cb = 0;
+		request.bookmark.lpb = NULL;
+		size += sizeof (uint16_t);
+	}
+
+	/* add subcontext size */
+	size += sizeof (uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_FindRow;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_FindRow = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* table contains SPropTagArray from previous SetColumns call */
+	table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_FindRow;
+	SRowSet->cRows = 1;
+	SRowSet->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, SRowSet->cRows);
+	emsmdb_get_SRowSet((TALLOC_CTX *)table, global_mapi_ctx->lp_ctx, SRowSet, &table->proptags, &reply->row);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the status of a table
+
+   \param obj_table the table we are retrieving the status from
+   \param TableStatus the table status result
+
+   TableStatus can either hold:
+	- TBLSTAT_COMPLETE (0x0)
+	- TBLSTAT_SORTING (0x9)
+	- TBLSTAT_SORT_ERROR (0xA)
+	- TBLSTAT_SETTING_COLS (0xB)
+	- TBLSTAT_SETCOL_ERROR (0xD)
+	- TBLSTAT_RESTRICTING (0xE)
+	- TBLSTAT_RESTRICT_ERROR (0xF)
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_INVALID_BOOKMARK: the bookmark specified is invalid or
+     beyond the last row requested.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa SetColumns, Restrict, FindRow, GetHierarchyTable, GetContentsTable
+ */
+_PUBLIC_ enum MAPISTATUS GetStatus(mapi_object_t *obj_table, uint8_t *TableStatus)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct GetStatus_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetStatus");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetStatus;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve TableStatus */
+	reply = &mapi_response->mapi_repl->u.mapi_GetStatus;
+	*TableStatus = reply->TableStatus;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Aborts an asynchronous table operation in progress
+
+   \param obj_table the table object where we want to abort an
+   asynchronous operation
+   \param TableStatus pointer on the table status returned by the
+   operation
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table or TableStatus are null
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+ */
+_PUBLIC_ enum MAPISTATUS Abort(mapi_object_t *obj_table, uint8_t *TableStatus)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct Abort_repl	*reply;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!TableStatus, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "Abort");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_Abort;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* Fill the mapi_request stucture */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t);
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve TableStatus */
+	reply = &mapi_response->mapi_repl->u.mapi_Abort;
+	*TableStatus = reply->TableStatus;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Expand a collapsed row in a table
+
+   After a contents table has been sorted and categorized using
+   SortTable, rows can be expanded and collapsed (using ExpandRow and
+   CollapseRow repectively).
+
+   \param obj_table the table we are collapsing the category in.
+   \param categoryId the row identification for the heading row for
+   the category being expanded.
+   \param maxRows the maximum number of rows to retrieve (can be zero)
+   \param rowData (result) the data rows under this category heading
+   \param expandedRowCount (result) the number of rows that were added
+   to the table when the row was expanded
+
+   You obtain the categoryId argument from the PR_INST_ID property of
+   the heading row for the category that is being collapsed.
+
+   The maxRows argument specifies the upper limit on how many rows to
+   return (as rowData) when the category is expanded. The
+   expandedRowCount argument returns the number of rows that were
+   added to the table. As an example, consider a collapsed category
+   with 8 entries. If you set maxRows to 3, then rowData will contain
+   the data for the first three rows, and expandedRowCount will be set
+   to 8. If you now use QueryRows(), you can read the 5 additional
+   rows. If you'd specified maxRows as 8 (or more), rowData would have
+   contained all 8 rows and expandedRowCount still would have been 8.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table, rowData or rowCount are NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa CollapseRow
+ */
+_PUBLIC_ enum MAPISTATUS ExpandRow(mapi_object_t *obj_table, uint64_t categoryId,
+				   uint16_t maxRows, struct SRowSet *rowData,
+				   uint32_t *expandedRowCount)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct ExpandRow_req		request;
+	struct ExpandRow_repl		*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	mapi_object_table_t		*table;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!rowData, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!expandedRowCount, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ExpandRow");
+	size = 0;
+
+	/* Fill the ExpandRow operation */
+	request.MaxRowCount = maxRows;
+	size += sizeof (uint16_t);
+	request.CategoryId = categoryId;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ExpandRow;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_ExpandRow = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* table contains mapitags from previous SetColumns */
+	table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
+
+	/* Retrieve the rowData and expandedRowCount */
+	reply = &mapi_response->mapi_repl->u.mapi_ExpandRow;
+	rowData->cRows = reply->RowCount;
+	rowData->aRow = talloc_array((TALLOC_CTX *)table, struct SRow, reply->RowCount);
+	emsmdb_get_SRowSet((TALLOC_CTX *)table, global_mapi_ctx->lp_ctx, rowData, &table->proptags, &reply->RowData);
+	*expandedRowCount = reply->ExpandedRowCount;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Collapse an expanded row in a table
+
+   After a contents table has been sorted and categorized using
+   SortTable, rows can be expanded and collapsed (using ExpandRow and
+   CollapseRow repectively).
+
+   \param obj_table the table we are collapsing the category in.
+   \param categoryId the row identification for the heading row for
+   the category being collapsed.
+   \param rowCount (result) the number of rows that were removed from the 
+   table when the row was collapsed.
+
+   You obtain the categoryId argument from the PR_INST_ID property of
+   the heading row for the category that is being collapsed.
+
+   If you pass rowCount as null, the number of rows will not be returned.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table is NULL
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa ExpandRow
+ */
+_PUBLIC_ enum MAPISTATUS CollapseRow(mapi_object_t *obj_table, uint64_t categoryId,
+				     uint32_t *rowCount)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct CollapseRow_req		request;
+	struct CollapseRow_repl		*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CollapseRow");
+	size = 0;
+
+	/* Fill the CollapseRow operation */
+	request.CategoryId = categoryId;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CollapseRow;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CollapseRow = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve the RowCount */
+	reply = &mapi_response->mapi_repl->u.mapi_CollapseRow;
+	*rowCount = reply->CollapsedRowCount;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+
+}
+
+/**
+   \details Get the Collapse State of a Table
+
+   After a contents table has been sorted and categorized using
+   SortTable, rows can be expanded and collapsed (using ExpandRow() and
+   CollapseRow() repectively). You can save the state of the table using
+   this function, and restore it using SetCollapseState.
+
+   \param obj_table the table we are retrieving the state from
+   \param rowId the row number for the cursor
+   \param rowInstanceNumber the instance number for the cursor
+   \param CollapseState (result) the returned table Collapse State
+
+   You obtain the row number and row instance number arguments from
+   the PR_INST_ID and  PR_INST_NUM properties of the row you want to
+   use as the cursor.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table or CollapseState are null
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa SetCollapseState
+ */
+_PUBLIC_ enum MAPISTATUS GetCollapseState(mapi_object_t *obj_table, uint64_t rowId,
+					  uint32_t rowInstanceNumber,
+					  struct SBinary_short *CollapseState)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetCollapseState_req	request;
+	struct GetCollapseState_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mem_ctx = talloc_named(NULL, 0, "GetCollapseState");
+	size = 0;
+
+	/* Fill the GetCollapseState operation */
+	size = 0;
+	request.RowId = rowId;
+	size += sizeof (uint64_t);
+	request.RowInstanceNumber = rowInstanceNumber;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetCollapseState;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetCollapseState = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve the CollapseState */
+	reply = &mapi_response->mapi_repl->u.mapi_GetCollapseState;
+	CollapseState->cb = reply->CollapseState.cb;
+	CollapseState->lpb = talloc_array((TALLOC_CTX *)session, uint8_t, reply->CollapseState.cb);
+	memcpy(CollapseState->lpb, reply->CollapseState.lpb, reply->CollapseState.cb);
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the Collapse State of a Table
+
+   After a contents table has been sorted and categorized using
+   SortTable, rows can be expanded and collapsed (using ExpandRow() and
+   CollapseRow() repectively). You can save the state of the table using
+   GetCollapseState, and restore it using this function.
+
+   \param obj_table the table we are restoring the state for
+   \param CollapseState the Collapse State to restore
+   \param lpbkPosition pointer to the bookmark value. This bookmark
+   can be passed in a call to the SeekRowBookmark method
+
+   You obtain the row number and row instance number arguments from
+   the PR_INST_ID and  PR_INST_NUM properties of the row you want to
+   use as the cursor.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_table or CollapseState are null
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa GetCollapseState
+ */
+_PUBLIC_ enum MAPISTATUS SetCollapseState(mapi_object_t *obj_table,
+					  struct SBinary_short *CollapseState,
+					  uint32_t *lpbkPosition)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetCollapseState_req	request;
+	struct SetCollapseState_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	mapi_object_table_t	       	*mapi_table;
+	mapi_object_bookmark_t		*bookmark;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!CollapseState, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_table);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mem_ctx = talloc_named(NULL, 0, "SetCollapseState");
+	size = 0;
+
+	/* Fill the SetCollapseState operation */
+	size = 0;
+	request.CollapseState.cb = CollapseState->cb;
+	size += sizeof (uint16_t);
+	request.CollapseState.lpb = CollapseState->lpb;
+	size += CollapseState->cb;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetCollapseState;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetCollapseState = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_SetCollapseState;
+
+	mapi_table = (mapi_object_table_t *)obj_table->private_data;
+	OPENCHANGE_RETVAL_IF(!mapi_table, MAPI_E_INVALID_PARAMETER, mem_ctx);
+
+	/* Store the bookmark in the mapi_object_table private_data */
+	bookmark = talloc_zero((TALLOC_CTX *)mapi_table->bookmark, mapi_object_bookmark_t);
+	mapi_table->bk_last++;
+	bookmark->index = mapi_table->bk_last;
+	bookmark->bin.cb = reply->bookmark.cb;
+	bookmark->bin.lpb = talloc_array((TALLOC_CTX *)bookmark, uint8_t, reply->bookmark.cb);
+	memcpy(bookmark->bin.lpb, reply->bookmark.lpb, reply->bookmark.cb);
+
+	DLIST_ADD(mapi_table->bookmark, bookmark);
+
+	*lpbkPosition = mapi_table->bk_last;
+
+	obj_table->private_data = mapi_table;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMSProvider.c
===================================================================
--- trunk/openchange/libmapi/IMSProvider.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMSProvider.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,325 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/mapicode.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <gen_ndr/ndr_exchange_c.h>
+#include <core/error.h>
+#include <param.h>
+#include <credentials.h>
+
+
+/**
+   \file IMSProvider.c
+
+   \brief Provider operations
+*/
+
+
+/*
+ * Log MAPI to one instance of a message store provider
+ */
+
+static NTSTATUS provider_rpc_connection(TALLOC_CTX *parent_ctx, 
+					struct dcerpc_pipe **p, 
+					const char *binding,
+					struct cli_credentials *credentials,
+					const struct ndr_interface_table *table,
+					struct loadparm_context *lp_ctx)
+{
+	NTSTATUS		status;
+	struct tevent_context	*ev;
+
+	if (!binding) {
+		DEBUG(3, ("You must specify a ncacn binding string\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	ev = tevent_context_init(talloc_autofree_context());
+
+	status = dcerpc_pipe_connect(parent_ctx, 
+				     p, binding, table,
+				     credentials, ev, lp_ctx); 
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("Failed to connect to remote server: %s %s\n", 
+			  binding, nt_errstr(status)));
+	}
+
+	/* dcerpc_pipe_connect set errno, we have to unset it */
+	errno = 0;
+	return status;
+}
+
+
+/**
+   \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
+ */
+_PUBLIC_ const char *RfrGetNewDSA(struct mapi_session *session,
+				  const char *server, 
+				  const char *userDN)
+{
+	NTSTATUS		status;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_profile	*profile;
+	struct RfrGetNewDSA	r;
+	struct dcerpc_pipe	*pipe;
+	char			*binding;
+	const char		*ppszServer = NULL;
+
+	/* Sanity Checks */
+	if (!global_mapi_ctx) return server;
+	if (!global_mapi_ctx->session) return server;
+
+	mem_ctx = (TALLOC_CTX *)session;
+	profile = session->profile;
+
+	binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+	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;
+
+
+	r.in.ulFlags = 0x0;
+	r.in.pUserDN = userDN ? userDN : "";
+	r.in.ppszUnused = NULL;
+	r.in.ppszServer = &ppszServer;
+
+	status = dcerpc_RfrGetNewDSA(pipe, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) return server;
+
+	return (ppszServer ? ppszServer : server);
+}
+
+
+/**
+   \details Returns the FQDN of the NSPI server corresponding to a DN
+
+   \param session pointer to the MAPI session context
+   \param serverFQDN pointer to the server FQDN string (return value)
+
+   \return MAPI_E_SUCCESS on success, otherwise a MAPI error and
+   serverFQDN content set to NULL.
+ */
+_PUBLIC_ enum MAPISTATUS RfrGetFQDNFromLegacyDN(struct mapi_session *session,
+						const char **serverFQDN)
+{
+	NTSTATUS			status;
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_profile		*profile;
+	struct RfrGetFQDNFromLegacyDN	r;
+	struct dcerpc_pipe		*pipe;
+	char				*binding;
+	const char     			*ppszServerFQDN;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = (TALLOC_CTX *)session;
+	profile = session->profile;
+	*serverFQDN = NULL;
+
+	binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", profile->server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+	status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, global_mapi_ctx->lp_ctx);
+	talloc_free(binding);
+
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);
+
+	r.in.ulFlags = 0x0;
+	r.in.cbMailboxServerDN = strlen(profile->homemdb) + 1;
+	r.in.szMailboxServerDN = profile->homemdb;
+	r.out.ppszServerFQDN = &ppszServerFQDN;
+
+	status = dcerpc_RfrGetFQDNFromLegacyDN(pipe, mem_ctx, &r);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+	
+	if (ppszServerFQDN) {
+		*serverFQDN = ppszServerFQDN;
+	} else {
+		*serverFQDN = NULL;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+enum MAPISTATUS Logon(struct mapi_session *session,
+		      struct mapi_provider *provider, 
+		      enum PROVIDER_ID provider_id)
+{
+	NTSTATUS		status;
+	TALLOC_CTX		*mem_ctx;
+	struct dcerpc_pipe	*pipe;
+	struct mapi_profile	*profile;
+	char			*binding;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = (TALLOC_CTX *)provider;
+	profile = session->profile;
+	
+	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]" : "[]"));
+		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);
+		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL);
+		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);
+		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]" : "[]"));
+		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);
+		OPENCHANGE_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_HOST_UNREACHABLE), MAPI_E_NETWORK_ERROR, NULL);
+		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 = (void *)nspi_bind(provider, pipe, profile->credentials, 
+						  profile->codepage, profile->language, profile->method);
+		OPENCHANGE_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL);
+		break;
+	default:
+		OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL);
+		break;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Logoff an Exchange store
+
+   This function uninitializes the MAPI session associated to the
+   object.
+
+   \param obj_store pointer to the store object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS Logoff(mapi_object_t *obj_store)
+{
+	struct mapi_session	*session;
+	struct mapi_session	*el;
+	bool			found = false;
+
+	/* Sanity checks */
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (el = global_mapi_ctx->session; el; el = el->next) {
+		if (session == el) {
+			found = true;
+			mapi_object_release(obj_store);
+			DLIST_REMOVE(global_mapi_ctx->session, el);
+			break;
+		}
+	}
+
+	return (found == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Initialize the notification subsystem
+
+   This function initializes the notification subsystem, binds a local
+   UDP port to receive Exchange (server side) notifications and
+   configures the server to send notifications on this port.
+
+   \param ulEventMask the mask of events to provide notifications for.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa Subscribe, Unsubscribe, MonitorNotification, GetLastError 
+*/
+_PUBLIC_ enum MAPISTATUS RegisterNotification(uint16_t ulEventMask)
+{
+	NTSTATUS		status;
+	struct emsmdb_context	*emsmdb;
+	struct mapi_session	*session;
+	TALLOC_CTX		*mem_ctx;
+	struct NOTIFKEY		*lpKey;
+	static uint8_t		rand = 0;
+	static uint8_t		attempt = 0;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx->session, MAPI_E_SESSION_LIMIT, NULL);
+
+	session = (struct mapi_session *)global_mapi_ctx->session;
+	OPENCHANGE_RETVAL_IF(!session->emsmdb, MAPI_E_SESSION_LIMIT, NULL);
+
+	emsmdb = (struct emsmdb_context *)global_mapi_ctx->session->emsmdb->ctx;
+	OPENCHANGE_RETVAL_IF(!emsmdb, MAPI_E_SESSION_LIMIT, NULL);
+
+	mem_ctx = emsmdb->mem_ctx;
+
+	/* bind local udp port */
+	session->notify_ctx = emsmdb_bind_notification(mem_ctx);
+	if (!session->notify_ctx) return MAPI_E_CANCEL;
+
+	/* tell exchange where to send notifications */
+	lpKey = talloc_zero(mem_ctx, struct NOTIFKEY);
+	lpKey->cb = 8;
+	lpKey->ab = talloc_array((TALLOC_CTX *)lpKey, uint8_t, lpKey->cb);
+	memcpy(lpKey->ab, "libmapi", 7);
+retry:
+	lpKey->ab[7] = rand;
+
+	status = emsmdb_register_notification(lpKey, ulEventMask);
+	if (!NT_STATUS_IS_OK(status)) {
+		if (attempt < 5) {
+			rand++;
+			attempt++;
+			errno = 0;
+			goto retry;
+		} else {
+			talloc_free(lpKey);
+			return MAPI_E_CALL_FAILED;
+		}
+	}
+	talloc_free(lpKey);
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IMessage.c
===================================================================
--- trunk/openchange/libmapi/IMessage.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMessage.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1435 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+
+
+/**
+   \file IMessage.c
+
+   \brief Operations on messages
+ */
+
+
+/**
+   \details Create a new attachment
+
+   This function creates a new attachment to an existing message.
+
+   \param obj_message the message to attach to
+   \param obj_attach the attachment
+
+   Both objects need to exist before you call this message. obj_message
+   should be a valid message on the server. obj_attach needs to be 
+   initialised.
+
+   \code
+   enum MAPISTATUS         retval;
+   mapi_object_t           obj_message;
+   mapi_object_t           obj_attach;
+
+   ... open or create the obj_message ...
+
+   mapi_object_init(&obj_attach);
+   retval = CreateAttach(&obj_message, &obj_attach);
+   ... check the return value ...
+
+   ... use SetProps() to set the attachment up ...
+   ... perhaps OpenStream() / WriteStream() / CommitStream() on obj_attach ...
+
+   // Save the changes to the attachment and then the message
+   retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+   ... check the return value ...
+   retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+   ... check the return value ...
+   \endcode
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa CreateMessage, GetAttachmentTable, OpenAttach, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS CreateAttach(mapi_object_t *obj_message, 
+				      mapi_object_t *obj_attach)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct CreateAttach_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateAttach");
+	size = 0;
+
+	/* Fill the CreateAttach operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CreateAttach;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CreateAttach = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + (sizeof (uint32_t) * 2);
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_attach, session);
+	mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Delete an attachment from a message
+
+   This function deletes one attachment from a message. The attachment
+   to be deleted is specified by its PR_ATTACH_NUM
+
+   \param obj_message the message to operate on
+   \param AttachmentID the attachment number
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+      \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa CreateMessage, GetAttachmentTable, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS DeleteAttach(mapi_object_t *obj_message, uint32_t AttachmentID)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct DeleteAttach_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeleteAttach");
+	size = 0;
+
+	/* Fill the DeleteAttach operation */
+	request.AttachmentID = AttachmentID;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_DeleteAttach;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_DeleteAttach = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the attachment table for a message
+
+   \param obj_message the message
+   \param obj_table the attachment table for the message
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa CreateMessage, OpenMessage, CreateAttach, OpenAttach, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetAttachmentTable(mapi_object_t *obj_message, 
+					    mapi_object_t *obj_table)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetAttachmentTable_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetAttachmentTable");
+	size = 0;
+
+	/* Fill the GetAttachmentTable operation */
+	request.handle_idx = 1;
+	size += sizeof (uint8_t);
+
+	request.TableFlags = 0x0;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetAttachmentTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetAttachmentTable = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_table, session);
+	mapi_object_set_handle(obj_table, mapi_response->handles[mapi_response->mapi_repl->handle_idx]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Open an attachment to a message
+
+   This function opens one attachment from a message. The attachment
+   to be opened is specified by its PR_ATTACH_NUM.
+
+   \param obj_message the message to operate on
+   \param AttachmentID the attachment number
+   \param obj_attach the resulting attachment object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa CreateMessage, CreateAttach, GetAttachmentTable, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS OpenAttach(mapi_object_t *obj_message, uint32_t AttachmentID,
+				    mapi_object_t *obj_attach)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct OpenAttach_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenAttach");
+	size = 0;
+
+	/* Fill the OpenAttach operation */
+	request.handle_idx = 0x1;
+	size += sizeof(uint8_t);
+	request.OpenAttachmentFlags = OpenAttachmentFlags_ReadOnly;
+	size += sizeof(uint8_t);
+	request.AttachmentID = AttachmentID;
+	size += sizeof(uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenAttach;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenAttach = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_attach, session);
+	mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the type of a recipient
+
+   The function sets the recipient type (RecipClass) in the aRow
+   parameter.  ResolveNames should be used to fill the SRow structure.
+
+   \param aRow the row to set
+   \param RecipClass the type of recipient to set on the specified row
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: The aRow parameter was not set
+     properly.
+
+   \sa ResolveNames, ModifyRecipients, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS SetRecipientType(struct SRow *aRow, enum ulRecipClass RecipClass)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	lpProp;
+
+	lpProp.ulPropTag = PR_RECIPIENT_TYPE;
+	lpProp.value.l = RecipClass;
+
+	retval = SRow_addprop(aRow, lpProp);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * retrieve the organization length for Exchange recipients
+ */
+uint8_t mapi_recipients_get_org_length(struct mapi_profile *profile)
+{
+	if (profile->mailbox && profile->username)
+		return (strlen(profile->mailbox) - strlen(profile->username));
+	return 0;
+}
+
+
+/*
+ * EXPERIMENTAL:
+ * bitmask calculation for recipients headers structures
+ */
+uint16_t mapi_recipients_bitmask(struct SRow *aRow)
+{
+	uint16_t		bitmask;
+	struct SPropValue	*lpProp = NULL;
+
+	bitmask = 0;
+
+	/* recipient type: EXCHANGE or SMTP */
+	lpProp = get_SPropValue_SRow(aRow, PR_ADDRTYPE);
+	if (lpProp && lpProp->value.lpszA) {
+		if (!strcmp("SMTP", lpProp->value.lpszA)) {
+			bitmask |= 0xB;
+		}
+	} else {
+		/* (Bit 8) doesn't seem to work if unset */
+		bitmask |= 0x81;
+	}
+
+	/* Bit 15: DISPLAY_NAME */
+	lpProp = get_SPropValue_SRow(aRow, PR_DISPLAY_NAME);
+	if (lpProp && lpProp->value.lpszA) {
+		bitmask |= 0x400;
+	}
+
+	lpProp = get_SPropValue_SRow(aRow, PR_DISPLAY_NAME_UNICODE);
+	if (lpProp && lpProp->value.lpszW) {
+		bitmask |= 0x600;
+	}
+
+	/* Bit 6: PR_GIVEN_NAME */
+	lpProp = get_SPropValue_SRow(aRow, PR_GIVEN_NAME);
+	if (lpProp && lpProp->value.lpszA) {
+		bitmask |= 0x20;
+	}
+
+	lpProp = get_SPropValue_SRow(aRow, PR_GIVEN_NAME_UNICODE);
+	if (lpProp && lpProp->value.lpszW) {
+		bitmask |= 0x220;
+	}
+
+	/* Bit 5. PR_7BIT_DISPLAY_NAME */
+	lpProp = get_SPropValue_SRow(aRow, PR_7BIT_DISPLAY_NAME);
+	if (lpProp && lpProp->value.lpszA) {
+		bitmask |= 0x10;
+	}
+
+	lpProp = get_SPropValue_SRow(aRow, PR_7BIT_DISPLAY_NAME_UNICODE);
+	if (lpProp && lpProp->value.lpszW) {
+		bitmask |= 0x210;
+	}
+
+	/* Bit 4: PR_EMAIL_ADDRESS */
+	if (bitmask & 0xA) {
+		lpProp = get_SPropValue_SRow(aRow, PR_SMTP_ADDRESS);
+		if (lpProp && lpProp->value.lpszA) {
+			bitmask |= 0x8;
+		}
+		
+		lpProp = get_SPropValue_SRow(aRow, PR_SMTP_ADDRESS_UNICODE);
+		if (lpProp && lpProp->value.lpszW) {
+			bitmask |= 0x208;
+		}
+	}
+
+	return bitmask;
+}
+
+
+/**
+   \details Adds, deletes or modifies message recipients
+
+   \param obj_message the message to change the recipients for
+   \param SRowSet the recipients to add
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \bug ModifyRecipients can only add recipients.
+
+   \sa CreateMessage, ResolveNames, SetRecipientType, GetLastError
+
+*/
+_PUBLIC_ enum MAPISTATUS ModifyRecipients(mapi_object_t *obj_message, 
+					  struct SRowSet *SRowSet)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct ModifyRecipients_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+	unsigned long			i_prop, j;
+	unsigned long			i_recip;
+	uint32_t			count;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SRowSet, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!SRowSet->aRow, MAPI_E_NOT_INITIALIZED, NULL);
+
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ModifyRecipients");
+	size = 0;
+
+	/* Fill the ModifyRecipients operation */
+	request.prop_count = SRowSet->aRow[0].cValues;
+	size += sizeof(uint16_t);
+
+	/* 
+	 * append here property tags that can be fetched with
+	 * ResolveNames but shouldn't be included in ModifyRecipients rows
+	 */
+	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,
+						     PR_DISPLAY_NAME,
+						     PR_DISPLAY_NAME_UNICODE,
+						     PR_GIVEN_NAME,
+						     PR_GIVEN_NAME_UNICODE,
+						     PR_GIVEN_NAME_ERROR,
+						     PR_RECIPIENT_TYPE,
+						     PR_ADDRTYPE);
+	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);
+
+	for (i_recip = 0; i_recip < request.cValues; i_recip++) {
+		struct SRow			*aRow;
+		struct RecipientRow		*RecipientRow;
+		struct ndr_push			*ndr;
+		struct mapi_SPropValue		mapi_sprop;
+		const uint32_t			*RecipClass = 0;
+
+		ndr = talloc_zero(mem_ctx, struct ndr_push);
+		ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
+
+		aRow = &(SRowSet->aRow[i_recip]);
+		RecipientRow = &(request.RecipientRow[i_recip].RecipientRow);
+		
+		request.RecipientRow[i_recip].idx = i_recip;
+		size += sizeof(uint32_t);
+
+		RecipClass = (const uint32_t *) find_SPropValue_data(aRow, PR_RECIPIENT_TYPE);
+		OPENCHANGE_RETVAL_IF(!RecipClass, MAPI_E_INVALID_PARAMETER, mem_ctx);
+		request.RecipientRow[i_recip].RecipClass = (uint8_t) *RecipClass;
+		size += sizeof(uint8_t);
+		
+		RecipientRow->RecipientFlags = mapi_recipients_bitmask(aRow);
+		
+		/* recipient type EXCHANGE or SMTP */
+		switch (RecipientRow->RecipientFlags & 0xB) {
+		case 0x1: 
+			RecipientRow->type.EXCHANGE.organization_length = mapi_recipients_get_org_length(session->profile);
+			RecipientRow->type.EXCHANGE.addr_type = 0;
+			RecipientRow->type.EXCHANGE.username = (const char *) find_SPropValue_data(aRow, PR_7BIT_DISPLAY_NAME);
+			size += sizeof(uint32_t) + strlen(RecipientRow->type.EXCHANGE.username) + 1;
+			break;
+		case 0xB:
+			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;
+			break;
+		case (0x220):
+			RecipientRow->TransmittableDisplayName.lpszW = (const char *) find_SPropValue_data(aRow, PR_GIVEN_NAME_UNICODE);
+			size += strlen(RecipientRow->TransmittableDisplayName.lpszW) * 2 + 2;
+			break;
+		default:
+			break;
+		}
+
+		/* Bit 5: PR_7BIT_DISPLAY_NAME */
+		switch (RecipientRow->RecipientFlags & 0x210) {
+		case (0x10):
+			RecipientRow->DisplayName.lpszA = (const char *) find_SPropValue_data(aRow, PR_7BIT_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);
+			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;
+			break;
+		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;
+		}
+		
+		RecipientRow->prop_count = request.prop_count;
+		size += sizeof(uint16_t);
+		RecipientRow->layout = 0;
+		size += sizeof(uint8_t);
+		
+		/* for each property, we set the switch values and ndr_flags then call mapi_SPropValue_CTR */
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		for (i_prop = 0; i_prop < request.prop_count; i_prop++) {
+			for (j = 0; j < aRow->cValues; j++) {
+				if (aRow->lpProps[j].ulPropTag == request.properties[i_prop]) {
+					ndr_push_set_switch_value(ndr, &mapi_sprop.value, 
+								  (aRow->lpProps[j].ulPropTag & 0xFFFF));
+					cast_mapi_SPropValue(&mapi_sprop, &aRow->lpProps[j]);
+					ndr_push_mapi_SPropValue_CTR(ndr, NDR_SCALARS, &mapi_sprop.value);
+				}
+			}
+		}
+		
+		RecipientRow->prop_values.length = ndr->offset;
+		RecipientRow->prop_values.data = ndr->data;
+		/* add the blob size field */
+		size += sizeof(uint16_t);
+		size += RecipientRow->prop_values.length;
+	}
+	
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ModifyRecipients;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_ModifyRecipients = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Read Recipients from a message
+
+   \param obj_message the message we want to read recipients from
+   \param RowId the row index we start reading recipients from
+   \param RowCount pointer on the number of recipients
+   \param RecipientRows pointer on the recipients array
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+  \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa ModifyRecipients, RemoveAllRecipients, GetRecipientTable,
+   OpenMessage
+ */
+_PUBLIC_ enum MAPISTATUS ReadRecipients(mapi_object_t *obj_message, 
+					uint32_t RowId, uint8_t *RowCount,
+					struct ReadRecipientRow **RecipientRows)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct ReadRecipients_req	request;
+	struct ReadRecipients_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ReadRecipients");
+	size = 0;
+
+	/* Fill the ReadRecipients operation */
+	request.RowId = RowId;
+	size += sizeof (uint32_t);
+
+	request.ulReserved = 0;
+	size += sizeof (uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ReadRecipients;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_ReadRecipients = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve the recipients */
+	reply = &mapi_response->mapi_repl->u.mapi_ReadRecipients;
+	*RowCount = reply->RowCount;
+	*RecipientRows = talloc_steal((TALLOC_CTX *)session, reply->RecipientRows);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Deletes all recipients from a message
+
+   \param obj_message the message we want to remove all recipients from
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa ModifyRecipients, ReadRecipients
+*/
+_PUBLIC_ enum MAPISTATUS RemoveAllRecipients(mapi_object_t *obj_message)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct RemoveAllRecipients_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "RemoveAllRecipients");
+	size = 0;
+
+	/* Fill the RemoveAllRecipients operation */
+	request.ulReserved = 0;
+	size += sizeof (uint32_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_RemoveAllRecipients;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_RemoveAllRecipients = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Saves all changes to the message and marks it as ready for
+   sending.
+
+   This function saves all changes made to a message and marks it
+   ready to be sent.
+
+   \param obj_message the message to mark complete
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa CreateMessage, SetProps, ModifyRecipients, SetRecipientType,
+   GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS SubmitMessage(mapi_object_t *obj_message)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SubmitMessage_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SubmitMessage");
+	size = 0;
+
+	/* Fill the SubmitMessage operation */
+	request.SubmitFlags = 0x0;
+	size += sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SubmitMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SubmitMessage = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Aborts a previous message submission.
+
+   \param obj_store the store object
+   \param obj_folder the folder object where the message has been
+   submitted
+   \param obj_message the submitted message object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+   - MAPI_E_UNABLE_TO_ABORT: The operation can not be aborted
+   - MAPI_E_NOT_IN_QUEUE: The message is no longer in the message store's
+     spooler queue
+   - MAPI_E_NO_SUPPORT: the server object associated with the input
+     handle index in the server object table is not of type Logon or
+     the current logon session is a public logon.
+
+    \sa SubmitMessage
+ */
+_PUBLIC_ enum MAPISTATUS AbortSubmit(mapi_object_t *obj_store,
+				     mapi_object_t *obj_folder, 
+				     mapi_object_t *obj_message)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct AbortSubmit_req	request;
+	struct mapi_session	*session[2];
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_store);
+	session[1] = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "AbortSubmit");
+	size = 0;
+
+	/* Fill the AbortSubmit operation */
+	request.FolderId = mapi_object_get_id(obj_folder);
+	size += sizeof (uint64_t);
+
+	request.MessageId = mapi_object_get_id(obj_message);
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_AbortSubmit;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_AbortSubmit = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Saves all changes to the message
+
+   \param parent the parent object for the message
+   \param obj_message the message to save
+   \param SaveFlags specify how the save operation behaves
+
+   Possible value for SaveFlags:
+   -# KeepReadOnly Keep the Message object open with read-only access
+   -# KeepOpenReadWrite Keep the Message object open with read-write
+      access
+   -# ForceSave Commit the changes and keep the message object open
+      with read-write access
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa SetProps, ModifyRecipients, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS SaveChangesMessage(mapi_object_t *parent,
+					    mapi_object_t *obj_message,
+					    uint8_t SaveFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SaveChangesMessage_req	request;
+	struct mapi_session		*session[2];
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!parent, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF((SaveFlags != 0x9) && (SaveFlags != 0xA) && 
+			     (SaveFlags != 0xC), MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(parent);
+	session[1] = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SaveChangesMessage");
+	size = 0;
+
+	/* Fill the SaveChangesMessage operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.SaveFlags = SaveFlags;
+	size += sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SaveChangesMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SaveChangesMessage = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + (2 * sizeof (uint32_t));
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* store the message_id */
+	mapi_object_set_id(obj_message, mapi_response->mapi_repl->u.mapi_SaveChangesMessage.MessageId);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Sends the specified Message object out for message
+   delivery.
+
+*/
+_PUBLIC_ enum MAPISTATUS TransportSend(mapi_object_t *obj_message, 
+				       struct mapi_SPropValue_array *lpProps)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct TransportSend_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_message);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "TransportSend");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_TransportSend;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve reply parameters */
+	reply = &mapi_response->mapi_repl->u.mapi_TransportSend;
+	if (!reply->NoPropertiesReturned) {
+		lpProps->cValues = reply->properties.lpProps.cValues;
+		lpProps->lpProps = talloc_steal((TALLOC_CTX *)session, reply->properties.lpProps.lpProps);
+	} else {
+		lpProps = NULL;
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns the message recipient table
+
+   \param obj_message the message to receive recipients from
+   \param SRowSet pointer to the recipient table
+   \param SPropTagArray pointer to the array of properties listed in
+   the recipient table
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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
+
+     \sa OpenMessage
+ */
+_PUBLIC_ enum MAPISTATUS GetRecipientTable(mapi_object_t *obj_message, 
+					   struct SRowSet *SRowSet,
+					   struct SPropTagArray *SPropTagArray)
+{
+	mapi_object_message_t	*message;
+
+	message = (mapi_object_message_t *)obj_message->private_data;
+
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!message, MAPI_E_NOT_INITIALIZED, NULL);
+
+	*SRowSet = message->SRowSet;
+	*SPropTagArray = message->SPropTagArray;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Clear or set the MSGFLAG_READ flag for a given message
+
+   This function clears or sets the MSGFLAG_READ flag in the
+   PR_MESSAGE_FLAGS property of a given message.
+
+   \param obj_folder the folder to operate in
+   \param obj_child the message to set flags on
+   \param flags the new flags (MSGFLAG_READ) value
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenMessage, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS SetMessageReadFlag(mapi_object_t *obj_folder, 
+					    mapi_object_t *obj_child,
+					    uint8_t flags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetMessageReadFlag_req	request;
+	struct mapi_session		*session[2];
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_folder);
+	session[1] = mapi_object_get_session(obj_child);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetMessageReadFlags");
+	size = 0;
+
+	/* Fill the SetMessageReadFlags operation */
+	request.handle_idx = 0x1;
+	size += sizeof(uint8_t);
+	request.flags = flags;
+	size += sizeof(uint8_t);
+
+	request.clientdata.length = 0;
+	request.clientdata.data = NULL;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetMessageReadFlag;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetMessageReadFlag = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Opens an embedded message object and retrieves a MAPI object that
+   can be used to get or set properties on the embedded message.
+
+   This function essentially takes an attachment and gives you back
+   a message.
+
+   \param obj_attach the attachment object
+   \param obj_embeddedmsg the embedded message
+   \param ulFlags access rights on the embedded message
+
+   Possible ulFlags values:
+   - 0x0: read only access
+   - 0x1: Read / Write access
+   - 0x2: Create 
+
+   \code
+	... assume we have a message - obj_message ...
+	// Initialise the attachment object
+	mapi_object_init(&obj_attach);
+
+	// Create an attachment to the message
+	retval = CreateAttach(&obj_message, &obj_attach);
+	... check the return value ...
+
+	// use SetProps() to set the attachment up, noting the special PR_ATTACHM_METHOD property
+	attach[0].ulPropTag = PR_ATTACH_METHOD;
+	attach[0].value.l = ATTACH_EMBEDDED_MSG;
+	attach[1].ulPropTag = PR_RENDERING_POSITION;
+	attach[1].value.l = 0;
+	retval = SetProps(&obj_attach, attach, 2);
+	... check the return value ...
+
+        // Initialise the embedded message object
+	mapi_object_init(&obj_embeddedmsg);
+	retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE);
+	... check the return value ...
+
+	// Fill in the embedded message properties, just like any other message (e.g. resulting from CreateMessage())
+
+	// Save the changes to the embedded message
+	retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly);
+	... check the return value ...
+
+	// Save the changes to the attachment
+	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+	... check the return value ...
+
+	// Save the changes to the original message
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	... check the return value ...
+   \endcode
+
+   \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: obj_store is undefined
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. 
+
+   \sa CreateAttach, OpenMessage, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS OpenEmbeddedMessage(mapi_object_t *obj_attach,
+					     mapi_object_t *obj_embeddedmsg,
+					     enum OpenEmbeddedMessage_OpenModeFlags ulFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct OpenEmbeddedMessage_req	request;
+	struct OpenEmbeddedMessage_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_attach, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_attach);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_embeddedmsg, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenEmbeddedMessage");
+
+	/* Fill the OpenEmbeddedMessage request */
+	request.handle_idx = 0x1;
+	size += sizeof(uint8_t);
+	request.CodePageId = 0xfff;
+	size += sizeof(uint16_t);
+	request.OpenModeFlags = ulFlags;
+	size += sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenEmbeddedMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenEmbeddedMessage = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_embeddedmsg, session);
+	mapi_object_set_handle(obj_embeddedmsg, mapi_response->handles[1]);
+
+	/* Store OpenEmbeddedMessage reply data */
+	reply = &mapi_response->mapi_repl->u.mapi_OpenEmbeddedMessage;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+

Added: trunk/openchange/libmapi/IMsgStore.c
===================================================================
--- trunk/openchange/libmapi/IMsgStore.c	                        (rev 0)
+++ trunk/openchange/libmapi/IMsgStore.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,813 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IMsgStore.c
+
+   \brief Folders related operations
+ */
+
+
+/**
+   \details Open a folder from the store
+ 
+   \param obj_store the store to open a folder in (i.e. the parent)
+   \param id_folder the folder identifier
+   \param obj_folder the resulting open folder
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize, OpenMsgStore, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS OpenFolder(mapi_object_t *obj_store, mapi_id_t id_folder,
+				    mapi_object_t *obj_folder)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct OpenFolder_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenFolder");
+
+	/* Fill the OpenFolder operation */
+	request.handle_idx = 0x1;
+	request.folder_id = id_folder;
+	request.OpenModeFlags = OpenModeFlags_Folder;
+	size += sizeof (uint8_t) + sizeof(uint64_t) + sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenFolder = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);	
+
+	/* Set object session, id and handle */
+	mapi_object_set_session(obj_folder, session);
+	mapi_object_set_id(obj_folder, id_folder);
+	mapi_object_set_handle(obj_folder, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Determine if a public folder is ghosted.
+
+   This function returns whether a public folder is ghosted or not.
+
+   \param obj_store the store of the public folder
+   \param obj_folder the folder we are querying for ghost
+   \param IsGhosted pointer on the boolean value returned
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+*/
+_PUBLIC_ enum MAPISTATUS PublicFolderIsGhosted(mapi_object_t *obj_store,
+					       mapi_object_t *obj_folder,
+					       bool *IsGhosted)
+{
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct PublicFolderIsGhosted_req	request;
+	struct mapi_session			*session[2];
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size = 0;
+	TALLOC_CTX				*mem_ctx;
+	mapi_id_t				folderId;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session[0] = mapi_object_get_session(obj_store);
+	session[1] = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	folderId = mapi_object_get_id(obj_folder);
+	OPENCHANGE_RETVAL_IF(!folderId, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "PublicFolderIsGhosted");
+	size = 0;
+
+	/* Fill the PublicFolderIsGhosted operation */
+	request.FolderId = folderId;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_PublicFolderIsGhosted;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_PublicFolderIsGhosted = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*IsGhosted = mapi_response->mapi_repl->u.mapi_PublicFolderIsGhosted.IsGhosted;
+	
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Open a NNTP Public Folder given its name
+
+   \param obj_folder the parent folder
+   \param obj_child the resulting open folder
+   \param name the folder name
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa OpenPublicFolder
+ */
+_PUBLIC_ enum MAPISTATUS OpenPublicFolderByName(mapi_object_t *obj_folder,
+						mapi_object_t *obj_child,
+						const char *name)
+{
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct OpenPublicFolderByName_req	request;
+	struct mapi_session			*session;
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size = 0;
+	TALLOC_CTX				*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!name, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_folder);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenPublicFolderByName");
+	size = 0;
+
+	/* Fill the OpenPublicFolderByName operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	/* name is prefixed with 32 bit [size] */
+	request.name = name;
+	size += strlen(name) + 1 + sizeof (uint32_t);
+	
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenPublicFolderByName;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenPublicFolderByName = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_child, session);
+	mapi_object_set_handle(obj_child, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Sets a folder as the destination for incoming messages of
+   a particular message class.
+
+   \param obj_store the store to set the receive folder for
+   \param obj_folder the destination folder
+   \param lpszMessageClass the message class the folder will receive
+
+      \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_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa GetReceiveFolder, GetReceiveFolderTable
+ */
+_PUBLIC_ enum MAPISTATUS SetReceiveFolder(mapi_object_t *obj_store,
+					  mapi_object_t *obj_folder,
+					  const char *lpszMessageClass)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetReceiveFolder_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpszMessageClass, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetReceiveFolder");
+
+	/* Fill the SetReceiveFolder operation */
+	size = 0;
+	request.fid = mapi_object_get_id(obj_folder);
+	size += sizeof (uint64_t);
+	request.lpszMessageClass = lpszMessageClass;
+	size += strlen(lpszMessageClass) + 1;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetReceiveFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetReceiveFolder = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Gets the receive folder for incoming messages of a
+   particular message class.
+
+   This function obtains the folder that was established as the
+   destination for incoming messages of a specified message class, or
+   the default receive folder for the message store.
+
+   \param obj_store the store to get the receiver folder for
+   \param id_folder the resulting folder identification
+   \param MessageClass which message class to find the receivefolder
+   for
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize, OpenMsgStore, GetLastError, SetReceiveFolder,
+   GetReceiveFolderTable
+*/
+_PUBLIC_ enum MAPISTATUS GetReceiveFolder(mapi_object_t *obj_store, 
+					  mapi_id_t *id_folder,
+					  const char *MessageClass)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetReceiveFolder_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mem_ctx = talloc_named(NULL, 0, "GetReceiveFolder");
+
+	*id_folder = 0;
+
+	/* Fill the GetReceiveFolder operation */
+	if (!MessageClass) {
+		request.MessageClass = "";
+		size += 1;
+	} else {
+		request.MessageClass = MessageClass;
+		size += strlen (MessageClass) + 1;
+	}
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetReceiveFolder;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetReceiveFolder = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*id_folder = mapi_response->mapi_repl->u.mapi_GetReceiveFolder.folder_id;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the receive folder table which includes all the
+   information about the receive folders for the message store
+
+   \param obj_store the message store object
+   \param SRowSet pointer on a SRowSet structure with
+   GetReceiveFolderTable results.
+
+   Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when
+   they don't need the folder table data anymore.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetReceiveFolder, SetReceiveFolder
+ */
+_PUBLIC_ enum MAPISTATUS GetReceiveFolderTable(mapi_object_t *obj_store, 
+					       struct SRowSet *SRowSet)
+{
+	struct mapi_request			*mapi_request;
+	struct mapi_response			*mapi_response;
+	struct EcDoRpc_MAPI_REQ			*mapi_req;
+	struct GetReceiveFolderTable_repl	*reply;
+	struct mapi_session			*session;
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	uint32_t				size = 0;
+	TALLOC_CTX				*mem_ctx;
+	uint32_t				i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetReceiveFolderTable");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetReceiveFolderTable;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	reply = &mapi_response->mapi_repl->u.mapi_GetReceiveFolderTable;
+
+	/* Retrieve the ReceiveFolderTable entries */
+	SRowSet->cRows = reply->cValues;
+	SRowSet->aRow = talloc_array((TALLOC_CTX *)session, struct SRow, reply->cValues);
+	
+	for (i = 0; i < reply->cValues; i++) {
+		SRowSet->aRow[i].ulAdrEntryPad = 0;
+		SRowSet->aRow[i].cValues = 3;
+		SRowSet->aRow[i].lpProps = talloc_array((TALLOC_CTX *)SRowSet->aRow, struct SPropValue, 
+							SRowSet->aRow[i].cValues);
+
+		SRowSet->aRow[i].lpProps[0].ulPropTag = PR_FID;
+		SRowSet->aRow[i].lpProps[0].dwAlignPad = 0x0;
+		SRowSet->aRow[i].lpProps[0].value.d = reply->entries[i].fid;
+
+		SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
+		SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
+		SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup((TALLOC_CTX *)SRowSet->aRow, reply->entries[i].lpszMessageClass);
+	
+		SRowSet->aRow[i].lpProps[2].ulPropTag = PR_LAST_MODIFICATION_TIME;
+		SRowSet->aRow[i].lpProps[2].dwAlignPad = 0x0;
+		SRowSet->aRow[i].lpProps[2].value.ft.dwLowDateTime = reply->entries[i].modiftime.dwLowDateTime;
+		SRowSet->aRow[i].lpProps[2].value.ft.dwHighDateTime = reply->entries[i].modiftime.dwHighDateTime;
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieves the folder ID of the temporary transport folder.
+
+   \param obj_store the server object
+   \param FolderId pointer on the returning Folder identifier
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+ */
+_PUBLIC_ enum MAPISTATUS GetTransportFolder(mapi_object_t *obj_store,
+					    mapi_id_t *FolderId)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetTransportFolder_repl	*reply;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetTransportFolder");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetTransportFolder;
+	mapi_req->logon_id =0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve the FolderId parameter */
+	reply = &mapi_response->mapi_repl->u.mapi_GetTransportFolder;
+	*FolderId = reply->FolderId;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the list of servers that host replicas of a given
+   public folder.
+
+   \param obj_store the public folder store object
+   \param obj_folder the folder object we search replica for
+   \param OwningServersCount number of OwningServers
+   \param CheapServersCount number of low-cost servers
+   \param OwningServers pointer on the list of NULL terminated ASCII
+   string representing replica servers
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note ecNoReplicaAvailable (0x469) can be returned if no replica is
+   available for the folder.
+
+   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_CALL_FAILED: A network problem was encountered during the
+     transaction
+ */
+_PUBLIC_ enum MAPISTATUS GetOwningServers(mapi_object_t *obj_store,
+					  mapi_object_t *obj_folder,
+					  uint16_t *OwningServersCount,
+					  uint16_t *CheapServersCount,
+					  char **OwningServers)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct GetOwningServers_req	request;
+	struct GetOwningServers_repl	response;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+	mapi_id_t			FolderId;
+	uint32_t			i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OwningServersCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!CheapServersCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OwningServers, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	FolderId = mapi_object_get_id(obj_folder);
+	OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL);
+		
+	mem_ctx = talloc_named(NULL, 0, "GetOwningServers");
+	
+	size = 0;
+
+	/* Fill the GetOwningServers operation */
+	request.FolderId = FolderId;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetOwningServers;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_GetOwningServers = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve GetOwningServers response */
+	response = mapi_response->mapi_repl->u.mapi_GetOwningServers;
+
+	*OwningServersCount = response.OwningServersCount;
+	*CheapServersCount = response.CheapServersCount;
+	if (*OwningServersCount) {
+		OwningServers = talloc_array((TALLOC_CTX *)session, char *, *OwningServersCount + 1);
+		for (i = 0; i != *OwningServersCount; i++) {
+			OwningServers[i] = talloc_strdup((TALLOC_CTX *)OwningServers, response.OwningServers[i]);
+		}
+		OwningServers[i] = NULL;
+	} else {
+		OwningServers = NULL;
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Gets the current store state for the loggued user
+
+   \param obj_store the store object
+   \param StoreState pointer on the store state returned by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+ */
+_PUBLIC_ enum MAPISTATUS GetStoreState(mapi_object_t *obj_store,
+				       uint32_t *StoreState)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!StoreState, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetStoreState");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetStoreState;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve the StoreState */
+	*StoreState = mapi_response->mapi_repl->u.mapi_GetStoreState.StoreState;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieves the sending folder (OUTBOX) for a given store
+
+   This function obtains the folder that was established as the
+   destination for outgoing messages of a specified message class.
+
+   This function does not result in any network traffic.
+
+   \param obj_store the store to get the outbox folder for
+   \param outbox_id the resulting folder identification
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize, OpenMsgStore, GetLastError, GetDefaultFolder
+*/
+_PUBLIC_ enum MAPISTATUS GetOutboxFolder(mapi_object_t *obj_store, 
+					 mapi_id_t *outbox_id)
+{
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+
+	*outbox_id = ((mapi_object_store_t *)obj_store->private_data)->fid_outbox;
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IProfAdmin.c
===================================================================
--- trunk/openchange/libmapi/IProfAdmin.c	                        (rev 0)
+++ trunk/openchange/libmapi/IProfAdmin.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1399 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-2008.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <credentials.h>
+#include <ldb_errors.h>
+#include <ldb.h>
+
+/**
+   \file IProfAdmin.c
+
+   \brief MAPI Profiles interface
+ */
+
+/*
+ * Private functions
+ */
+
+/**
+ * Load a MAPI profile into a mapi_profile struct
+ */
+static enum MAPISTATUS ldb_load_profile(TALLOC_CTX *mem_ctx,
+					struct ldb_context *ldb_ctx,
+					struct mapi_profile *profile,
+					const char *profname, const char *password)
+{
+	int			ret;
+	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	struct ldb_result	*res;
+	struct ldb_message	*msg;
+	const char * const	attrs[] = { "*", NULL };
+
+	/* fills in profile name */
+	profile->profname = talloc_strdup(mem_ctx, profname);
+	if (!profile->profname) return MAPI_E_NOT_ENOUGH_RESOURCES;
+
+	/* ldb query */
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profile->profname);
+	if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND;
+
+	/* profile not found */
+	if (!res->count) return MAPI_E_NOT_FOUND;
+	/* more than one profile */
+	if (res->count > 1) return MAPI_E_COLLISION;
+
+	/* fills in profile with query result */
+	msg = res->msgs[0];
+
+	profile->username = ldb_msg_find_attr_as_string(msg, "username", NULL);
+	profile->password = password ? password : ldb_msg_find_attr_as_string(msg, "password", "");
+	profile->workstation = ldb_msg_find_attr_as_string(msg, "workstation", NULL);
+	profile->realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
+	profile->domain = ldb_msg_find_attr_as_string(msg, "domain", NULL);
+	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->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);
+	profile->language = ldb_msg_find_attr_as_int(msg, "language", 0);
+	profile->method = ldb_msg_find_attr_as_int(msg, "method", 0);
+
+	if (!profile->password) return MAPI_E_INVALID_PARAMETER;
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Search for and attribute within profiles
+ */
+static enum MAPISTATUS ldb_clear_default_profile(TALLOC_CTX *mem_ctx)
+{
+	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	struct ldb_context	*ldb_ctx;
+	struct ldb_dn		*basedn;
+	struct ldb_message	*msg;
+	struct ldb_result	*res;
+	const char		*attrs[] = { "PR_DEFAULT_PROFILE", NULL };
+	int			ret;
+	uint32_t       		i;
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles");
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, scope, attrs, "(cn=*)");
+	
+	if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND;
+	if (!res->count) return MAPI_E_NOT_FOUND;
+
+	for (i = 0; i < res->count; i++) {
+		struct ldb_message		*message;
+
+		msg = res->msgs[i];
+		if (msg->num_elements == 1) {
+			message = talloc_steal(mem_ctx, msg);
+			message->elements[0].flags = LDB_FLAG_MOD_DELETE;
+
+			ret = ldb_modify(ldb_ctx, message);
+			talloc_free(message);
+		}
+	}
+	
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Test if the password is correct
+ */
+static enum MAPISTATUS ldb_test_password(TALLOC_CTX *mem_ctx, const char *profile, 
+					 const char *password)
+{
+	enum ldb_scope		scope = LDB_SCOPE_DEFAULT;
+	struct ldb_context	*ldb_ctx;
+	struct ldb_message	*msg;
+	struct ldb_result	*res;
+	const char		*attrs[] = {"cn", "password", NULL };
+	const char		*ldb_password;
+	int			ret;
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+	
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, NULL, scope, attrs, 
+					 "(cn=%s)(cn=Profiles)", profile);
+
+	if (ret != LDB_SUCCESS) return MAPI_E_NO_SUPPORT;
+	if (!res->count) return MAPI_E_NOT_FOUND;
+	
+	msg = res->msgs[0];
+	
+	ldb_password = ldb_msg_find_attr_as_string(msg, "password", NULL);
+	if (!ldb_password) return MAPI_E_NO_SUPPORT;
+	if (strncmp(password, ldb_password, strlen(password))) return MAPI_E_LOGON_FAILED;
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * Add a profile to the database with default fields
+ */
+static enum MAPISTATUS ldb_create_profile(TALLOC_CTX *mem_ctx,
+					  struct ldb_context *ldb_ctx,
+					  const char *profname)
+{
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_message		msg;
+	struct ldb_message_element	el[2];
+	struct ldb_val			vals[2][1];
+	struct ldb_result		*res;
+	struct ldb_dn			*basedn;
+	char				*dn;
+	int				ret;
+	const char * const		attrs[] = { "*", NULL };
+
+	/* Sanity check */
+	if (profname == NULL) 
+		return MAPI_E_BAD_VALUE;
+
+	/* Does the profile already exists? */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), 
+					 scope, attrs, "(cn=%s)(cn=Profiles)", profname);
+	if (res->msgs) return MAPI_E_NO_ACCESS;
+
+	/*
+	 * We now prepare the entry for transaction
+	 */
+	
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname);
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+	if (!ldb_dn_validate(basedn)) return MAPI_E_BAD_VALUE;
+
+	msg.dn = ldb_dn_copy(mem_ctx, basedn);
+	msg.num_elements = 2;
+	msg.elements = el;
+
+	el[0].flags = 0;
+	el[0].name = talloc_strdup(mem_ctx, "cn");
+	el[0].num_values = 1;
+	el[0].values = vals[0];
+	vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, profname);
+	vals[0][0].length = strlen(profname);
+
+	el[1].flags = 0;
+	el[1].name = talloc_strdup(mem_ctx, "name");
+	el[1].num_values = 1;
+	el[1].values = vals[1];
+	vals[1][0].data = (uint8_t *)talloc_strdup(mem_ctx, profname);
+	vals[1][0].length = strlen(profname);
+
+	ret = ldb_add(ldb_ctx, &msg);
+
+	if (ret != LDB_SUCCESS) return MAPI_E_NO_SUPPORT;
+
+	return MAPI_E_SUCCESS;
+}
+
+/*
+ * delete the current profile
+ */
+static enum MAPISTATUS ldb_delete_profile(TALLOC_CTX *mem_ctx,
+					  struct ldb_context *ldb_ctx,
+					  const char *profname)
+{
+	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	struct ldb_result	*res;
+	const char * const	attrs[] = { "*", NULL };
+	int			ret;
+
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname);
+	if (!res->msgs) return MAPI_E_NOT_FOUND;
+
+	ret = ldb_delete(ldb_ctx, res->msgs[0]->dn);
+	if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND;
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Rename a profile
+
+   \param mem_ctx pointer on the memory context
+   \param old_profname the old profile name string
+   \param new_profname the new profile name string
+
+   \return MAPI_E_SUCCESS on success otherwise MAPI error.
+ */
+static enum MAPISTATUS ldb_rename_profile(TALLOC_CTX *mem_ctx, 
+					  const char *old_profname,
+					  const char *new_profname)
+{
+	int			ret;
+	struct ldb_context	*ldb_ctx;
+	struct ldb_dn		*old_dn;
+	struct ldb_dn		*new_dn;
+	char			*dn;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!old_profname, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!new_profname, MAPI_E_INVALID_PARAMETER, NULL);
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", old_profname);
+	old_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", new_profname);
+	new_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+
+	ret = ldb_rename(ldb_ctx, old_dn, new_dn);
+	OPENCHANGE_RETVAL_IF(ret, MAPI_E_CORRUPT_STORE, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * Public interface
+ */
+
+/**
+   \details Add an attribute to the profile
+ */
+_PUBLIC_ enum MAPISTATUS mapi_profile_add_string_attr(const char *profile, 
+						      const char *attr, 
+						      const char *value)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_message		msg;
+	struct ldb_message_element	el[1];
+	struct ldb_val			vals[1][1];
+	struct ldb_result		*res;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_dn			*basedn;
+	char				*dn;
+	int				ret;
+	const char * const		attrs[] = { "*", NULL };
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx->ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_BAD_VALUE, NULL);
+	OPENCHANGE_RETVAL_IF(!value, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_profile_add_string_attr");
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	/* Retrieve the profile from the database */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profile);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx);
+
+	/* Preparing for the transaction */
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profile);
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx);
+
+	msg.dn = ldb_dn_copy(mem_ctx, basedn);
+	msg.num_elements = 1;
+	msg.elements = el;
+
+	el[0].flags = LDB_FLAG_MOD_ADD;
+	el[0].name = talloc_strdup(mem_ctx, attr);
+	el[0].num_values = 1;
+	el[0].values = vals[0];
+	vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value);
+	vals[0][0].length = strlen(value);
+
+	ret = ldb_modify(ldb_ctx, &msg);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx);
+	
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Modify an attribute
+ */
+_PUBLIC_ enum MAPISTATUS mapi_profile_modify_string_attr(const char *profname, 
+							 const char *attr, 
+							 const char *value)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_message		msg;
+	struct ldb_message_element	el[1];
+	struct ldb_val			vals[1][1];
+	struct ldb_result		*res;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_dn			*basedn;
+	char				*dn;
+	int				ret;
+	const char * const		attrs[] = { "*", NULL };
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profname, MAPI_E_BAD_VALUE, NULL);
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+	mem_ctx = talloc_named(NULL, 0, "mapi_profile_modify_string_attr");
+
+	/* Retrieve the profile from the database */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx);
+
+	/* Preparing for the transaction */
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname);
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx);
+
+	msg.dn = ldb_dn_copy(mem_ctx, basedn);
+	msg.num_elements = 1;
+	msg.elements = el;
+
+	el[0].flags = LDB_FLAG_MOD_REPLACE;
+	el[0].name = talloc_strdup(mem_ctx, attr);
+	el[0].num_values = 1;
+	el[0].values = vals[0];
+	vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value);
+	vals[0][0].length = strlen(value);
+
+	ret = ldb_modify(ldb_ctx, &msg);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx);
+
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Delete an attribute
+ */
+_PUBLIC_ enum MAPISTATUS mapi_profile_delete_string_attr(const char *profname, 
+							 const char *attr, 
+							 const char *value)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_message		msg;
+	struct ldb_message_element	el[1];
+	struct ldb_val			vals[1][1];
+	struct ldb_result		*res;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_dn			*basedn;
+	char				*dn;
+	int				ret;
+	const char * const		attrs[] = { "*", NULL };
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profname, MAPI_E_BAD_VALUE, NULL);
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+	mem_ctx = talloc_named(NULL, 0, "mapi_profile_delete_string_attr");
+
+	/* Retrieve the profile from the database */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, "(cn=%s)(cn=Profiles)", profname);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_BAD_VALUE, mem_ctx);
+
+	/* Preparing for the transaction */
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profname);
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+	OPENCHANGE_RETVAL_IF(!ldb_dn_validate(basedn), MAPI_E_BAD_VALUE, mem_ctx);
+
+	msg.dn = ldb_dn_copy(mem_ctx, basedn);
+	msg.num_elements = 1;
+	msg.elements = el;
+
+	el[0].flags = LDB_FLAG_MOD_DELETE;
+	el[0].name = talloc_strdup(mem_ctx, attr);
+	el[0].num_values = 1;
+	el[0].values = vals[0];
+	vals[0][0].data = (uint8_t *)talloc_strdup(mem_ctx, value);
+	vals[0][0].length = strlen(value);
+
+	ret = ldb_modify(ldb_ctx, &msg);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_SUPPORT, mem_ctx);
+
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+/*
+ * Private function which opens the profile store
+ * Should only be called within MAPIInitialize
+ */
+enum MAPISTATUS OpenProfileStore(TALLOC_CTX *mem_ctx, struct ldb_context **ldb_ctx, 
+				 const char *profiledb)
+{
+	int			ret;
+	struct ldb_context	*tmp_ctx;
+	struct tevent_context	*ev;
+	
+	*ldb_ctx = 0;
+	
+	/* store path */
+	if (!profiledb) return MAPI_E_NOT_FOUND;
+
+	ev = tevent_context_init(mem_ctx);
+	if (!ev) return MAPI_E_NOT_ENOUGH_RESOURCES;
+
+	/* connect to the store */
+	tmp_ctx = ldb_init(mem_ctx, ev);
+	if (!tmp_ctx) return MAPI_E_NOT_ENOUGH_RESOURCES;
+
+	ret = ldb_connect(tmp_ctx, profiledb, 0, NULL);
+	if (ret != LDB_SUCCESS) return MAPI_E_NOT_FOUND;
+
+	*ldb_ctx = tmp_ctx;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get default ldif_path
+
+   This function returns the path for the default LDIF files.
+
+   \sa CreateProfileStore
+*/
+_PUBLIC_ const char *mapi_profile_get_ldif_path(void)
+{
+	return DEFAULT_LDIF;
+}
+
+
+/**
+   \details Create a profile database
+   
+   This function creates a new profile database, including doing an
+   initial setup.
+
+   \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.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ 
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_CALL_FAILED: profiledb or ldif_path is not set
+   - MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed
+   - MAPI_E_NO_ACCESS: connection or ldif add failed
+
+   \sa GetLastError, mapi_profile_get_ldif_path
+*/
+_PUBLIC_ enum MAPISTATUS CreateProfileStore(const char *profiledb, const char *ldif_path)
+{
+	int			ret;
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_context	*ldb_ctx;
+	struct ldb_ldif		*ldif;
+	char			*url = NULL;
+	char			*filename = NULL;
+	FILE			*f;
+	struct tevent_context	*ev;
+
+	OPENCHANGE_RETVAL_IF(!profiledb, MAPI_E_CALL_FAILED, NULL);
+	OPENCHANGE_RETVAL_IF(!ldif_path, MAPI_E_CALL_FAILED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateProfileStore");
+
+	ev = tevent_context_init(mem_ctx);
+	OPENCHANGE_RETVAL_IF(!ev, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	ldb_ctx = ldb_init(mem_ctx, ev);
+	OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	url = talloc_asprintf(mem_ctx, "tdb://%s", profiledb);
+	ret = ldb_connect(ldb_ctx, url, 0, 0);
+	talloc_free(url);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NO_ACCESS, mem_ctx);
+
+	filename = talloc_asprintf(mem_ctx, "%s/oc_profiles_init.ldif", ldif_path);
+	f = fopen(filename, "r");
+	OPENCHANGE_RETVAL_IF(!f, MAPI_E_NO_ACCESS, mem_ctx);
+	talloc_free(filename);
+
+	while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
+		ldif->msg = ldb_msg_canonicalize(ldb_ctx, ldif->msg);
+		ret = ldb_add(ldb_ctx, ldif->msg);
+		if (ret != LDB_SUCCESS) {
+			fclose(f);
+			OPENCHANGE_RETVAL_ERR(MAPI_E_NO_ACCESS, mem_ctx);
+		}
+		ldb_ldif_read_free(ldb_ctx, ldif);
+	}
+	fclose(f);
+
+	filename = talloc_asprintf(mem_ctx, "%s/oc_profiles_schema.ldif", ldif_path);
+	f = fopen(filename, "r");
+	OPENCHANGE_RETVAL_IF(!f, MAPI_E_NO_ACCESS, mem_ctx);
+
+	talloc_free(filename);
+	while ((ldif = ldb_ldif_read_file(ldb_ctx, f))) {
+		ldif->msg = ldb_msg_canonicalize(ldb_ctx, ldif->msg);
+		ret = ldb_add(ldb_ctx, ldif->msg);
+		if (ret != LDB_SUCCESS) {
+			fclose(f);
+			OPENCHANGE_RETVAL_ERR(MAPI_E_NO_ACCESS, mem_ctx);
+		}
+
+		ldb_ldif_read_free(ldb_ctx, ldif);
+	}
+	fclose(f);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Load a profile from the database
+
+   This function opens a named profile from the database, and fills
+   the mapi_profile structure with common profile information.
+
+   \param profile the resulting profile
+   \param profname the name of the profile to open
+   \param password the password to use with the profile
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_ENOUGH_RESOURCES: ldb subsystem initialization failed
+   - MAPI_E_NOT_FOUND: the profile was not found in the profile
+     database
+   - MAPI_E_COLLISION: profname matched more than one entry
+
+   \sa MAPIInitialize, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS OpenProfile(struct mapi_profile *profile, const char *profname, const char *password)
+{
+	TALLOC_CTX	*mem_ctx;
+	enum MAPISTATUS	retval;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = (TALLOC_CTX *) global_mapi_ctx->session;
+	
+	/* find the profile in ldb store */
+	retval = ldb_load_profile(mem_ctx, global_mapi_ctx->ldb_ctx, profile, profname, password);
+
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;	
+}
+
+/**
+   \details Load a MAPI Profile and sets its credentials
+
+   This function loads a named MAPI profile and sets the MAPI session
+   credentials.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The profile parameter is not
+     initialized
+   - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to perform the operation
+
+   \sa OpenProfile, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS LoadProfile(struct mapi_profile *profile)
+{
+	TALLOC_CTX *mem_ctx;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = (TALLOC_CTX *) global_mapi_ctx->session;
+
+	profile->credentials = cli_credentials_init(mem_ctx);
+	OPENCHANGE_RETVAL_IF(!profile->credentials, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+	cli_credentials_set_username(profile->credentials, profile->username, CRED_SPECIFIED);
+	cli_credentials_set_password(profile->credentials, profile->password, CRED_SPECIFIED);
+	cli_credentials_set_workstation(profile->credentials, profile->workstation, CRED_SPECIFIED);
+	cli_credentials_set_realm(profile->credentials, profile->realm, CRED_SPECIFIED);
+	cli_credentials_set_domain(profile->credentials, profile->domain, CRED_SPECIFIED);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Release a profile
+
+   This function releases the credentials associated with the profile.
+
+   \param profile the profile to release.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: The profile parameter was not set or
+     not valid
+ */
+_PUBLIC_ enum MAPISTATUS ShutDown(struct mapi_profile *profile)
+{
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL);
+
+	if (profile->credentials) 
+		talloc_free(profile->credentials);
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Create a profile in the MAPI profile database
+
+   This function creates a profile named \a profile in the MAPI profile
+   database and sets the specified username in that profile.
+
+   This function may also set the password. If the flags include
+   OC_PROFILE_NOPASSWORD then the password will not be set. Otherwise,
+   the specified password argument will also be saved to the profile.
+
+   \param profile the name of the profile
+   \param username the username of the profile
+   \param password the password for the profile (if used)
+   \param flag the union of the flags. 
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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. The MAPI subsystem must be initialized (using
+     MAPIInitialize) prior to creating a profile.
+   - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   - MAPI_E_NO_SUPPORT: An error was encountered while setting the
+     MAPI profile attributes in the database.
+
+   \note profile information (including the password, if saved to the
+   profile) is stored unencrypted.
+
+   \sa DeleteProfile, SetDefaultProfile, GetDefaultProfile,
+   ChangeProfilePassword, GetProfileTable, ProcessNetworkProfile,
+   GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS CreateProfile(const char *profile, const char *username,
+				       const char *password, uint32_t flag)
+{
+	enum MAPISTATUS retval;
+	TALLOC_CTX	*mem_ctx;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CreateProfile");
+	retval = ldb_create_profile(mem_ctx, global_mapi_ctx->ldb_ctx, profile);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = mapi_profile_add_string_attr(profile, "username", username);
+	if (flag != OC_PROFILE_NOPASSWORD) {
+		retval = mapi_profile_add_string_attr(profile, "password", password);
+	}
+	talloc_free(mem_ctx);
+
+	return retval;
+}
+
+
+/**
+   \details Delete a profile from the MAPI profile database
+
+   \param profile the name of the profile to delete
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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. The MAPI subsystem must be initialized (using
+     MAPIInitialize) prior to creating a profile.
+   - MAPI_E_NOT_FOUND: The profile was not found in the database.
+
+   \sa CreateProfile, ChangeProfilePassword, GetProfileTable,
+   GetProfileAttr, ProcessNetworkProfile, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS DeleteProfile(const char *profile)
+{
+	TALLOC_CTX	*mem_ctx;
+	enum MAPISTATUS	retval;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "DeleteProfile");
+	retval = ldb_delete_profile(mem_ctx, global_mapi_ctx->ldb_ctx, profile);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	talloc_free(mem_ctx);
+
+	return retval;
+}
+
+
+/**
+   \details Change the profile password of an existing MAPI profile
+
+   \param profile the name of the profile to have its password changed
+   \param old_password the old password
+   \param password the new password
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: One of the following argument was not
+     set: profile, old_password, password
+   - MAPI_E_NOT_FOUND: The profile was not found in the database
+
+   \sa CreateProfile, GetProfileTable, GetProfileAttr,
+   ProcessNetworkProfile, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS ChangeProfilePassword(const char *profile, 
+					       const char *old_password,
+					       const char *password)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+
+	if (!profile || !old_password | !password) return MAPI_E_INVALID_PARAMETER;
+
+	mem_ctx = talloc_named(NULL, 0, "ChangeProfilePassword");
+
+	retval = ldb_test_password(mem_ctx, profile, password);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = mapi_profile_modify_string_attr(profile, "password", password);
+	
+	talloc_free(mem_ctx);
+	return retval;
+}
+
+
+/**
+   \details Rename a profile
+
+   \param old_profile old profile name
+   \param profile new profile name
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS RenameProfile(const char *old_profile, 
+				       const char *profile)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct SRowSet		proftable;
+	struct SPropValue	*lpProp;
+	struct ldb_message	*msg = NULL;
+	bool			found = false;
+	char			*dn = NULL;
+	int			ret;
+	int			i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!old_profile, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = global_mapi_ctx->mem_ctx;
+
+	retval = GetProfileTable(&proftable);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 1. Check if old profile exists */
+	for (found = false, i = 0; i < proftable.cRows; i++) {
+		lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME);
+		if (lpProp && !strcmp(lpProp->value.lpszA, old_profile)) {
+			found = true;
+		}
+	}
+	OPENCHANGE_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, proftable.aRow);
+
+	/* Step 2. Check if new profile already exists */
+	for (found = false, i = 0; i < proftable.cRows; i++) {
+		lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME);
+		if (lpProp && !strcmp(lpProp->value.lpszA, profile)) {
+			found = true;
+		}
+	}
+	talloc_free(proftable.aRow);
+	OPENCHANGE_RETVAL_IF(found == true, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Step 3. Rename the profile */
+	retval = ldb_rename_profile(mem_ctx, old_profile, profile);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 4. Change name and cn */
+	msg = ldb_msg_new(mem_ctx);
+	dn = talloc_asprintf(mem_ctx, "CN=%s,CN=Profiles", profile);
+	msg->dn = ldb_dn_new(mem_ctx, global_mapi_ctx->ldb_ctx, dn);
+	talloc_free(dn);
+
+	ret = ldb_msg_add_string(msg, "cn", profile);
+	ret = ldb_msg_add_string(msg, "name", profile);
+	for (i = 0; i < msg->num_elements; i++) {
+		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+	}
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, NULL);
+	ret = ldb_modify(global_mapi_ctx->ldb_ctx, msg);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set a default profile for the database
+
+   \param profname the name of the profile to make the default profile
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The profile parameter was not set
+     properly.
+   - MAPI_E_NOT_FOUND: The profile was not found in the database
+
+   \sa GetDefaultProfile, GetProfileTable, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS SetDefaultProfile(const char *profname)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_profile	profile;
+	enum MAPISTATUS		retval;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profname, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetDefaultProfile");
+
+	/* open profile */
+	retval = ldb_load_profile(mem_ctx, global_mapi_ctx->ldb_ctx, &profile, profname, NULL);
+	OPENCHANGE_RETVAL_IF(retval && retval != MAPI_E_INVALID_PARAMETER, retval, mem_ctx);
+
+	/* search any previous default profile and unset it */
+	retval = ldb_clear_default_profile(mem_ctx);
+
+	/* set profname as the default profile */
+	retval = mapi_profile_modify_string_attr(profname, "PR_DEFAULT_PROFILE", "1");
+
+	talloc_free(mem_ctx);
+
+	return retval;
+}
+
+
+/**
+   \details Get the default profile from the database
+
+   \param profname the result of the function (name of the default
+   profile)
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_NOT_FOUND: The profile was not found in the database
+
+   \note On success GetDefaultProfile profname string is allocated. It
+   is up to the developer to free it when not needed anymore.
+
+   \sa SetDefaultProfile, GetProfileTable, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetDefaultProfile(char **profname)
+{
+	enum MAPISTATUS		retval;
+	struct SRowSet		proftable;
+	struct SPropValue	*lpProp;
+	uint32_t		i;
+	
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	
+	retval = GetProfileTable(&proftable);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	for (i = 0; i < proftable.cRows; i++) {
+		lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DEFAULT_PROFILE);
+		if (lpProp && (lpProp->value.l == 1)) {
+			lpProp = get_SPropValue_SRow(&(proftable.aRow[i]), PR_DISPLAY_NAME);
+			if (lpProp) {
+			  *profname = talloc_strdup(global_mapi_ctx->mem_ctx, lpProp->value.lpszA);
+				talloc_free(proftable.aRow);
+				return MAPI_E_SUCCESS;
+			}
+		}
+	}
+	
+	OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, proftable.aRow);
+}
+
+
+/**
+   \details Retrieve the profile table
+
+   This function retrieves the profile table. Two fields are returned:
+   - PR_DISPLAY_NAME: The profile name stored as a UTF8 string
+   - PR_DEFAULT_PROFILE: Whether the profile is the default one(1) or
+     not(0), stored as an integer
+
+   \param proftable the result of the call
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_NOT_FOUND: The profile was not found in the database
+
+   \sa SetDefaultProfile, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS GetProfileTable(struct SRowSet *proftable)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_result		*res;
+	struct ldb_message		*msg;
+	struct ldb_dn			*basedn;
+	const char			*attrs[] = {"cn", "PR_DEFAULT_PROFILE", NULL};
+	int				ret;
+	uint32_t			count;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+	mem_ctx = talloc_autofree_context();
+
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles");
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, scope, attrs, "(cn=*)");
+	talloc_free(basedn);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, NULL);
+
+	/* Allocate Arow */
+	proftable->cRows = res->count;
+	proftable->aRow = talloc_array(global_mapi_ctx->mem_ctx, struct SRow, res->count);
+
+	/* Build Arow array */
+	for (count = 0; count < res->count; count++) {
+		msg = res->msgs[count];
+		
+		proftable->aRow[count].lpProps = talloc_array((TALLOC_CTX *)proftable->aRow, struct SPropValue, 2);
+		proftable->aRow[count].cValues = 2;
+
+		proftable->aRow[count].lpProps[0].ulPropTag = PR_DISPLAY_NAME;
+		proftable->aRow[count].lpProps[0].value.lpszA = talloc_strdup((TALLOC_CTX *)proftable->aRow, 
+									      ldb_msg_find_attr_as_string(msg, "cn", NULL));
+									      
+		proftable->aRow[count].lpProps[1].ulPropTag = PR_DEFAULT_PROFILE;
+		proftable->aRow[count].lpProps[1].value.l = ldb_msg_find_attr_as_int(msg, "PR_DEFAULT_PROFILE", 0);
+	}
+
+	talloc_free(res);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve attribute values from a profile
+
+   This function retrieves all the attribute values from the given
+   profile.  The number of results is stored in \a count and values
+   are stored in an allocated string array in the \a value parameter
+   that needs to be free'd using MAPIFreeBuffer().
+   
+   \param profile the name of the profile to retrieve attributes from
+   \param attribute the attribute(s) to search for
+   \param count the number of results
+   \param value the resulting values
+   
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: Either profile or attribute was not set
+     properly
+   - MAPI_E_NOT_FOUND: The profile was not found in the database
+
+   \sa SetDefaultProfile, GetDefaultProfile, MAPIFreeBuffer,
+   GetProfileTable, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetProfileAttr(struct mapi_profile *profile, 
+					const char *attribute, 
+					unsigned int *count,
+					char ***value)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_result		*res;
+	struct ldb_message		*msg;
+	struct ldb_message_element	*ldb_element;
+	struct ldb_dn			*basedn;
+	const char			*attrs[] = {"*", NULL};
+	int				ret;
+	uint32_t       			i;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!attribute, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = (TALLOC_CTX *)global_mapi_ctx->ldb_ctx;
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles");
+
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "(cn=%s)", profile->profname);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, NULL);
+
+	msg = res->msgs[0];
+	ldb_element = ldb_msg_find_element(msg, attribute);
+	if (!ldb_element) {
+		DEBUG(3, ("ldb_msg_find_element: NULL\n"));
+		return MAPI_E_NOT_FOUND;
+	}
+
+	*count = ldb_element[0].num_values;
+	value[0] = talloc_array(mem_ctx, char *, *count);
+
+	if (*count == 1) {
+		value[0][0] = talloc_strdup(value[0], 
+						ldb_msg_find_attr_as_string(msg, attribute, NULL));
+	} else {
+		for (i = 0; i < *count; i++) {
+			value[0][i] = talloc_strdup(mem_ctx, (char *)ldb_element->values[i].data);
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details Search the value of an attribute within a given profile
+ */
+_PUBLIC_ enum MAPISTATUS FindProfileAttr(struct mapi_profile *profile, const char *attribute, const char *value)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_context		*ldb_ctx;
+	struct ldb_result		*res;
+	struct ldb_message		*msg;
+	struct ldb_message_element	*ldb_element;
+	struct ldb_val			val;
+	struct ldb_dn			*basedn;
+	const char			*attrs[] = {"*", NULL};
+	int				ret;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!profile, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!attribute, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!value, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = (TALLOC_CTX *)global_mapi_ctx->ldb_ctx;
+	ldb_ctx = global_mapi_ctx->ldb_ctx;
+
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, "CN=Profiles");
+
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "(CN=%s)", profile->profname);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!res->count, MAPI_E_NOT_FOUND, NULL);
+
+	msg = res->msgs[0];
+	ldb_element = ldb_msg_find_element(msg, attribute);
+	OPENCHANGE_RETVAL_IF(!ldb_element, MAPI_E_NOT_FOUND, NULL);
+
+	val.data = (uint8_t *)talloc_strdup(mem_ctx, value);
+	val.length = strlen(value);
+	OPENCHANGE_RETVAL_IF(!ldb_msg_find_val(ldb_element, &val), MAPI_E_NOT_FOUND, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   Create the profile 
+ */
+
+static bool set_profile_attribute(const char *profname, struct SRowSet rowset, 
+				  uint32_t index, uint32_t property, const char *attr)
+{
+	struct SPropValue	*lpProp;
+	enum MAPISTATUS		ret;
+
+	lpProp = get_SPropValue_SRow(&(rowset.aRow[index]), property);
+
+	if (!lpProp) {
+		DEBUG(3, ("MAPI Property %s not set\n", attr));
+		return true;
+	}
+
+	ret = mapi_profile_add_string_attr(profname, attr, lpProp->value.lpszA);
+
+	if (ret != MAPI_E_SUCCESS) {
+		DEBUG(3, ("Problem adding attribute %s in profile %s\n", attr, profname));
+		return false;
+	}
+	return true;
+}
+
+static bool set_profile_mvstr_attribute(const char *profname, struct SRowSet rowset,
+					uint32_t index, uint32_t property, const char *attr)
+{
+	struct SPropValue	*lpProp;
+	enum MAPISTATUS		ret;
+	uint32_t       		i;
+
+	lpProp = get_SPropValue_SRow(&(rowset.aRow[index]), property);
+
+	if (!lpProp) {
+		DEBUG(3, ("MAPI Property %s not set\n", attr));
+		return true;
+	}
+
+	for (i = 0; i < lpProp->value.MVszA.cValues; i++) {
+		ret = mapi_profile_add_string_attr(profname, attr, lpProp->value.MVszA.lppszA[i]);
+		if (ret != MAPI_E_SUCCESS) {
+			DEBUG(3, ("Problem adding attribute %s in profile %s\n", attr, profname));
+			return false;
+		}
+	}
+	return true;
+}
+
+
+/**
+   \details Process a full and automated MAPI profile creation
+
+   This function process a full and automated MAPI profile creation
+   using the \a username pattern passed as a parameter. The functions
+   takes a callback parameter which will be called when the username
+   checked matches several usernames. Private data needed by the
+   callback can be supplied using the private_data pointer.
+
+   \code
+   typedef int (*mapi_callback_t) callback(struct SRowSet *, void *private_data);
+   \endcode
+   
+   The callback returns the SRow element index within the SRowSet
+   structure.  If the user cancels the operation the callback return
+   value should be SRowSet->cRows or more.
+
+   \param session the session context
+   \param username the username for the network profile
+   \param callback function pointer callback function
+   \param private_data context data that will be provided to the callback
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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. The MAPI subsystem must be initialized (using
+     MAPIInitialize) prior to creating a profile.
+   - MAPI_E_END_OF_SESSION: The NSPI session has not been initialized
+   - MAPI_E_CANCEL_USER: The user has aborted the operation
+   - MAPI_E_INVALID_PARAMETER: The profile parameter was not set
+     properly.
+   - MAPI_E_NOT_FOUND: One of the mandatory field was not found during
+     the profile creation process.
+
+   \sa OpenProfileStore, MAPILogonProvider, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS ProcessNetworkProfile(struct mapi_session *session, const char *username,
+					       mapi_profile_callback_t callback, const void *private_data)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct Restriction_r	Filter;
+	struct SRowSet		*SRowSet;
+	struct SPropValue	*lpProp = NULL;
+	struct SPropTagArray	*MIds = NULL;
+	struct SPropTagArray	MIds2;
+	struct SPropTagArray	*MId_server = NULL;
+	struct StringsArray_r	pNames;
+	const char		*profname;
+	uint32_t		instance_key = 0;
+	uint32_t		index = 0;
+
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL);
+	
+	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);
+	MAPIFreeBuffer(SRowSet);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0xc,
+					  PR_DISPLAY_NAME,
+					  PR_OFFICE_TELEPHONE_NUMBER,
+					  PR_OFFICE_LOCATION,
+					  PR_TITLE,
+					  PR_COMPANY_NAME,
+					  PR_ACCOUNT,
+					  PR_ADDRTYPE,
+					  PR_ENTRYID,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_INSTANCE_KEY,
+					  PR_EMAIL_ADDRESS
+					  );
+
+	/* Retrieve the username to match */
+	if (!username) {
+		username = cli_credentials_get_username(nspi->cred);
+		OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+	}
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(nspi->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_ANR_UNICODE;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszW = username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(lpProp);
+	if (retval != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		MAPIFreeBuffer(SRowSet);
+		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);
+
+	/* 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);
+		instance_key = MIds->aulPropTag[index];
+	} else {
+		instance_key = MIds->aulPropTag[0];
+	}
+	MAPIFreeBuffer(MIds);
+	
+	MIds2.cValues = 0x1;
+	MIds2.aulPropTag = &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,
+					  PR_DISPLAY_NAME,
+					  PR_EMAIL_ADDRESS,
+					  PR_DISPLAY_TYPE,
+					  PR_EMS_AB_HOME_MDB,
+					  PR_ATTACH_NUM,
+					  PR_PROFILE_HOME_SERVER_ADDRS,
+					  PR_EMS_AB_PROXY_ADDRESSES
+					  );
+
+	nspi->pStat->CurrentRec = 0x0;
+	nspi->pStat->Delta = 0x0;
+	nspi->pStat->NumPos = 0x0;
+	nspi->pStat->TotalRecs = 0x1;
+
+	MAPIFreeBuffer(SRowSet);
+	SRowSet = talloc(nspi->mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi, SPropTagArray, &MIds2, 1, &SRowSet);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	lpProp = get_SPropValue_SRowSet(SRowSet, PR_EMS_AB_HOME_MDB);
+	OPENCHANGE_RETVAL_IF(!lpProp, MAPI_E_NOT_FOUND, NULL);
+
+	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);
+	
+	OPENCHANGE_RETVAL_IF(!nspi->org_unit, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!nspi->org, MAPI_E_INVALID_PARAMETER, NULL);
+
+	retval = mapi_profile_add_string_attr(profname, "Organization", nspi->org);
+	retval = mapi_profile_add_string_attr(profname, "OrganizationUnit", nspi->org_unit);
+
+	nspi->servername = x500_get_servername(lpProp->value.lpszA);
+	mapi_profile_add_string_attr(profname, "ServerName", nspi->servername);
+	set_profile_attribute(profname, *SRowSet, 0, PR_EMS_AB_HOME_MDB, "HomeMDB");
+	set_profile_mvstr_attribute(profname, *SRowSet, 0, PR_EMS_AB_PROXY_ADDRESSES, "ProxyAddress");
+	MAPIFreeBuffer(SRowSet);
+
+	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, 
+							   nspi->org, nspi->org_unit, 
+							   nspi->servername);
+	MId_server = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
+	retval = nspi_DNToMId(nspi, &pNames, &MId_server);
+	MAPIFreeBuffer((char *)pNames.Strings[0]);
+	MAPIFreeBuffer((char **)pNames.Strings);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	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);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(MId_server);
+	if (retval != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(SRowSet);
+		return retval;
+	}
+
+	set_profile_mvstr_attribute(profname, *SRowSet, 0, PR_EMS_AB_NETWORK_ADDRESS, "NetworkAddress");
+	MAPIFreeBuffer(SRowSet);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IStoreFolder.c
===================================================================
--- trunk/openchange/libmapi/IStoreFolder.c	                        (rev 0)
+++ trunk/openchange/libmapi/IStoreFolder.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,162 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IStoreFolder.c
+ 
+   \brief Open messages
+*/
+
+
+/**
+   \details Opens a specific message and retrieves a MAPI object that
+   can be used to get or set message properties.
+
+   This function opens a specific message defined by a combination of
+   object store, folder ID, and message ID and which read/write access
+   is defined by ulFlags.
+
+   \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
+
+   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
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: obj_store is undefined
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa MAPIInitialize, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS OpenMessage(mapi_object_t *obj_store, 
+				     mapi_id_t id_folder, 
+				     mapi_id_t id_message, 
+				     mapi_object_t *obj_message,
+				     uint8_t ulFlags)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct OpenMessage_req		request;
+	struct OpenMessage_repl		*reply;
+	struct mapi_session		*session;
+	mapi_object_message_t		*message;
+	struct SPropValue		lpProp;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			i = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenMessage");
+
+	/* Fill the OpenMessage operation */
+	request.handle_idx = 0x1;
+	request.CodePageId = 0xfff;
+	request.FolderId = id_folder;
+	request.OpenModeFlags = ulFlags;
+	request.MessageId = id_message;
+	size = sizeof (uint8_t) + sizeof(uint16_t) + sizeof(mapi_id_t) + sizeof(uint8_t) + sizeof(mapi_id_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenMessage = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_message, session);
+	mapi_object_set_handle(obj_message, mapi_response->handles[1]);
+
+	/* Store OpenMessage reply data */
+	reply = &mapi_response->mapi_repl->u.mapi_OpenMessage;
+
+	message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t);
+	message->cValues = reply->RecipientColumns.cValues;
+	message->SRowSet.cRows = reply->RowCount;
+	message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
+
+	message->SPropTagArray.cValues = reply->RecipientColumns.cValues;
+	message->SPropTagArray.aulPropTag = reply->RecipientColumns.aulPropTag;
+
+	for (i = 0; i < reply->RowCount; i++) {
+		emsmdb_get_SRow((TALLOC_CTX *)message, global_mapi_ctx->lp_ctx,
+				&(message->SRowSet.aRow[i]), &message->SPropTagArray, 
+				reply->recipients[i].RecipientRow.prop_count,
+				&reply->recipients[i].RecipientRow.prop_values,
+				reply->recipients[i].RecipientRow.layout, 1);
+
+		lpProp.ulPropTag = PR_RECIPIENT_TYPE;
+		lpProp.value.l = reply->recipients[i].RecipClass;
+		SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
+
+		lpProp.ulPropTag = PR_INTERNET_CPID;
+		lpProp.value.l = reply->recipients[i].codepage;
+		SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
+	}
+
+	/* add SPropTagArray elements we automatically append to SRow */
+	SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE);
+	SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID);
+
+	obj_message->private_data = (void *) message;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IStream.c
===================================================================
--- trunk/openchange/libmapi/IStream.c	                        (rev 0)
+++ trunk/openchange/libmapi/IStream.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,704 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IStream.c
+
+   \brief Functions for operating on Streams on MAPI objects
+ */
+
+
+/**
+   \details Open a stream
+
+   This function opens a stream on the property \a prop set in \a
+   obj_related with access flags set to \a access_flags and returns an
+   object \a obj_stream.
+
+   \param obj_related the object to open.
+   \param PropertyTag the property name for the object to create a stream
+   for.
+   \param OpenModeFlags sets the access mode for the stream and is one
+   of the following values:
+   * 0x0: ReadOnly
+   * 0x1: ReadWrite
+   * 0x2: Create
+   * 0x3: BestAccess
+   \param obj_stream the resulting stream object.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. 
+
+   \sa ReadStream, WriteStream, GetLastError
+ */
+
+_PUBLIC_ enum MAPISTATUS OpenStream(mapi_object_t *obj_related, uint32_t PropertyTag,
+				    uint8_t OpenModeFlags, mapi_object_t *obj_stream)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct OpenStream_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	session = mapi_object_get_session(obj_related);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "OpenStream");
+
+	size = 0;
+
+	/* Fill the OpenStream operation */
+	request.handle_idx = 0x1;
+	request.PropertyTag = PropertyTag;
+
+	/* STGM_XXX (obj_base.h windows header) */
+	request.OpenModeFlags = OpenModeFlags;
+	size += sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_OpenStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_OpenStream = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Set object session and handle */
+	mapi_object_set_session(obj_stream, session);
+	mapi_object_set_handle(obj_stream, mapi_response->handles[1]);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Read buffer from a stream
+
+   This function reads from an open data stream. It will read up to
+   ByteCount bytes from the stream, and return the data in data_buf.
+   ByteRead is set to the number of bytes actually read.
+
+   \param obj_stream the opened stream object
+   \param buf_data the buffer where data read from the stream will be
+   stored
+   \param ByteCount the number of bytes requested to be read from the
+   stream
+   \param ByteRead the number of bytes read from the stream
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. 
+
+   \note The data size intended to be read from the stream shouldn't
+   extend a maximum size each time you call ReadStream. This size
+   depends on Exchange server version. However 0x1000 is known to be a
+   reliable read size value.
+
+   \sa OpenStream, WriteStream, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS ReadStream(mapi_object_t *obj_stream, unsigned char *buf_data, 
+				    uint16_t ByteCount, uint16_t *ByteRead)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct ReadStream_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ReadStream");
+
+	*ByteRead = 0;
+	size = 0;
+
+	/* Fill the ReadStream operation */
+	request.ByteCount = ByteCount;
+	size += sizeof(uint16_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_ReadStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_ReadStream = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 1;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* copy no more than sz_data into buffer */
+	*ByteRead = mapi_response->mapi_repl->u.mapi_ReadStream.data.length;
+	if (*ByteRead > 0) {
+		if (*ByteRead > ByteCount) {
+			*ByteRead = ByteCount;
+		}
+		memcpy(buf_data, mapi_response->mapi_repl->u.mapi_ReadStream.data.data, *ByteRead);
+	}
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Write buffer to the stream
+
+   This function writes the stream specified as a DATA_BLOB in data to
+   the stream obj_stream.
+
+   \param obj_stream the opened stream object
+   \param blob the DATA_BLOB to write to the stream
+   \param WrittenSize the actual number of bytes written to the
+   stream
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error. 
+
+   \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
+     context, or blob was null.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+   - MAPI_E_TOO_BIG: the data blob was too large to process
+
+   \note The data size intended to be written to the stream should not
+   exceed a maximum size each time you call WriteStream. This size
+   depends on Exchange server version. However 0x1000 is known to be a
+   reliable write size value.
+
+   \sa OpenStream, ReadStream, GetLastError
+  */
+_PUBLIC_ enum MAPISTATUS WriteStream(mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct WriteStream_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size;
+
+	/* Sanity Checks */
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!blob, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(blob->length > 0x7000, MAPI_E_TOO_BIG, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "WriteStream");
+
+	size = 0;
+
+	/* Fill the WriteStream operation */
+	request.data = *blob;
+	size +=  blob->length;
+	/* size for subcontext(2) */
+	size += 2;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_WriteStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_WriteStream = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*WrittenSize = mapi_response->mapi_repl->u.mapi_WriteStream.WrittenSize;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Commits stream operations
+
+   \param obj_stream the stream object to commit
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: Either the network stream or session
+   context are not valid.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa OpenStream, ReadStream, WriteStream
+ */
+_PUBLIC_ enum MAPISTATUS CommitStream(mapi_object_t *obj_stream)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CommitStream");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CommitStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Gets the size of a stream
+
+   \param obj_stream the stream object we retrieve size from
+   \param StreamSize pointer on the stream size
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_stream is not initialized, or there
+     was a problem obtaining the session context
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa OpenStream, ReadStream
+ */
+_PUBLIC_ enum MAPISTATUS GetStreamSize(mapi_object_t *obj_stream, uint32_t *StreamSize)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetStreamSize");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_GetStreamSize;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*StreamSize = mapi_response->mapi_repl->u.mapi_GetStreamSize.StreamSize;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Seek a specific position within the stream
+
+   \param obj_stream the stream object
+   \param Origin origin location for the seek operation
+   \param Offset the seek offset
+   \param NewPosition pointer on the new position after the operation
+
+   Origin can either take one of the following values:
+
+   * 0x0 The new seek pointer is an offset relative to the beginning
+   of the stream.
+   * 0x1 The new seek pointer is an offset relative to the current
+   seek pointer location.
+   * 0x2 The new seek pointer is an offset relative to the end of the
+   stream.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+
+   \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_BOOKMARK: the bookmark specified is invalid or
+     beyond the last row requested.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa OpenStream, ReadStream 
+ */
+_PUBLIC_ enum MAPISTATUS SeekStream(mapi_object_t *obj_stream, uint8_t Origin, uint64_t Offset, 
+				    uint64_t *NewPosition)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct SeekStream_req	request;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF((Origin > 2), MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!NewPosition, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SeekStream");
+	size = 0;
+
+	/* Fill the SeekStream operation */
+	request.Origin = Origin;
+	size += sizeof (uint8_t);
+
+	request.Offset = Offset;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SeekStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SeekStream = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*NewPosition = mapi_response->mapi_repl->u.mapi_SeekStream.NewPosition;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the stream size
+
+   \param obj_stream the stream object
+   \param SizeStream the size of the stream
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+
+   \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_BOOKMARK: the bookmark specified is invalid or
+     beyond the last row requested.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa OpenStream, GetStreamSize
+ */
+_PUBLIC_ enum MAPISTATUS SetStreamSize(mapi_object_t *obj_stream, uint64_t SizeStream)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SetStreamSize_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj_stream);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetStreamSize");
+	size = 0;
+
+	/* Fill the SetStreamSize operation */
+	request.SizeStream = SizeStream;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetStreamSize;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SetStreamSize = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Copy a number of bytes from a source stream to another
+   stream
+
+   \param obj_src the source stream object
+   \param obj_dst the destination stream object
+   \param ByteCount the number of bytes to copy
+   \param ReadByteCount pointer on the number of bytes read from the
+   source object
+   \param WrittenByteCount pointer on the number of bytes written to
+   the destination object
+ 
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_BOOKMARK: the bookmark specified is invalid or
+     beyond the last row requested.
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+   
+   \sa OpenStream
+*/
+_PUBLIC_ enum MAPISTATUS CopyToStream(mapi_object_t *obj_src, mapi_object_t *obj_dst,
+				      uint64_t ByteCount, uint64_t *ReadByteCount,
+				      uint64_t *WrittenByteCount)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct CopyToStream_req	request;
+	struct mapi_session	*session[2];
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size;
+
+	/* Sanity Check */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session[0] = mapi_object_get_session(obj_src);
+	session[1] = mapi_object_get_session(obj_dst);
+
+	OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
+
+	OPENCHANGE_RETVAL_IF(!ByteCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ReadByteCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!WrittenByteCount, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "CopyToStream");
+	size = 0;
+
+	/* Fill the CopyToStream operation */
+	request.handle_idx = 0x1;
+	size += sizeof (uint8_t);
+
+	request.ByteCount = ByteCount;
+	size += sizeof (uint64_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_CopyToStream;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_CopyToStream = request;
+	size += 5;
+
+	/* Fill the mapi_request structure */
+	mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+	mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+	mapi_request->length = size;
+	mapi_request->mapi_req = mapi_req;
+	mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*ReadByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.ReadByteCount;
+	*WrittenByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.WrittenByteCount;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IUnknown.c
===================================================================
--- trunk/openchange/libmapi/IUnknown.c	                        (rev 0)
+++ trunk/openchange/libmapi/IUnknown.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,328 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IUnknown.c
+
+   \brief Various miscellaneous (ungrouped) functions
+ */
+
+
+/**
+   \details Allocate memory using the MAPI memory context
+
+   \param size the number of bytes to allocate
+   \param ptr pointer to the allocated byte region
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_SESSION_LIMIT: No session has been opened on the provider
+   - MAPI_E_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   - MAPI_E_INVALID_PARAMER: size is not set properly.
+
+   \sa MAPIFreeBuffer, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS MAPIAllocateBuffer(uint32_t size, void **ptr)
+{
+	TALLOC_CTX	*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = (TALLOC_CTX *) global_mapi_ctx->mem_ctx;
+
+	*ptr = talloc_size(mem_ctx, size);
+	OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Free allocated memory
+
+   This function frees memory previously allocated with
+   MAPIAllocateBuffer.
+
+   \param ptr memory region to free
+       
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMER: ptr is not set properly.
+
+   \sa MAPIAllocateBuffer, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS MAPIFreeBuffer(void *ptr)
+{
+	int		ret;
+
+	OPENCHANGE_RETVAL_IF(!ptr, MAPI_E_INVALID_PARAMETER, NULL);
+
+	ret = talloc_free(ptr);
+	OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_INVALID_PARAMETER, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Release an object on the server
+
+   The function releases the object \a obj on the server.
+
+   \param obj the object to release
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS Release(mapi_object_t *obj)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ *mapi_req;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		size = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "Release");
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_Release;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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 = (uint16_t)size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns the latest error code.
+
+   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.
+*/
+_PUBLIC_ enum MAPISTATUS GetLastError(void)
+{
+	return errno;
+}
+
+
+/**
+   \details Convert an ID to a Long Term Id
+
+   The function looks up the Long Term Id for a specified ID value.
+
+   \param obj the object to look up on
+   \param id the id to look up
+   \param long_term_id the long term ID returned from the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj is null
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetIdFromLongTermId
+*/
+_PUBLIC_ enum MAPISTATUS GetLongTermIdFromId(mapi_object_t *obj, mapi_id_t id,
+					     struct LongTermId *long_term_id)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ 	*mapi_req;
+	struct LongTermIdFromId_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size = 0;
+	enum MAPISTATUS			retval;
+	int				i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "LongTermIdFromId");
+
+	/* Fill the LongTermIdFromId operation */
+	request.Id = id;
+	size += sizeof(mapi_id_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_LongTermIdFromId;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_LongTermIdFromId = request;
+	size += 5;
+
+	/* 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 = (uint16_t)size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	long_term_id->DatabaseGuid = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.DatabaseGuid;
+	for (i = 0; i < 6; ++i) {
+		long_term_id->GlobalCounter[i] = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.GlobalCounter[i];
+	}
+	long_term_id->padding = 0x0;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Convert an Long Term Id into an Id
+
+   The function looks up the Id for a specified Long Term Id value.
+
+   \param obj the object to look up on
+   \param long_term_id the id to look up
+   \param id the id returned by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj is null
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetLongTermIdFromId
+*/
+_PUBLIC_ enum MAPISTATUS GetIdFromLongTermId(mapi_object_t *obj, struct LongTermId long_term_id,
+					     mapi_id_t *id)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ 	*mapi_req;
+	struct IdFromLongTermId_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	TALLOC_CTX			*mem_ctx;
+	uint32_t			size = 0;
+	enum MAPISTATUS			retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	session = mapi_object_get_session(obj);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "IdFromLongTermId");
+	size = 0;
+
+	/* Fill the IdFromLongTermId operation */
+	request.LongTermId = long_term_id;
+	size += sizeof(struct LongTermId);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_IdFromLongTermId;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_IdFromLongTermId = request;
+	size += 5;
+
+	/* 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 = (uint16_t)size;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	*id = mapi_response->mapi_repl->u.mapi_IdFromLongTermId.Id;
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/IXPLogon.c
===================================================================
--- trunk/openchange/libmapi/IXPLogon.c	                        (rev 0)
+++ trunk/openchange/libmapi/IXPLogon.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,256 @@
+/*
+   OpenChange MAPI implementation.
+
+   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 <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file IXPLogon.c
+
+   \brief Transport provider status information
+*/
+
+
+/**
+   \details Returns the types of recipients that the transport
+   provider handles.
+
+   \param obj_store the object to get recipients types from
+   \param lpcAdrType the count of recipients types returned
+   \param lpAdrTypeArray pointer on pointer of returned transport
+   provider types
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_store is not initialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+ */
+_PUBLIC_ enum MAPISTATUS AddressTypes(mapi_object_t *obj_store,
+				      uint16_t *lpcAdrType,
+				      struct mapi_LPSTR **lpAdrTypeArray)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct AddressTypes_repl	*response;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size;
+	TALLOC_CTX			*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "AddressTypes");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_AddressTypes;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Retrieve Address Types */
+	response = &mapi_response->mapi_repl->u.mapi_AddressTypes;
+	*lpcAdrType = response->cValues;
+	*lpAdrTypeArray = talloc_steal((TALLOC_CTX *)session, response->transport);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Informs the server that the client intends to act as a
+   mail spooler.
+
+   \param obj_store: the object server store object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_store is not initialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction 
+
+   \sa SpoolerLockMessage
+ */
+_PUBLIC_ enum MAPISTATUS SetSpooler(mapi_object_t *obj_store)
+{
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mapi_session	*session;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		size = 0;
+	TALLOC_CTX		*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SetSpooler");
+	size = 0;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SetSpooler;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Locks the specified message for spooling.
+
+   \param obj_store the store object
+   \param obj_message the message object we want to lock
+   \param LockState the lock state
+
+   Possible values for the lock state:
+   -# LockState_1stLock (0x0): Mark the message as locked
+   -# LockState_1stUnlock (0x1): Mark the message as unlocked
+   -# LockState_1stFinished (0x2): Mark the message as ready for
+      processing by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: obj_store is not initialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction 
+
+     \sa SetSPooler
+ */
+_PUBLIC_ enum MAPISTATUS SpoolerLockMessage(mapi_object_t *obj_store,
+					    mapi_object_t *obj_message, 
+					    uint8_t LockState)
+{
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	struct SpoolerLockMessage_req	request;
+	struct mapi_session		*session;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	uint32_t			size = 0;
+	TALLOC_CTX			*mem_ctx;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(LockState > 2, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "SpoolerLockMessage");
+	size = 0;
+
+	/* Fill the SpoolerLockMessage operation */
+	request.MessageId = mapi_object_get_id(obj_message);
+	size += sizeof (uint64_t);
+
+	request.LockState = LockState;
+	size += sizeof (uint8_t);
+
+	/* Fill the MAPI_REQ request */
+	mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	mapi_req->opnum = op_MAPI_SpoolerLockMessage;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_SpoolerLockMessage = request;
+	size += 5;
+
+	/* 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;
+	mapi_request->mapi_req = mapi_req;
+	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);
+	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;
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mapi_response);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;	
+}

Added: trunk/openchange/libmapi/cdo_mapi.c
===================================================================
--- trunk/openchange/libmapi/cdo_mapi.c	                        (rev 0)
+++ trunk/openchange/libmapi/cdo_mapi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,353 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-2009.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <libmapi/dlinklist.h>
+#include <param.h>
+#include <ldb_errors.h>
+#include <ldb.h>
+
+struct mapi_ctx *global_mapi_ctx = NULL;
+
+
+/**
+   \file cdo_mapi.c
+
+   \brief MAPI subsystem related operations
+*/
+
+
+/**
+   \details Create a full MAPI session
+ 
+   Open providers stored in the profile and return a pointer on a
+   IMAPISession object.
+
+   \param session pointer to a pointer to a MAPI session object
+   \param profname profile name to use
+   \param password password to use for the profile
+
+   password should be set to NULL if the password has been stored in
+   the profile.
+
+   \return MAPI_E_SUCCESS on success otherwise MAPI error.
+
+   \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_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa MAPIInitialize, OpenProfile, MapiLogonProvider
+*/
+_PUBLIC_ enum MAPISTATUS MapiLogonEx(struct mapi_session **session, 
+				     const char *profname, const char *password)
+{
+	struct mapi_session	*tmp_session = NULL;
+	enum MAPISTATUS		retval;
+
+	retval = MapiLogonProvider(&tmp_session, profname, password, PROVIDER_ID_NSPI);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	retval = MapiLogonProvider(&tmp_session, profname, password, PROVIDER_ID_EMSMDB);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	*session = tmp_session;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Initialize a session on the specified provider
+
+   \param session pointer to a pointer to a MAPI session object
+   \param profname profile name
+   \param password profile password
+   \param provider provider we want to establish a connection on
+
+   password should be set to NULL if the password has been stored in
+   the profile.
+
+   Supported providers are:
+   - PROVIDER_ID_NSPI: Address Book provider
+   - PROVIDER_ID_EMSMDB: MAPI Store provider
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa MapiLogonEx, OpenProfile, LoadProfile
+*/
+_PUBLIC_ enum MAPISTATUS MapiLogonProvider(struct mapi_session **session,
+					   const char *profname, 
+					   const char *password,
+					   enum PROVIDER_ID provider)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_provider	*provider_emsmdb;
+	struct mapi_provider	*provider_nspi;
+	struct mapi_profile	*profile;
+	struct mapi_session	*el;
+	bool			found = false;
+	bool			exist = false;
+
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+
+	/* If no MAPI session has already been created */
+	if (!global_mapi_ctx->session) {
+		global_mapi_ctx->session = talloc_zero(global_mapi_ctx->mem_ctx, struct mapi_session);
+	}
+	
+	/* If the session doesn't exist, create a new one */
+	if (!*session) {
+		el = talloc_zero((TALLOC_CTX *)global_mapi_ctx->session, struct mapi_session);
+		OPENCHANGE_RETVAL_IF(!el, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+	} else {
+		/* Lookup the session within the chained list */
+		for (el = global_mapi_ctx->session; el; el = el->next) {
+			if (*session == el) {
+				found = true;
+				break;
+			}
+		}
+		OPENCHANGE_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, NULL);
+		exist = true;
+	}
+
+	mem_ctx = (TALLOC_CTX *) el;
+
+	/* Open the profile */
+	if (!el->profile) {
+		profile = talloc_zero(mem_ctx, struct mapi_profile);
+		OPENCHANGE_RETVAL_IF(!profile, MAPI_E_NOT_ENOUGH_RESOURCES, el);
+
+		retval = OpenProfile(profile, profname, password);
+		OPENCHANGE_RETVAL_IF(retval, retval, el);
+		
+		retval = LoadProfile(profile);
+		OPENCHANGE_RETVAL_IF(retval, retval, el);
+
+		el->profile = profile;
+	}
+
+	switch (provider) {
+	case PROVIDER_ID_EMSMDB:
+		provider_emsmdb = talloc_zero(mem_ctx, struct mapi_provider);
+		OPENCHANGE_RETVAL_IF(!provider_emsmdb, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+		talloc_set_destructor((void *)provider_emsmdb, (int (*)(void *))emsmdb_disconnect_dtor);
+		retval = Logon(el, provider_emsmdb, PROVIDER_ID_EMSMDB);
+		if (retval) return retval;
+		el->emsmdb = provider_emsmdb;
+		break;
+	case PROVIDER_ID_NSPI:
+		provider_nspi = talloc_zero(mem_ctx, struct mapi_provider);
+		OPENCHANGE_RETVAL_IF(!provider_nspi, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+		talloc_set_destructor((void *)provider_nspi, (int (*)(void *))nspi_disconnect_dtor);
+		retval = Logon(el, provider_nspi, PROVIDER_ID_NSPI);
+		if (retval) return retval;
+		el->nspi = provider_nspi;
+		break;
+	default:
+		OPENCHANGE_RETVAL_IF(1, MAPI_E_NO_SUPPORT, el);
+		break;
+	}
+
+	/* Add the element to the session list */
+	if (exist == false) {
+		DLIST_ADD(global_mapi_ctx->session, el);
+		*session = el;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Initialize mapi context global structure
+
+   This function inititalizes the MAPI subsystem and open the profile
+   database pointed by profiledb .
+
+   \param profiledb profile database path
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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_NOT_ENOUGH_RESOURCES: MAPI subsystem failed to allocate
+     the necessary resources to operate properly
+   - MAPI_E_NOT_FOUND: No suitable profile database was found in the
+     path pointed by profiledb
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \sa MAPIUninitialize
+*/
+_PUBLIC_ enum MAPISTATUS MAPIInitialize(const char *profiledb)
+{
+	enum MAPISTATUS	retval;
+	TALLOC_CTX	*mem_ctx;
+
+	/* Set the initial errno value for GetLastError */
+	errno = 0;
+
+	OPENCHANGE_RETVAL_IF(global_mapi_ctx, MAPI_E_SESSION_LIMIT, NULL);
+	OPENCHANGE_RETVAL_IF(!profiledb, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "MAPIInitialize");
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
+	/* global context */
+	global_mapi_ctx = talloc_zero(mem_ctx, struct mapi_ctx);
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+	global_mapi_ctx->mem_ctx = mem_ctx;
+	global_mapi_ctx->dumpdata = false;
+	global_mapi_ctx->session = NULL;
+	global_mapi_ctx->lp_ctx = loadparm_init(global_mapi_ctx->mem_ctx);
+	lp_load_default(global_mapi_ctx->lp_ctx);
+
+	/* Enable logging on stdout */
+	setup_logging(NULL, DEBUG_STDOUT);
+
+	/* profile store */
+	retval = OpenProfileStore(mem_ctx, &global_mapi_ctx->ldb_ctx, profiledb);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Initialize dcerpc subsystem */
+	dcerpc_init(global_mapi_ctx->lp_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+
+/**
+   \details Uninitialize MAPI subsystem
+
+   This function uninitializes the MAPI context and destroy
+   recursively the whole mapi session and associated objects hierarchy
+
+   \sa MAPIInitialize, GetLastError
+ */
+_PUBLIC_ void MAPIUninitialize(void)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_session	*session;
+
+	if (!global_mapi_ctx) return;
+
+	session = global_mapi_ctx->session;
+	if (session && session->notify_ctx && session->notify_ctx->fd != -1) {
+		DEBUG(3, ("emsmdb_disconnect_dtor: unbind udp\n"));
+		shutdown(session->notify_ctx->fd, SHUT_RDWR);
+		close(session->notify_ctx->fd);
+	}
+	
+	mem_ctx = global_mapi_ctx->mem_ctx;
+	talloc_free(mem_ctx);
+	global_mapi_ctx = NULL;
+}
+
+
+/**
+   \details Enable MAPI network trace output
+
+   \param status the status
+
+   possible status values/behavior:
+   -# true:  Network traces are displayed on stdout
+   -# false: Network traces are not displayed on stdout
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED
+ */
+_PUBLIC_ enum MAPISTATUS SetMAPIDumpData(bool status)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	
+	global_mapi_ctx->dumpdata = status;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set MAPI debug level
+
+   \param level the debug level to set
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: the function parameter is invalid
+ */
+_PUBLIC_ enum MAPISTATUS SetMAPIDebugLevel(uint32_t level)
+{
+	char	*debuglevel;
+	bool	ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	debuglevel = talloc_asprintf(talloc_autofree_context(), "%u", level);
+	ret = lp_set_cmdline(global_mapi_ctx->lp_ctx, "log level", debuglevel);
+	talloc_free(debuglevel);
+
+	return (ret == true) ? MAPI_E_SUCCESS : MAPI_E_INVALID_PARAMETER;
+}
+
+
+/**
+   \details Retrieve the global MAPI loadparm context
+
+   \param lp_ctx pointer to a pointer to the loadparm context that the
+   function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED
+   or MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS GetLoadparmContext(struct loadparm_context **lp_ctx)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!lp_ctx, MAPI_E_INVALID_PARAMETER, NULL);
+
+	*lp_ctx = global_mapi_ctx->lp_ctx;
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/conf/build.sh
===================================================================
--- trunk/openchange/libmapi/conf/build.sh	                        (rev 0)
+++ trunk/openchange/libmapi/conf/build.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+./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


Property changes on: trunk/openchange/libmapi/conf/build.sh
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/libmapi/conf/mapi-codes
===================================================================
--- trunk/openchange/libmapi/conf/mapi-codes	                        (rev 0)
+++ trunk/openchange/libmapi/conf/mapi-codes	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,292 @@
+#
+# OpenChange MAPI implementation.
+# MAPI error codes
+#
+# 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/>.
+#
+
+0x00000000  MAPI_E_SUCCESS
+0x80004002  MAPI_E_INTERFACE_NO_SUPPORT
+0x80004005  MAPI_E_CALL_FAILED
+0x80040102  MAPI_E_NO_SUPPORT
+0x80040103  MAPI_E_BAD_CHARWIDTH
+0x80040105  MAPI_E_STRING_TOO_LONG
+0x80040106  MAPI_E_UNKNOWN_FLAGS
+0x80040107  MAPI_E_INVALID_ENTRYID
+0x80040108  MAPI_E_INVALID_OBJECT
+0x80040109  MAPI_E_OBJECT_CHANGED
+0x8004010A  MAPI_E_OBJECT_DELETED
+0x8004010B  MAPI_E_BUSY
+0x8004010D  MAPI_E_NOT_ENOUGH_DISK
+0x8004010E  MAPI_E_NOT_ENOUGH_RESOURCES
+0x8004010F  MAPI_E_NOT_FOUND
+0x80040110  MAPI_E_VERSION
+0x80040111  MAPI_E_LOGON_FAILED
+0x80040112  MAPI_E_SESSION_LIMIT
+0x80040113  MAPI_E_USER_CANCEL
+0x80040114  MAPI_E_UNABLE_TO_ABORT
+0x80040115  MAPI_E_NETWORK_ERROR
+0x80040116  MAPI_E_DISK_ERROR
+0x80040117  MAPI_E_TOO_COMPLEX
+0x80040118  MAPI_E_BAD_COLUMN
+0x80040119  MAPI_E_EXTENDED_ERROR
+0x8004011A  MAPI_E_COMPUTED
+0x8004011B  MAPI_E_CORRUPT_DATA
+0x8004011C  MAPI_E_UNCONFIGURED
+0x8004011D  MAPI_E_FAILONEPROVIDER
+0x8004011E  MAPI_E_UNKNOWN_CPID
+0x8004011F  MAPI_E_UNKNOWN_LCID
+0x80040120  MAPI_E_PASSWORD_CHANGE_REQUIRED
+0x80040121  MAPI_E_PASSWORD_EXPIRED
+0x80040122  MAPI_E_INVALID_WORKSTATION_ACCOUNT
+0x80040123  MAPI_E_INVALID_ACCESS_TIME
+0x80040124  MAPI_E_ACCOUNT_DISABLED
+0x80040200  MAPI_E_END_OF_SESSION
+0x80040201  MAPI_E_UNKNOWN_ENTRYID
+0x80040202  MAPI_E_MISSING_REQUIRED_COLUMN
+0x80040203  MAPI_W_NO_SERVICE
+0x80040301  MAPI_E_BAD_VALUE
+0x80040302  MAPI_E_INVALID_TYPE
+0x80040303  MAPI_E_TYPE_NO_SUPPORT
+0x80040304  MAPI_E_UNEXPECTED_TYPE
+0x80040305  MAPI_E_TOO_BIG
+0x80040306  MAPI_E_DECLINE_COPY
+0x80040307  MAPI_E_UNEXPECTED_ID
+0x80040380  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
+0x80040500  MAPI_E_WAIT
+0x80040501  MAPI_E_CANCEL
+0x80040502  MAPI_E_NOT_ME
+0x80040580  MAPI_W_CANCEL_MESSAGE
+0x80040600  MAPI_E_CORRUPT_STORE
+0x80040601  MAPI_E_NOT_IN_QUEUE
+0x80040602  MAPI_E_NO_SUPPRESS
+0x80040604  MAPI_E_COLLISION
+0x80040605  MAPI_E_NOT_INITIALIZED
+0x80040606  MAPI_E_NON_STANDARD
+0x80040607  MAPI_E_NO_RECIPIENTS
+0x80040608  MAPI_E_SUBMITTED
+0x80040609  MAPI_E_HAS_FOLDERS
+0x8004060A  MAPI_E_HAS_MESAGES
+0x8004060B  MAPI_E_FOLDER_CYCLE
+0x8004060D  MAPI_E_LOCKID_LIMIT
+0x80040680  MAPI_W_PARTIAL_COMPLETION
+0x80040700  MAPI_E_AMBIGUOUS_RECIP
+0x80040800  SYNC_E_OBJECT_DELETED
+0x80040801  SYNC_E_IGNORE
+0x80040802  SYNC_E_CONFLICT
+0x80040803  SYNC_E_NO_PARENT
+0x80040804  SYNC_E_CYCLE_DETECTED
+0x80040805  SYNC_E_UNSYNCHRONIZED
+0x80040820  SYNC_W_PROGRESS
+0x80040821  SYNC_W_CLIENT_CHANGE_NEWER
+0x80040900  MAPI_E_NAMED_PROP_QUOTA_EXCEEDED
+0x80070005  MAPI_E_NO_ACCESS
+0x8007000E  MAPI_E_NOT_ENOUGH_MEMORY
+0x80070057  MAPI_E_INVALID_PARAMETER
+
+#
+# Additional Error Codes
+#
+
+0x000003EA  ecJetError
+0x000003EB  ecUnknownUser
+0x000003ED  ecExiting
+0x000003EE  ecBadConfig
+0x000003EF  ecUnknownCodePage
+0x000003F0  ecMemory
+0x000003F2  ecLoginPerm
+0x000003F3  ecDatabaseRolledBack
+0x000003F4  ecDatabaseCopiedError
+0x000003F5  ecAuditNotAllowed
+0x000003F6  ecZombieUser
+0x000003F7  ecUnconvertableACL
+0x0000044C  ecNoFreeJses
+0x0000044D  ecDifferentJses
+0x0000044F  ecFileRemove
+0x00000450  ecParameterOverflow
+0x00000451  ecBadVersion
+0x00000452  ecTooManyCols
+0x00000453  ecHaveMore
+0x00000454  ecDatabaseError
+0x00000455  ecIndexNameTooBig
+0x00000456  ecUnsupportedProp
+0x00000457  ecMsgNotSaved
+0x00000459  ecUnpubNotif
+0x0000045B  ecDifferentRoot
+0x0000045C  ecBadFolderName
+0x0000045D  ecAttachOpen
+0x0000045E  ecInvClpsState
+0x0000045F  ecSkipMyChildren
+0x00000460  ecSearchFolder
+0x00000461  ecNotSearchFolder
+0x00000462  ecFolderSetReceive
+0x00000463  ecNoReceiveFolder
+0x00000465  ecNoDelSubmitMsg
+0x00000467  ecInvalidRecips
+0x00000468  ecNoReplicaHere
+0x00000469  ecNoReplicaAvailable
+0x0000046A  ecPublicMDB
+0x0000046B  ecNotPublicMDB
+0x0000046C  ecRecordNotFound
+0x0000046D  ecReplConflict
+0x00000470  ecFxBufferOverrun
+0x00000471  ecFxBufferEmpty
+0x00000472  ecFxPartialValue
+0x00000473  ecFxNoRoom
+0x00000474  ecMaxTimeExpired
+0x00000475  ecDstError
+0x00000476  ecMDBNotInit
+0x00000478  ecWrongServer
+0x0000047D  ecBufferTooSmall
+0x0000047E  ecRequiresRefResolve
+0x0000047F  ecServerPaused
+0x00000480  ecServerBusy
+0x00000481  ecNoSuchLogon
+0x00000482  ecLoadLibFailed
+0x00000483  ecObjAlreadyConfig
+0x00000484  ecObjNotConfig
+0x00000485  ecDataLoss
+0x00000488  ecMaxSendThreadExceeded
+0x00000489  ecFxErrorMarker
+0x0000048A  ecNoFreeJtabs
+0x0000048B  ecNotPrivateMDB
+0x0000048C  ecIsintegMDB
+0x0000048D  ecRecoveryMDBMismatch
+0x0000048E  ecTableMayNotBeDeleted
+0x000004B1  ecRpcRegisterIf
+0x000004B2  ecRpcListen
+0x000004B6  ecRpcFormat
+0x000004B7  ecNoCopyTo
+0x000004B9  ecNullObject
+0x000004BC  ecRpcAuthentication
+0x000004BD  ecRpcBadAuthenticationLevel
+0x000004BE  ecNullCommentRestriction
+0x000004CC  ecRulesLoadError
+0x000004CD  ecRulesDelivErr
+0x000004CE  ecRulesParsingErr
+0x000004CF  ecRulesCreateDaeErr
+0x000004D0  ecRulesCreateDamErr
+0x000004D1  ecRulesNoMoveCopyFolder
+0x000004D2  ecRulesNoFolderRights
+0x000004D4  ecMessageTooBig
+0x000004D5  ecFormNotValid
+0x000004D6  ecNotAuthorized
+0x000004D7  ecDeleteMessage
+0x000004D8  ecBounceMessage
+0x000004D9  ecQuotaExceeded
+0x000004DA  ecMaxSubmissionExceeded
+0x000004DB  ecMaxAttachmentExceeded
+0x000004DC  ecSendAsDenied
+0x000004DD  ecShutoffQuotaExceeded
+0x000004DE  ecMaxObjsExceeded
+0x000004DF  ecClientVerDisallowed
+0x000004E0  ecRpcHttpDisallowed
+0x000004E1  ecCachedModeRequired
+0x000004E3  ecFolderNotCleanedUp
+0x000004ED  ecFmtError
+0x000004F7  ecNotExpanded
+0x000004F8  ecNotCollapsed
+0x000004F9  ecLeaf
+0x000004FA  ecUnregisteredNamedProp
+0x000004FB  ecFolderDisabled
+0x000004FC  ecDomainError
+0x000004FF  ecNoCreateRight
+0x00000500  ecPublicRoot
+0x00000501  ecNoReadRight
+0x00000502  ecNoCreateSubfolderRight
+0x00000503  ecDstNullObject
+0x00000504  ecMsgCycle
+0x00000505  ecTooManyRecips
+0x0000050A  ecVirusScanInProgress
+0x0000050B  ecVirusDetected
+0x0000050C  ecMailboxInTransit
+0x0000050D  ecBackupInProgress
+0x0000050E  ecVirusMessageDeleted
+0x0000050F  ecInvalidBackupSequence
+0x00000510  ecInvalidBackupSize
+0x00000511  ecTooManyBackupsInProgress
+0x00000512  ecRestoreInProgress
+0x00000579  ecDuplicateObject
+0x0000057A  ecObjectNotFound
+0x0000057B  ecFixupReplyRule
+0x0000057C  ecTemplateNotFound
+0x0000057D  ecRuleException
+0x0000057E  ecDSNoSuchObject
+0x0000057F  ecMessageAlreadyTombstoned
+0x00000596  ecRequiresRWTransaction
+0x0000060E  ecPaused
+0x00000648  ecWrongMailbox
+0x0000064C  ecChgPassword
+0x0000064D  ecPwdExpired
+0x0000064E  ecInvWkstn
+0x0000064F  ecInvLogonHrs
+0x00000650  ecAcctDisabled
+0x000006A4  ecRuleVersion
+0x000006A5  ecRuleFormat
+0x000006A6  ecRuleSendAsDenied
+0x000006B9  ecNoServerSupport
+0x000006BA  ecLockTimedOut
+0x000006BB  ecObjectLocked
+0x000006BD  ecInvalidLockNamespace
+0x000007D6  ecMessageDeleted
+0x000007D8  ecProtocolDisabled
+0x000007D9  ecClearTextLogonDisabled
+0x000007EE  ecRejected
+0x0000089A  ecAmbiguousAlias
+0x0000089B  ecUnknownMailbox
+0x000008FC  ecExpReserved
+0x000008FD  ecExpParseDepth
+0x000008FE  ecExpFuncArgType
+0x000008FF  ecExpSyntax
+0x00000900  ecExpBadStrToken
+0x00000901  ecExpBadColToken
+0x00000902  ecExpTypeMismatch
+0x00000903  ecExpOpNotSupported
+0x00000904  ecExpDivByZero
+0x00000905  ecExpUnaryArgType
+0x00000960  ecNotLocked
+0x00000961  ecClientEvent
+0x00000965  ecCorruptEvent
+0x00000966  ecCorruptWatermark
+0x00000967  ecEventError
+0x00000968  ecWatermarkError
+0x00000969  ecNonCanonicalACL
+0x0000096C  ecMailboxDisabled
+0x0000096D  ecRulesFolderOverQuota
+0x0000096E  ecADUnavailable
+0x0000096F  ecADError
+0x00000971  ecADNotFound
+0x00000972  ecADPropertyError
+0x00000970  ecNotEncrypted
+0x00000973  ecRpcServerTooBusy
+0x00000974  ecRpcOutOfMemory
+0x00000975  ecRpcServerOutOfMemory
+0x00000976  ecRpcOutOfResources
+0x00000977  ecRpcServerUnavailable
+0x0000097A  ecSecureSubmitError
+0x0000097C  ecEventsDeleted
+0x0000097D  ecSubsystemStopping
+0x0000097E  ecSAUnavailable
+0x00000A28  ecCIStopping
+0x00000A29  ecFxInvalidState
+0x00000A2A  ecFxUnexpectedMarker
+0x00000A2B  ecDuplicateDelivery
+0x00000A2C  ecConditionViolation

Added: trunk/openchange/libmapi/conf/mapi-named-properties
===================================================================
--- trunk/openchange/libmapi/conf/mapi-named-properties	                        (rev 0)
+++ trunk/openchange/libmapi/conf/mapi-named-properties	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,456 @@
+#
+#   OpenChange MAPI implementation.
+#
+#   Copyright (C) Julien Kerihuel 2007-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/>.
+#
+
+
+### Canonical name				       OOM	                     propID propName			  propType	Kind        OLEGUID
+
+### Meeting Properties
+PidLidAttendeeCriticalChange                           LID_ATTENDEE_CRITICAL_CHANGE  0x0001 NULL                          PT_SYSTIME    MNID_ID     PSETID_Meeting
+PidLidWhere                                            LID_WHERE                     0x0002 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidGlobalObjectId                                   LID_GLOBAL_OBJID              0x0003 NULL                          PT_BINARY     MNID_ID     PSETID_Meeting
+PidLidIsSilent                                         LID_IS_SILENT                 0x0004 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Meeting
+PidLidIsRecurring                                      LID_IS_RECURRING              0x0005 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Meeting
+PidLidRequiredAttendees                                LID_REQUIRED_ATTENDEES        0x0006 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidOptionalAttendees                                LID_OPTIONAL_ATTENDEES        0x0007 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidResourceAttendees                                LID_RESOURCE_ATTENDEES        0x0008 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidDelegateMail                                     LID_DELEGATE_MAIL             0x0009 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Meeting
+PidLidIsException                                      LID_IS_EXCEPTION              0x000A NULL                          PT_BOOLEAN    MNID_ID     PSETID_Meeting
+PidLidSingleInvite                                     LID_SINGLE_INVITE             0x000B NULL                          PT_BOOLEAN    MNID_ID     PSETID_Meeting
+PidLidTimeZone                                         LID_TIME_ZONE                 0x000C NULL                          PT_LONG       MNID_ID     PSETID_Meeting
+PidLidDayInterval                                      LID_DAY_INTERVAL              0x0011 NULL                          PT_SHORT      MNID_ID     PSETID_Meeting
+PidLidWeekInterval                                     LID_WEEK_INTERVAL             0x0012 NULL                          PT_SHORT      MNID_ID     PSETID_Meeting
+PidLidMonthInterval                                    LID_MONTH_INTERVAL            0x0013 NULL                          PT_SHORT      MNID_ID     PSETID_Meeting
+PidLidYearInterval                                     LID_YEAR_INTERVAL             0x0014 NULL                          PT_SHORT      MNID_ID     PSETID_Meeting
+PidLidOwnerCriticalChange                              LID_OWNER_CRITICAL_CHANGE     0x001A NULL                          PT_SYSTIME    MNID_ID     PSETID_Meeting
+PidLidCalendarType                                     LID_CALENDAR_TYPE             0x001C NULL                          PT_LONG       MNID_ID     PSETID_Meeting
+PidLidAllAttendeesList                                 LID_ALL_ATTENDEES_LIST        0x001D NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidCleanGlobalObjectId                              CleanGlobalObjId              0x0023 NULL                          PT_BINARY     MNID_ID     PSETID_Meeting
+PidLidAppointmentMessageClass                          ApptMessageClass              0x0024 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidMeetingType                                      MeetingType                   0x0026 NULL                          PT_LONG       MNID_ID     PSETID_Meeting
+PidLidOldLocation                                      OldLocation                   0x0028 NULL                          PT_UNICODE    MNID_ID     PSETID_Meeting
+PidLidOldWhenStartWhole                                OldWhenStartWhole             0x0029 NULL                          PT_SYSTIME    MNID_ID     PSETID_Meeting
+PidLidOldWhenEndWhole                                  OldWhenEndWhole               0x002A NULL                          PT_SYSTIME    MNID_ID     PSETID_Meeting
+
+
+### Address Named Properties
+PidLidYomiCompanyName                                  YomiCompanyName               0x8002 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFileUnder                                        FileUnder                     0x8005 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFileUnderId                                      FileUnderId                   0x8006 NULL                          PT_LONG       MNID_ID     PSETID_Address
+PidLidContactItemData                                  ContactItemData               0x8007 NULL                          PT_MV_LONG    MNID_ID     PSETID_Address
+NULL                                                   NULL                          0x800E NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidDepartment                                       Department                    0x8010 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidHasPicture                                       HasPicture                    0x8015 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Address
+PidLidHomeAddress                                      HomeAddress                   0x801A NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddress                                      WorkAddress                   0x801B NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidOtherAddress                                     OtherAddress                  0x801C NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidPostalAddressId                                  PostalAddressId               0x8022 NULL                          PT_LONG       MNID_ID     PSETID_Address
+PidLidContactCharacterSet                              ContactCharSet                0x8023 NULL                          PT_LONG       MNID_ID     PSETID_Address
+PidLidAutoLog                                          AutoLog                       0x8025 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Address
+PidLidFileUnderList                                    FileUnderList                 0x8026 NULL                          PT_MV_LONG    MNID_ID     PSETID_Address
+PidLidEmailList                                        EmailList                     0x8027 NULL                          PT_MV_LONG    MNID_ID     PSETID_Address
+PidLidAddressBookProviderEmailList                     ABPEmailList                  0x8028 NULL                          PT_MV_LONG    MNID_ID     PSETID_Address
+PidLidAddressBookProviderArrayType                     ABPArrayType                  0x8029 NULL                          PT_LONG       MNID_ID     PSETID_Address
+PidLidHtml                                             HTML                          0x802B NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidYomiFirstName                                    YomiFirstName                 0x802C NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidYomiLastName                                     YomiLastName                  0x802D NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidBusinessCardDisplayDefinition                    BCDisplayDefinition           0x8040 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidBusinessCardCardPicture                          BCCardPicture                 0x8041 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidWorkAddressStreet                                WorkAddressStreet             0x8045 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressCity                                  WorkAddressCity               0x8046 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressState                                 WorkAddressState              0x8047 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressPostalCode                            WorkAddressPostalCode         0x8048 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressCountry                               WorkAddressCountry            0x8049 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressPostOfficeBox                         WorkAddressPostOfficeBox      0x804A NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidDistributionListChecksum                         DLChecksum                    0x804C NULL                          PT_LONG       MNID_ID     PSETID_Address
+PidLidBirthdayEventEntryId                             BirthdayEventEID              0x804D NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidAnniversaryEventEntryId                          AnniversaryEventEID           0x804E NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidContactUserField1                                ContactUserField1             0x804F NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidContactUserField2			               ContactUserField2             0x8050 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidContactUserField3			               ContactUserField3             0x8051 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidContactUserField4			               ContactUserField4             0x8052 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidDistributionListName                             DLName                        0x8053 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidDistributionListOneOffMembers                    DLOneOffMembers               0x8054 NULL                          PT_MV_BINARY  MNID_ID     PSETID_Address
+PidLidDistributionListMembers                          DLMembers                     0x8055 NULL                          PT_MV_BINARY  MNID_ID     PSETID_Address
+PidLidInstantMessagingAddress                          InstMsg                       0x8062 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail1DisplayName                                Email1DisplayName             0x8080 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail1AddressType                                Email1AddrType                0x8082 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail1EmailAddress                               Email1EmailAddress            0x8083 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail1OriginalDisplayName                        Email1OriginalDisplayName     0x8084 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail1OriginalEntryId                            Email1OriginalEntryID         0x8085 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidEmail1EmailType                                  Email1EmailType               0x8087 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail2DisplayName                                Email2DisplayName             0x8090 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail2EntryId                                    Email2EntryID                 0x8091 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidEmail2AddressType                                Email2AddrType                0x8092 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail2EmailAddress                               Email2EmailAddress            0x8093 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail2OriginalDisplayName                        Email2OriginalDisplayName     0x8094 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail2OriginalEntryId                            Email2OriginalEntryID         0x8095 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidEmail3DisplayName                                Email3DisplayName             0x80A0 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail3EntryId                                    Email3EntryID                 0x80A1 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidEmail3AddressType                                Email3AddrType                0x80A2 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail3EmailAddress                               Email3EmailAddress            0x80A3 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail3OriginalDisplayName                        Email3OriginalDisplayName     0x80A4 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidEmail3OriginalEntryId                            Email3OriginalEntryID         0x80A5 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidFax1AddressType                                  Fax1AddrType                  0x80B2 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax1EmailAddress                                 Fax1EmailAddress              0x80B3 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax1OriginalDisplayName                          Fax1OriginalDisplayName       0x80B4 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax1OriginalEntryId                              Fax1OriginalEntryID           0x80B5 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidFax2AddressType                                  Fax2AddrType                  0x80C2 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax2EmailAddress                                 Fax2EmailAddress              0x80C3 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax2OriginalDisplayName                          Fax2OriginalDisplayName       0x80C4 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax2OriginalEntryId                              Fax2OriginalEntryID           0x80C5 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidFax3AddressType                                  Fax3AddrType                  0x80D2 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax3EmailAddress                                 Fax3EmailAddress              0x80D3 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax3OriginalDisplayName                          Fax3OriginalDisplayName       0x80D4 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidFax3OriginalEntryId                              Fax3OriginalEntryID           0x80D5 NULL                          PT_BINARY     MNID_ID     PSETID_Address
+PidLidFreeBusyLocation                                 FreeBusyLocation              0x80D8 NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidHomeAddressCountryCode                           HomeAddressCountryCode        0x80DA NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidWorkAddressCountryCode                           WorkAddressCountryCode        0x80DB NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidOtherAddressCountryCode                          OtherAddressCountryCode       0x80DC NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+PidLidAddressCountryCode                               AddressCountryCode            0x80DD NULL                          PT_UNICODE    MNID_ID     PSETID_Address
+
+
+
+### Task Named Properties
+PidLidTaskStatus                                       TaskStatus                    0x8101 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidPercentComplete                                  PercentComplete               0x8102 NULL                          PT_DOUBLE     MNID_ID     PSETID_Task
+PidLidTeamTask                                         TeamTask                      0x8103 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskStartDate                                    TaskStartDate                 0x8104 NULL                          PT_SYSTIME    MNID_ID     PSETID_Task
+PidLidTaskDueDate                                      TaskDueDate                   0x8105 NULL                          PT_SYSTIME    MNID_ID     PSETID_Task
+PidLidTaskResetReminder                                TaskResetReminder             0x8107 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskAccepted                                     TaskAccepted                  0x8108 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskDeadOccurrence                               TaskDeadOccur                 0x8109 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskDateCompleted                                TaskDateCompleted             0x810F NULL                          PT_SYSTIME    MNID_ID     PSETID_Task
+PidLidTaskActualEffort                                 TaskActualEffort              0x8110 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskEstimatedEffort                              TaskEstimatedEffort           0x8111 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskVersion                                      TaskVersion                   0x8112 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskState                                        TaskState                     0x8113 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskLastUpdate                                   TaskLastUpdate                0x8115 NULL                          PT_SYSTIME    MNID_ID     PSETID_Task
+PidLidTaskRecurrence                                   TaskRecur                     0x8116 NULL                          PT_BINARY     MNID_ID     PSETID_Task
+PidLidTaskAssigners                                    TaskMyDelegators              0x8117 NULL                          PT_BINARY     MNID_ID     PSETID_Task
+PidLidTaskStatusOnComplete                             TaskSOC                       0x8119 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskHistory                                      TaskHistory                   0x811A NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskUpdates                                      TaskUpdates                   0x811B NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskComplete                                     TaskComplete                  0x811C NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskFCreator                                     TaskFCreator                  0x811E NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskOwner                                        TaskOwner                     0x811F NULL                          PT_UNICODE    MNID_ID     PSETID_Task
+PidLidTaskMultipleRecipients                           TaskMultRecips                0x8120 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskAssigner                                     TaskDelegator                 0x8121 NULL                          PT_UNICODE    MNID_ID     PSETID_Task
+PidLidTaskLastUser                                     TaskLastUser                  0x8122 NULL                          PT_UNICODE    MNID_ID     PSETID_Task
+PidLidTaskOrdinal                                      TaskOrdinal                   0x8123 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskNoCompute                                    TaskNoCompute                 0x8124 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskLastDelegate                                 TaskLastDelegate              0x8125 NULL                          PT_UNICODE    MNID_ID     PSETID_Task
+PidLidTaskFRecurring                                   TaskFRecur                    0x8126 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+PidLidTaskRole                                         TaskRole                      0x8127 NULL                          PT_UNICODE    MNID_ID     PSETID_Task
+PidLidTaskOwnership                                    TaskOwnership                 0x8129 NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidAcceptanceState                                  TaskDelegValue                0x812A NULL                          PT_LONG       MNID_ID     PSETID_Task
+PidLidTaskFFixOffline                                  TaskFFixOffline               0x812C NULL                          PT_BOOLEAN    MNID_ID     PSETID_Task
+
+
+### Appointment Named Properties
+PidLidSendMeetingAsIcal                                SendMtgAsICAL                 0x8200 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentSequence                              ApptSequence                  0x8201 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentSequenceTime                          ApptSeqTime                   0x8202 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidAppointmentLastSequence                          ApptLastSequence              0x8203 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidChangeHighlight                                  ChangeHighlight               0x8204 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidBusyStatus                                       BusyStatus                    0x8205 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidFExceptionalBody                                 FExceptionalBody              0x8206 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentAuxiliaryFlags                        ApptAuxFlags                  0x8207 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidLocation                                         Location                      0x8208 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidMeetingWorkspaceUrl                              MWSURL                        0x8209 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidForwardInstance                                  FwrdInstance                  0x820A NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidLinkedTaskItems                                  LinkedTaskItems               0x820C NULL                          PT_MV_BINARY  MNID_ID     PSETID_Appointment
+PidLidAppointmentStartWhole                            ApptStartWhole                0x820D NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidAppointmentEndWhole                              ApptEndWhole                  0x820E NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+NULL                                                   NULL                          0x820F NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+NULL                                                   NULL                          0x8210 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+NULL                                                   NULL                          0x8211 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+NULL                                                   NULL                          0x8212 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidAppointmentDuration                              ApptDuration                  0x8213 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentColor                                 ApptColor                     0x8214 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentSubType                               ApptSubType                   0x8215 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentRecur                                 ApptRecur                     0x8216 NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+PidLidAppointmentStateFlags                            ApptStateFlags                0x8217 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidResponseStatus                                   ResponseStatus                0x8218 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentReplyTime                             ApptReplyTime                 0x8220 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidRecurring                                        Recurring                     0x8223 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidIntendedBusyStatus                               IntendedBusyStatus            0x8224 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidExceptionReplaceTime                             ExceptionReplaceTime          0x8228 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidFInvited                                         FInvited                      0x8229 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidFExceptionalAttendees                            FExceptionalAttendees         0x822B NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentReplyName                             ApptReplyName                 0x8230 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidRecurrenceType                                   RecurType                     0x8231 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidRecurrencePattern                                RecurPattern                  0x8232 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidTimeZoneStruct                                   TimeZoneStruct                0x8233 NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+PidLidTimeZoneDescription                              TimeZoneDesc                  0x8234 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidClipStart                                        ClipStart                     0x8235 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidClipEnd                                          ClipEnd                       0x8236 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidOriginalStoreEntryId                             OrigStoreEid                  0x8237 NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+PidLidAllAttendeesString                               AllAttendeesString            0x8238 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidAutoFillLocation                                 AutoFillLocation              0x823A NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidToAttendeesString                                ToAttendeesString             0x823B NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidCcAttendeesString                                CcAttendeesString             0x823C NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidAppointmentUnsendableRecipients                  ApptUnsendableRecips          0x823D NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidConferencingCheck                                ConfCheck                     0x8240 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidConferencingType                                 ConfType                      0x8241 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidDirectory                                        Directory                     0x8242 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidOrganizerAlias                                   OrgAlias                      0x8243 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidAutoStartCheck                                   AutoStartCheck                0x8244 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAutoStartWhen                                    AutoStartWhen                 0x8245 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAllowExternalCheck                               AllowExternCheck              0x8246 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidCollaborateDoc                                   CollaborateDoc                0x8247 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidNetShowUrl                                       NetShowURL                    0x8248 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidOnlinePassword                                   OnlinePassword                0x8249 NULL                          PT_UNICODE    MNID_ID     PSETID_Appointment
+PidLidAppointmentProposedStartWhole                    ApptProposedStartWhole        0x8250 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidAppointmentProposedEndWhole                      ApptProposedEndWhole          0x8251 NULL                          PT_SYSTIME    MNID_ID     PSETID_Appointment
+PidLidAPpointmentProposedDuration                      ApptProposedDuration          0x8256 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentCounterProposal                       ApptCounterProposal           0x8257 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentProposalNumber                        ApptProposalNum               0x8259 NULL                          PT_LONG       MNID_ID     PSETID_Appointment
+PidLidAppointmentNotAllowPropose                       ApptNotAllowPropose           0x825A NULL                          PT_BOOLEAN    MNID_ID     PSETID_Appointment
+PidLidAppointmentTimeZoneDefinitionStartDisplay	       ApptTZDefStartDisplay         0x825E NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+PidLidAppointmentTimeZoneDefinitionEndDisplay          ApptTZDefEndDisplay           0x825F NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+PidLidAppointmentTimeZoneDefinitionRecur               ApptTZDefRecur                0x8260 NULL                          PT_BINARY     MNID_ID     PSETID_Appointment
+
+
+### Common Named properties
+PidLidReminderDelta                                    ReminderDelta                 0x8501 NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidReminderTime                                     ReminderTime                  0x8502 NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidReminderSet                                      ReminderSet                   0x8503 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidPrivate                                          Private	                     0x8506 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidAgingDontAgeMe                                   AgingDontAgeMe                0x850E NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidSideEffects                                      SideEffects                   0x8510 NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidSmartNoAttach                                    SmartNoAttach                 0x8514 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidCommonStart                                      CommonStart                   0x8516 NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidCommonEnd                                        CommonEnd                     0x8517 NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidTaskMode                                         TaskMode                      0x8518 NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidTaskGlobalId                                     TaskGlobalObjId               0x8519 NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidAutoProcessState                                 SniffState                    0x851A NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidReminderOverride                                 ReminderOverride              0x851C NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidReminderType                                     ReminderType                  0x851D NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidReminderPlaySound                                ReminderPlaySound             0x851E NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidReminderFileParameter                            ReminderFileParam             0x851F NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidVerbStream                                       VerbStream                    0x8520 NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidVerbResponse                                     VerbResponse                  0x8524 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidFlagRequest                                      Request                       0x8530 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidMileage                                          MileAge                       0x8534 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidBillingInformation                               BillingInformation            0x8535 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidNonSendtableTo                                   NonSendableTo                 0x8536 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidNonSendableCc                                    NonSendableCC                 0x8537 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidNonSendableBcc                                   NonSendableBCC                0x8538 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidCompanies                                        Companies                     0x8539 NULL                          PT_MV_STRING8 MNID_ID     PSETID_Common
+PidLidContacts                                         Contacts                      0x853A NULL                          PT_MV_STRING8 MNID_ID     PSETID_Common
+PidLidNonSendToTrackStatus                             NonSendToTrackStatus          0x8543 NULL                          PT_MV_LONG    MNID_ID     PSETID_Common
+PidLidNonSendCcTrackStatus                             NonSendCcTrackStatus          0x8544 NULL                          PT_MV_LONG    MNID_ID     PSETID_Common
+PidLidNonSendBccTrackStatus                            NonSendBccTrackStatus         0x8545 NULL                          PT_MV_LONG    MNID_ID     PSETID_Common
+PidLidCurrentVersion                                   CurrentVersion                0x8552 NULL                          PT_LONG       MNID_ID     PSETID_Common
+PidLidCurrentVersionName                               CurrentVersionName            0x8554 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidReminderSignalTime                               ReminderNextTime              0x8560 NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidInternetAccountName                              InetAcctName                  0x8580 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidInternetAccountStamp                             InetAcctStamp                 0x8581 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidUseTnef                                          UseTNEF                       0x8582 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+NULL                                                   NULL                          0x8583 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidContactLinkSearchKey                             ContactLinkSearchKey          0x8584 NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidContactLinkEntry                                 ContactLinkEntry              0x8585 NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidContactLinkName                                  ContactLinkName               0x8586 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidSpamOriginalFolder                               SpamOriginalFolder            0x859C NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidToDoOrdinalDate                                  ToDoOrdinalDate               0x85A0 NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidToDoSubOrdinal                                   ToDoSubOrdinal                0x85A1 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidToDoTitle                                        ToDoTitle                     0x85A4 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidInfoPathFormName                                 InfoPathFormName              0x85B1 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidClassified                                       Classified                    0x85B5 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidClassification                                   Classification                0x85B6 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidClassificationDescription                        ClassDesc                     0x85B7 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidClassificationGuid                               ClassGuid                     0x85B8 NULL                          PT_UNICODE    MNID_ID     PSETID_Common
+PidLidClassificationKeep                               ClassKeep                     0x85BA NULL                          PT_BOOLEAN    MNID_ID     PSETID_Common
+PidLidReferenceEntryId                                 ReferenceEID                  0x85BD NULL                          PT_BINARY     MNID_ID     PSETID_Common
+PidLidValidFlagStringProof                             ValidFlagStringProof          0x85BF NULL                          PT_SYSTIME    MNID_ID     PSETID_Common
+PidLidFlagString                                       FlagStringEnum                0x85C0 NULL                          PT_LONG       MNID_ID     PSETID_Common
+
+### Log Named Properties
+PidLidLogType                                          LogType                       0x8700 NULL                          PT_UNICODE    MNID_ID     PSETID_Log
+PidLidLogStart                                         LogStart                      0x8706 NULL                          PT_SYSTIME    MNID_ID     PSETID_Log
+PidLidLogDuration                                      LogDuration                   0x8707 NULL                          PT_LONG       MNID_ID     PSETID_Log
+PidLidLogEnd                                           LogEnd                        0x8708 NULL                          PT_SYSTIME    MNID_ID     PSETID_Log
+PidLidLogFlags                                         LogFlags                      0x870C NULL                          PT_LONG       MNID_ID     PSETID_Log
+PidLidDocumentPrinted                                  LogDocPrinted                 0x870E NULL                          PT_BOOLEAN    MNID_ID     PSETID_Log
+PidLidDocumentSaved                                    LogDocSaved                   0x870F NULL                          PT_BOOLEAN    MNID_ID     PSETID_Log
+PidLidDocumentRouted                                   LogDocRouted                  0x8710 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Log
+PidLidDocumentPosted                                   LogDocPosted                  0x8711 NULL                          PT_BOOLEAN    MNID_ID     PSETID_Log
+PidLidLogTypeDesc                                      LogTypeDesc                   0x8712 NULL                          PT_UNICODE    MNID_ID     PSETID_Log
+
+
+### Post RSS Named Properties
+PidLidPostRssChannelLink                               PostRssChannelLink            0x8900 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+PidLidPostRssItemLink                                  PostRssItemLink               0x8901 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+PidLidPostRssItemHash                                  PostRssItemHash               0x8902 NULL                          PT_LONG       MNID_ID     PSETID_PostRss
+PidLidPostRssItemGuid                                  PostRssItemGuid               0x8903 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+PidLidPostRssChannel                                   PostRssChannel                0x8904 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+PidLidPostRssItemXml                                   PostRssItemXml                0x8905 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+PidLidPostRssSubscription                              PostRssSubscription           0x8906 NULL                          PT_UNICODE    MNID_ID     PSETID_PostRss
+
+
+### Sharing Named Properties
+PidLidSharingStatus                                    SharingStatus                 0x8A00 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingProviderGuid                              SharingProviderGuid           0x8A01 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingProviderName                              SharingProviderName           0x8A02 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingProviderUrl                               SharingProviderUrl            0x8A03 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemotePath                                SharingRemotePath             0x8A04 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemoteName                                SharingRemoteName             0x8A05 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemoteUid                                 SharingRemoteUid              0x8A06 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingInitiatorName                             SharingInitiatorName          0x8A07 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingInitiatorSmtp                             SharingInitiatorSmtp          0x8A08 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingInitiatorEntryId                          SharingInitiatorEid           0x8A09 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingFlags                                     SharingFlags                  0x8A0A NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingProviderExtension                         SharingProviderExtension      0x8A0B NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemoteUser                                SharingRemoteUser             0x8A0C NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemotePass                                SharingRemotePass             0x8A0D NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLocalPath                                 SharingLocalPath              0x8A0E NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLocalName                                 SharingLocalName              0x8A0F NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLocalUid                                  SharingLocalUid               0x8A10 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingFilter                                    SharingFilter                 0x8A13 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingLocalType                                 SharingLocalType              0x8A14 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingFolderEntryId                             SharingFolderEid              0x8A15 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingCapabilities                              SharingCaps                   0x8A17 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingFlavor                                    SharingFlavor                 0x8A18 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingAnonymity                                 SharingAnonymity              0x8A19 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingReciprocation                             SharingReciprocation          0x8A1A NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingPermissions                               SharingPermissions            0x8A1B NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingInstanceGuid                              SharingInstanceGuid           0x8A1C NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingRemoteType                                SharingRemoteType             0x8A1D NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingParticipants                              SharingParticipants           0x8A1E NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLastSyncTime                              SharingLastSync               0x8A1F NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingExtensionXml                              SharingExtXml                 0x8A21 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemoteLastModificationTime                SharingRemoteLastMod          0x8A22 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingLocalLastModificationTime                 SharingLocalLastMod           0x8A23 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingConfigurationUrl                          SharingConfigUrl              0x8A24 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingStart                                     SharingStart                  0x8A25 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingStop                                      SharingStop                   0x8A26 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingResponseType                              SharingResponseType           0x8A27 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingResponseTime                              SharingResponseTime           0x8A28 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingOriginalMessageEntryId                    SharingOriginalMessageEid     0x8A29 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingSyncInterval                              SharingSyncInterval           0x8A2A NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingDetail                                    SharingDetail                 0x8A2B NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingTimeToLive                                SharingTimeToLive             0x8A2C NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingBindingEntryId                            SharingBindingEid             0x8A2D NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingIndexEntryId                              SharingIndexEid               0x8A2E NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingRemoteComment                             SharingRemoteComment          0x8A2F NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingWorkingHoursStart                         SharingWorkingHoursStart      0x8A40 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingWorkingHoursEnd                           SharingWorkingHoursEnd        0x8A41 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingWorkingHoursDay                           SharingWorkingHoursDays       0x8A42 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingWorkingHoursTimeZone                      SharingWorkingHoursTZ         0x8A43 NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingDataRangeStart                            SharingDataRangeStart         0x8A44 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingDataRangeEnd                              SharingDataRangeEnd           0x8A45 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingRangeStart                                SharingRangeStart             0x8A46 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingRangeEnd                                  SharingRangeEnd               0x8A47 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingRemoteStoreUid                            SharingRemoteStoreUid         0x8A48 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLocalStoreUid                             SharingLocalStoreUid          0x8A49 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRemoteByteSize                            SharingRemoteByteSize         0x8A4B NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingRemoteCrc                                 SharingRemoteCrc              0x8A4C NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingLocalComment                              SharingLocalComment           0x8A4D NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingRoamLog                                   SharingRoamLog                0x8A4E NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingRemoteMessageCount                        SharingRemoteMsgCount         0x8A4F NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingBrowseUrl                                 SharingBrowseUrl              0x8A51 NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingLastAutoSyncTime                          SharingLastAutoSync           0x8A55 NULL                          PT_SYSTIME    MNID_ID     PSETID_Sharing
+PidLidSharingTimeToLiveAuto                            SharingTimeToLiveAuto         0x8A56 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+PidLidSharingRemoteVersion                             SharingRemoteVersion          0x8A5B NULL                          PT_UNICODE    MNID_ID     PSETID_Sharing
+PidLidSharingParentBindingEntryId                      SharingParentBindingEid       0x8A5C NULL                          PT_BINARY     MNID_ID     PSETID_Sharing
+PidLidSharingSyncFlags                                 SharingSyncFlags              0x8A60 NULL                          PT_LONG       MNID_ID     PSETID_Sharing
+
+### Note Named Properties
+PidLidNoteColor                                        NoteColor                     0x8B00 NULL                          PT_LONG       MNID_ID     PSETID_Note
+PidLidNoteWidth                                        NoteWidth                     0x8B02 NULL                          PT_LONG       MNID_ID     PSETID_Note
+PidLidNoteHeight                                       NoteHeight                    0x8B03 NULL                          PT_LONG       MNID_ID     PSETID_Note
+PidLidNoteX                                            NoteX                         0x8B04 NULL                          PT_LONG       MNID_ID     PSETID_Note
+PidLidNoteY                                            NoteY                         0x8B05 NULL                          PT_LONG       MNID_ID     PSETID_Note
+
+
+
+### PS_PUBLIC_STRINGS
+PidLidCategories                                       Categories                    0x2328 NULL                          PT_MV_STRING8 MNID_ID     PS_PUBLIC_STRINGS
+PidNameApplicationName                                 NULL                          0x0000 AppName                       PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameAuthor                                          NULL                          0x0000 Author                        PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameByteCount                                       NULL                          0x0000 ByteCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameCategory                                        NULL                          0x0000 Category                      PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameCharacterCount                                  NULL                          0x0000 CharCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameComments                                        NULL                          0x0000 Comments                      PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameCompany                                         NULL                          0x0000 Company                       PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameCreateDateTimeReadOnly                          NULL                          0x0000 CreateDtmRo                   PT_SYSTIME    MNID_STRING PS_PUBLIC_STRINGS
+PidNameRightsManagementLicense                         NULL                          0x0000 DRMLicense                    PT_MV_BINARY  MNID_STRING PS_PUBLIC_STRINGS
+PidNameEditTime                                        NULL                          0x0000 EditTime                      PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameJunkEmailMoveStamp                              NULL                          0x0000 http://schemas.microsoft.com/exchange/junkemailmovestamp PT_LONG     MNID_STRING PS_PUBLIC_STRINGS
+PidNameHiddenCount                                     NULL                          0x0000 HiddenCount                   PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameKeywords                                        NULL                          0x0000 Keywords                      PT_MV_STRING8 MNID_STRING PS_PUBLIC_STRINGS
+PidNameLastAuthor                                      NULL                          0x0000 LastAuthor                    PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameLastPrinted                                     NULL                          0x0000 LastPrinted                   PT_SYSTIME    MNID_STRING PS_PUBLIC_STRINGS
+PidNameLastSaveDateTime                                NULL                          0x0000 LastSaveDtm                   PT_SYSTIME    MNID_STRING PS_PUBLIC_STRINGS
+PidNameLineCount                                       NULL                          0x0000 LineCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameManager                                         NULL                          0x0000 Manager                       PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameMultimediaClipCount                             NULL                          0x0000 MMClipCount                   PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameNoteCount                                       NULL                          0x0000 NoteCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameOMSAccountGuid                                  NULL                          0x0000 OMSAccountGuid                PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameOMSMobileModel                                  NULL                          0x0000 OMSMobileModel                PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameOMSGScheduleTime                                NULL                          0x0000 OMSScheduleTime               PT_SYSTIME    MNID_STRING PS_PUBLIC_STRINGS
+PidNameOMSServiceType                                  NULL                          0x0000 OMSServiceType                PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameOMSSourceType                                   NULL                          0x0000 OMSSourceType                 PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNamePhishingStamp                                   NULL                          0x0000 http://schemas.microsoft.com/outlook/phishingstamp       PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNamePageCount                                       NULL                          0x0000 PageCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameParagraphCount                                  NULL                          0x0000 ParCount                      PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNamePresentationFormat                              NULL                          0x0000 PresFormat                    PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameSecurity                                        NULL                          0x0000 Security                      PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameSlideCount                                      NULL                          0x0000 SlideCount                    PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+PidNameSubject                                         NULL                          0x0000 Subject                       PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameTemplate                                        NULL                          0x0000 Template                      PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameTitle                                           NULL                          0x0000 Title                         PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+PidNameWordCount                                       NULL                          0x0000 WordCount                     PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+NULL                                                   NULL                          0x0000 urn:schemas:contacts:fileas   PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+NULL                                                   NULL                          0x0000 urn:schemas:calendar:sequence PT_LONG       MNID_STRING PS_PUBLIC_STRINGS
+NULL                                                   NULL                          0x0000 urn:schemas:calendar:version  PT_UNICODE    MNID_STRING PS_PUBLIC_STRINGS
+
+
+### PS_INTERNET_HEADERS
+PidNameAcceptLanguage                                  AcceptLanguage                0x0000 Accept-Language               PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameBodyContentBase                                 BodyContentBase               0x0000 Content-Base                  PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameContentClass                                    NULL                          0x0000 Content-Class                 PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameContentTransferEncoding                         NULL                          0x0000 Content-Transfer-Encoding     PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameContentType                                     NULL                          0x0000 Content-Type                  PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameCrossReference                                  NULL                          0x0000 Xref                          PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingBrowseUrl                               NULL                          0x0000 X-Sharing-Browse-Url          PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingCapabilities                            NULL                          0x0000 X-Sharing-Capabilities        PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingConfigUrl                               NULL                          0x0000 X-Sharing-Config-Url          PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingExtendedCaps                            NULL                          0x0000 X-Sharing-Extended-Caps       PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingFlavor                                  NULL                          0x0000 X-Sharing-Flavor              PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingInstanceGuid                            NULL                          0x0000 X-Sharing-Instance-Guid       PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingLocalType                               NULL                          0x0000 X-Sharing-Local-Type          PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingProviderGuid                            NULL                          0x0000 X-Sharing-Provider-Guid       PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingProviderName                            NULL                          0x0000 X-Sharing-Provider-Name       PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingProviderUrl                             NULL                          0x0000 X-Sharing-Provider-Url        PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingRemoteName                              NULL                          0x0000 X-Sharing-Remote-Name         PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingRemotePath                              NULL                          0x0000 X-Sharing-Remote-Path         PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingRemoteStoreUid                          NULL                          0x0000 X-Sharing-Remote-Store-Uid    PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingRemoteType                              NULL                          0x0000 X-Sharing-Remote-Type         PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+PidNameXSharingRemoteUid                               NULL                          0x0000 X-Sharing-Remote-Uid          PT_UNICODE    MNID_STRING PS_INTERNET_HEADERS
+
+
+
+### PSETID_Attachment
+PidNameAttachmentMacContentType                        NULL                          0x0000 AttachmentMacContentType      PT_UNICODE    MNID_STRING PSETID_Attachment
+PidNameAttachmentMacInfo                               NULL                          0x0000 AttachmentMacInfo             PT_BINARY     MNID_STRING PSETID_Attachment
+
+
+### PSETID_UnifiedMessaging
+PidNameAudioNotes                                      UMAudioNotes                  0x0000 UMAudioNotes                  PT_UNICODE    MNID_STRING PSETID_UnifiedMessaging

Added: trunk/openchange/libmapi/conf/mapi-properties
===================================================================
--- trunk/openchange/libmapi/conf/mapi-properties	                        (rev 0)
+++ trunk/openchange/libmapi/conf/mapi-properties	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1545 @@
+#
+# OpenChange MAPI implementation.
+# MAPI property tags
+#
+# This file was originally taken from the Gnome Evolution project.
+# evolution/evolution-exchange/docs/mapi-properties
+#
+# For the OpenChange project, UNICODE properties (1f) have been
+# replaced by PT_STRING8 ones (1e)
+#
+# 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/>.
+#
+
+0x00010003  PR_ACKNOWLEDGEMENT_MODE
+0x0002000b  PR_ALTERNATE_RECIPIENT_ALLOWED
+0x00030102  PR_AUTHORIZING_USERS
+0x0004001e  PR_AUTO_FORWARD_COMMENT
+0x0005000b  PR_AUTO_FORWARDED
+0x00060102  PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID
+0x00070102  PR_CONTENT_CORRELATOR
+0x0008001e  PR_CONTENT_IDENTIFIER
+0x00090003  PR_CONTENT_LENGTH
+0x000a000b  PR_CONTENT_RETURN_REQUESTED
+0x000b0102  PR_CONVERSATION_KEY
+0x000c0102  PR_CONVERSION_EITS
+0x000d000b  PR_CONVERSION_WITH_LOSS_PROHIBITED
+0x000e0102  PR_CONVERTED_EITS
+0x000f0040  PR_DEFERRED_DELIVERY_TIME
+0x00100040  PR_DELIVER_TIME
+0x00110003  PR_DISCARD_REASON
+0x0012000b  PR_DISCLOSURE_OF_RECIPIENTS
+0x00130102  PR_DL_EXPANSION_HISTORY
+0x0014000b  PR_DL_EXPANSION_PROHIBITED
+0x00150040  PR_EXPIRY_TIME
+0x0016000b  PR_IMPLICIT_CONVERSION_PROHIBITED
+0x00170003  PR_IMPORTANCE
+0x00180102  PR_IPM_ID
+0x00190040  PR_LATEST_DELIVERY_TIME
+0x001a001e  PR_MESSAGE_CLASS
+0x001b0102  PR_MESSAGE_DELIVERY_ID
+0x001e0102  PR_MESSAGE_SECURITY_LABEL
+0x001f0102  PR_OBSOLETED_IPMS
+0x00200102  PR_ORIGINALLY_INTENDED_RECIPIENT_NAME
+0x00210102  PR_ORIGINAL_EITS
+0x00220102  PR_ORIGINATOR_CERTIFICATE
+0x0023000b  PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED
+0x00240102  PR_ORIGINATOR_RETURN_ADDRESS
+0x00250102  PR_PARENT_KEY
+0x00260003  PR_PRIORITY
+0x00270102  PR_ORIGIN_CHECK
+0x0028000b  PR_PROOF_OF_SUBMISSION_REQUESTED
+0x0029000b  PR_READ_RECEIPT_REQUESTED
+0x002a0040  PR_RECEIPT_TIME
+0x002b000b  PR_RECIPIENT_REASSIGNMENT_PROHIBITED
+0x002c0102  PR_REDIRECTION_HISTORY
+0x002d0102  PR_RELATED_IPMS
+0x002e0003  PR_ORIGINAL_SENSITIVITY
+0x002f001e  PR_LANGUAGES
+0x00300040  PR_REPLY_TIME
+0x00310102  PR_REPORT_TAG
+0x00320040  PR_REPORT_TIME
+0x0033000b  PR_RETURNED_IPM
+0x00340003  PR_SECURITY
+0x0035000b  PR_INCOMPLETE_COPY
+0x00360003  PR_SENSITIVITY
+0x0037001e  PR_SUBJECT
+0x00380102  PR_SUBJECT_IPM
+0x00390040  PR_CLIENT_SUBMIT_TIME
+0x003a001e  PR_REPORT_NAME
+0x003b0102  PR_SENT_REPRESENTING_SEARCH_KEY
+0x003c0102  PR_X400_CONTENT_TYPE
+0x003d001e  PR_SUBJECT_PREFIX
+0x003e0003  PR_NON_RECEIPT_REASON
+0x003f0102  PR_RECEIVED_BY_ENTRYID
+0x0040001e  PR_RECEIVED_BY_NAME
+0x00410102  PR_SENT_REPRESENTING_ENTRYID
+0x0042001e  PR_SENT_REPRESENTING_NAME
+0x00430102  PR_RCVD_REPRESENTING_ENTRYID
+0x0044001e  PR_RCVD_REPRESENTING_NAME
+0x00450102  PR_REPORT_ENTRYID
+0x00460102  PR_READ_RECEIPT_ENTRYID
+0x00470102  PR_MESSAGE_SUBMISSION_ID
+0x00480040  PR_PROVIDER_SUBMIT_TIME
+0x0049001e  PR_ORIGINAL_SUBJECT
+0x004a000b  PR_DISC_VAL
+0x004b001e  PR_ORIG_MESSAGE_CLASS
+0x004c0102  PR_ORIGINAL_AUTHOR_ENTRYID
+0x004d001e  PR_ORIGINAL_AUTHOR_NAME
+0x004e0040  PR_ORIGINAL_SUBMIT_TIME
+0x004f0102  PR_REPLY_RECIPIENT_ENTRIES
+0x0050001e  PR_REPLY_RECIPIENT_NAMES
+0x00510102  PR_RECEIVED_BY_SEARCH_KEY
+0x00520102  PR_RCVD_REPRESENTING_SEARCH_KEY
+0x00530102  PR_READ_RECEIPT_SEARCH_KEY
+0x00540102  PR_REPORT_SEARCH_KEY
+0x00550040  PR_ORIGINAL_DELIVERY_TIME
+0x00560102  PR_ORIGINAL_AUTHOR_SEARCH_KEY
+0x0057000b  PR_MESSAGE_TO_ME
+0x0058000b  PR_MESSAGE_CC_ME
+0x0059000b  PR_MESSAGE_RECIP_ME
+0x005a001e  PR_ORIGINAL_SENDER_NAME
+0x005b0102  PR_ORIGINAL_SENDER_ENTRYID
+0x005c0102  PR_ORIGINAL_SENDER_SEARCH_KEY
+0x005d001e  PR_ORIGINAL_SENT_REPRESENTING_NAME
+0x005e0102  PR_ORIGINAL_SENT_REPRESENTING_ENTRYID
+0x005f0102  PR_ORIGINAL_SENT_REPRESENTING_SEARCH_KEY
+0x00600040  PR_START_DATE
+0x00610040  PR_END_DATE
+0x00620003  PR_OWNER_APPT_ID
+0x0063000b  PR_RESPONSE_REQUESTED
+0x0064001e  PR_SENT_REPRESENTING_ADDRTYPE
+0x0065001e  PR_SENT_REPRESENTING_EMAIL_ADDRESS
+0x0066001e  PR_ORIGINAL_SENDER_ADDRTYPE
+0x0067001e  PR_ORIGINAL_SENDER_EMAIL_ADDRESS
+0x0068001e  PR_ORIGINAL_SENT_REPRESENTING_ADDRTYPE
+0x0069001e  PR_ORIGINAL_SENT_REPRESENTING_EMAIL_ADDRESS
+0x0070001e  PR_CONVERSATION_TOPIC
+0x00710102  PR_CONVERSATION_INDEX
+0x0072001e  PR_ORIGINAL_DISPLAY_BCC
+0x0073001e  PR_ORIGINAL_DISPLAY_CC
+0x0074001e  PR_ORIGINAL_DISPLAY_TO
+0x0075001e  PR_RECEIVED_BY_ADDRTYPE
+0x0076001e  PR_RECEIVED_BY_EMAIL_ADDRESS
+0x0077001e  PR_RCVD_REPRESENTING_ADDRTYPE
+0x0078001e  PR_RCVD_REPRESENTING_EMAIL_ADDRESS
+0x0079001e  PR_ORIGINAL_AUTHOR_ADDRTYPE
+0x007a001e  PR_ORIGINAL_AUTHOR_EMAIL_ADDRESS
+0x007b001e  PR_ORIGINALLY_INTENDED_RECIP_ADDRTYPE
+0x007c001e  PR_ORIGINALLY_INTENDED_RECIP_EMAIL_ADDRESS
+0x007d001e  PR_TRANSPORT_MESSAGE_HEADERS
+0x007e0102  PR_DELEGATION
+0x007f0102  PR_TNEF_CORRELATION_KEY
+0x0c000102  PR_CONTENT_INTEGRITY_CHECK
+0x0c010003  PR_EXPLICIT_CONVERSION
+0x0c02000b  PR_IPM_RETURN_REQUESTED
+0x0c030102  PR_MESSAGE_TOKEN
+0x0c040003  PR_NDR_REASON_CODE
+0x0c050003  PR_NDR_DIAG_CODE
+0x0c06000b  PR_NON_RECEIPT_NOTIFICATION_REQUESTED
+0x0c070003  PR_DELIVERY_POINT
+0x0c08000b  PR_ORIGINATOR_NON_DELIVERY_REPORT_REQUESTED
+0x0c090102  PR_ORIGINATOR_REQUESTED_ALTERNATE_RECIPIENT
+0x0c0a000b  PR_PHYSICAL_DELIVERY_BUREAU_FAX_DELIVERY
+0x0c0b0003  PR_PHYSICAL_DELIVERY_MODE
+0x0c0c0003  PR_PHYSICAL_DELIVERY_REPORT_REQUEST
+0x0c0d0102  PR_PHYSICAL_FORWARDING_ADDRESS
+0x0c0e000b  PR_PHYSICAL_FORWARDING_ADDRESS_REQUESTED
+0x0c0f000b  PR_PHYSICAL_FORWARDING_PROHIBITED
+0x0c100102  PR_PHYSICAL_RENDITION_ATTRIBUTES
+0x0c110102  PR_PROOF_OF_DELIVERY
+0x0c12000b  PR_PROOF_OF_DELIVERY_REQUESTED
+0x0c130102  PR_RECIPIENT_CERTIFICATE
+0x0c14001e  PR_RECIPIENT_NUMBER_FOR_ADVICE
+0x0c150003  PR_RECIPIENT_TYPE
+0x0c160003  PR_REGISTERED_MAIL_TYPE
+0x0c17000b  PR_REPLY_REQUESTED
+0x0c180003  PR_REQUESTED_DELIVERY_METHOD
+0x0c190102  PR_SENDER_ENTRYID
+0x0c1a001e  PR_SENDER_NAME
+0x0c1b001e  PR_SUPPLEMENTARY_INFO
+0x0c1c0003  PR_TYPE_OF_MTS_USER
+0x0c1d0102  PR_SENDER_SEARCH_KEY
+0x0c1e001e  PR_SENDER_ADDRTYPE
+0x0c1f001e  PR_SENDER_EMAIL_ADDRESS
+0x0c200003  PR_NDR_STATUS_CODE
+0x0e000014  PR_CURRENT_VERSION
+0x0e01000b  PR_DELETE_AFTER_SUBMIT
+0x0e02001e  PR_DISPLAY_BCC
+0x0e03001e  PR_DISPLAY_CC
+0x0e04001e  PR_DISPLAY_TO
+0x0e05001e  PR_PARENT_DISPLAY
+0x0e060040  PR_MESSAGE_DELIVERY_TIME
+0x0e070003  PR_MESSAGE_FLAGS
+0x0e080003  PR_MESSAGE_SIZE
+0x0e080014  PR_MESSAGE_SIZE_EXTENDED
+0x0e090102  PR_PARENT_ENTRYID
+0x0e0a0102  PR_SENTMAIL_ENTRYID
+0x0e0c000b  PR_CORRELATE
+0x0e0d0102  PR_CORRELATE_MTSID
+0x0e0e000b  PR_DISCRETE_VALUES
+0x0e0f000b  PR_RESPONSIBILITY
+0x0e100003  PR_SPOOLER_STATUS
+0x0e110003  PR_TRANSPORT_STATUS
+0x0e12000d  PR_MESSAGE_RECIPIENTS
+0x0e13000d  PR_MESSAGE_ATTACHMENTS
+0x0e140003  PR_SUBMIT_FLAGS
+0x0e150003  PR_RECIPIENT_STATUS
+0x0e160003  PR_TRANSPORT_KEY
+0x0e170003  PR_MSG_STATUS
+0x0e180003  PR_MESSAGE_DOWNLOAD_TIME
+0x0e190014  PR_CREATION_VERSION
+0x0e1a0014  PR_MODIFY_VERSION
+0x0e1b000b  PR_HASATTACH
+0x0e1c0003  PR_BODY_CRC
+0x0e1d001e  PR_NORMALIZED_SUBJECT
+0x0e1f000b  PR_RTF_IN_SYNC
+0x0e200003  PR_ATTACH_SIZE
+0x0e210003  PR_ATTACH_NUM
+0x0e22000b  PR_PREPROCESS
+0x0e230003  PR_INTERNET_ARTICLE_NUMBER
+0x0e24001e  PR_NEWSGROUP_NAME
+0x0e250102  PR_ORIGINATING_MTA_CERTIFICATE
+0x0e260102  PR_PROOF_OF_SUBMISSION
+0x0e270102  PR_NT_SECURITY_DESCRIPTOR
+0x0e580102  PR_CREATOR_SID
+0x0e590102  PR_LAST_MODIFIER_SID
+0x0e5e0048  PR_MIME_HANDLER_CLASSIDS
+0x0e610003  PR_URL_COMP_NAME_POSTFIX
+0x0e62000b  PR_URL_COMP_NAME_SET
+0x0e630003  PR_SUBFOLDER_CT
+0x0e640003  PR_DELETED_SUBFOLDER_CT
+0x0e660040  PR_DELETE_TIME
+0x0e670102  PR_AGE_LIMIT
+0x0e790003  PR_TRUST_SENDER
+0x0e960102  PR_ATTACH_VIRUS_SCAN_INFO
+0x0ff40003  PR_ACCESS						PidTagAccess
+0x0ff50003  PR_ROW_TYPE
+0x0ff60102  PR_INSTANCE_KEY
+0x0ff70003  PR_ACCESS_LEVEL
+0x0ff80102  PR_MAPPING_SIGNATURE
+0x0ff90102  PR_RECORD_KEY
+0x0ffa0102  PR_STORE_RECORD_KEY
+0x0ffb0102  PR_STORE_ENTRYID
+0x0ffc0102  PR_MINI_ICON
+0x0ffd0102  PR_ICON
+0x0ffe0003  PR_OBJECT_TYPE
+0x0fff0102  PR_ENTRYID
+0x1000001e  PR_BODY
+0x1001001e  PR_REPORT_TEXT
+0x10020102  PR_ORIGINATOR_AND_DL_EXPANSION_HISTORY
+0x10030102  PR_REPORTING_DL_NAME
+0x10040102  PR_REPORTING_MTA_CERTIFICATE
+0x10060003  PR_RTF_SYNC_BODY_CRC
+0x10070003  PR_RTF_SYNC_BODY_COUNT
+0x1008001e  PR_RTF_SYNC_BODY_TAG
+0x10090102  PR_RTF_COMPRESSED
+0x10100003  PR_RTF_SYNC_PREFIX_COUNT
+0x10110003  PR_RTF_SYNC_TRAILING_COUNT
+0x10120102  PR_ORIGINALLY_INTENDED_RECIP_ENTRYID
+0x1013001e  PR_BODY_HTML
+0x10130102  PR_HTML
+0x1030001e  PR_INTERNET_APPROVED
+0x1031001e  PR_INTERNET_CONTROL
+0x1032001e  PR_INTERNET_DISTRIBUTION
+0x1033001e  PR_INTERNET_FOLLOWUP_TO
+0x10340003  PR_INTERNET_LINES
+0x1035001e  PR_INTERNET_MESSAGE_ID
+0x1036001e  PR_INTERNET_NEWSGROUPS
+0x1037001e  PR_INTERNET_ORGANIZATION
+0x1038001e  PR_INTERNET_NNTP_PATH
+0x1039001e  PR_INTERNET_REFERENCES
+0x103a001e  PR_SUPERSEDES
+0x103b0102  PR_POST_FOLDER_ENTRIES
+0x103c001e  PR_POST_FOLDER_NAMES
+0x103d0102  PR_POST_REPLY_FOLDER_ENTRIES
+0x103e001e  PR_POST_REPLY_FOLDER_NAMES
+0x103f0102  PR_POST_REPLY_DENIED
+0x1040001e  PR_NNTP_XREF
+0x1041001e  PR_INTERNET_PRECEDENCE
+0x1042001e  PR_IN_REPLY_TO_ID
+0x1043001e  PR_LIST_HELP
+0x1044001e  PR_LIST_SUBSCRIBE
+0x1045001e  PR_LIST_UNSUBSCRIBE
+0x10800003  PR_ICON_INDEX
+0x10810003  PR_ACTION_FLAG
+0x10820040  PR_ACTION_DATE
+0x10900003  PR_FLAG_STATUS
+0x10910040  PR_FLAG_COMPLETE
+0x10c00102  PR_SMTP_TEMP_TBL_DATA
+0x10c10003  PR_SMTP_TEMP_TBL_DATA_2
+0x10c20102  PR_SMTP_TEMP_TBL_DATA_3
+0x10c30040  PR_CAL_START_TIME
+0x10c40040  PR_CAL_END_TIME
+0x10c50040  PR_CAL_RECURRING_ID
+0x10c6001e  PR_DAV_SUBMIT_DATA
+0x10c70003  PR_CDO_EXPANSION_INDEX
+0x10c80102  PR_IFS_INTERNAL_DATA
+0x10ca0040  PR_CAL_REMINDER_NEXT_TIME
+0x10f1001e  PR_OWA_URL
+0x10f2000b  PR_DISABLE_FULL_FIDELITY
+0x10f3001e  PR_URL_COMP_NAME
+0x10f4000b  PR_ATTR_HIDDEN
+0x10f5000b  PR_ATTR_SYSTEM
+0x10f6000b  PR_ATTR_READONLY
+0x11000102  PR_P1_CONTENT
+0x11010102  PR_P1_CONTENT_TYPE
+0x30000003  PR_ROWID
+0x3001001e  PR_DISPLAY_NAME				PidTagDisplayName
+0x3002001e  PR_ADDRTYPE
+0x3003001e  PR_EMAIL_ADDRESS
+0x3004001e  PR_COMMENT
+0x30050003  PR_DEPTH
+0x3006001e  PR_PROVIDER_DISPLAY
+0x30070040  PR_CREATION_TIME
+0x30080040  PR_LAST_MODIFICATION_TIME
+0x30090003  PR_RESOURCE_FLAGS
+0x300a001e  PR_PROVIDER_DLL_NAME
+0x300b0102  PR_SEARCH_KEY
+0x300c0102  PR_PROVIDER_UID
+0x300d0003  PR_PROVIDER_ORDINAL
+0x3301001e  PR_FORM_VERSION
+0x33020048  PR_FORM_CLSID
+0x3303001e  PR_FORM_CONTACT_NAME
+0x3304001e  PR_FORM_CATEGORY
+0x3305001e  PR_FORM_CATEGORY_SUB
+0x33061003  PR_FORM_HOST_MAP
+0x3307000b  PR_FORM_HIDDEN
+0x3308001e  PR_FORM_DESIGNER_NAME
+0x33090048  PR_FORM_DESIGNER_GUID
+0x330a0003  PR_FORM_MESSAGE_BEHAVIOR
+0x3400000b  PR_DEFAULT_STORE
+0x340d0003  PR_STORE_SUPPORT_MASK
+0x340e0003  PR_STORE_STATE
+0x34100102  PR_IPM_SUBTREE_SEARCH_KEY
+0x34110102  PR_IPM_OUTBOX_SEARCH_KEY
+0x34120102  PR_IPM_WASTEBASKET_SEARCH_KEY
+0x34130102  PR_IPM_SENTMAIL_SEARCH_KEY
+0x34140102  PR_MDB_PROVIDER
+0x3415000d  PR_RECEIVE_FOLDER_SETTINGS
+0x35df0003  PR_VALID_FOLDER_MASK
+0x35e00102  PR_IPM_SUBTREE_ENTRYID
+0x35e20102  PR_IPM_OUTBOX_ENTRYID
+0x35e30102  PR_IPM_WASTEBASKET_ENTRYID
+0x35e40102  PR_IPM_SENTMAIL_ENTRYID
+0x35e50102  PR_VIEWS_ENTRYID
+0x35e60102  PR_COMMON_VIEWS_ENTRYID
+0x35e70102  PR_FINDER_ENTRYID
+0x36000003  PR_CONTAINER_FLAGS
+0x36010003  PR_FOLDER_TYPE
+0x36020003  PR_CONTENT_COUNT				PidTagContentCount
+0x36030003  PR_CONTENT_UNREAD				PidTagContentUnreadCount
+0x3604000d  PR_CREATE_TEMPLATES
+0x3605000d  PR_DETAILS_TABLE
+0x3607000d  PR_SEARCH
+0x3609000b  PR_SELECTABLE
+0x360a000b  PR_SUBFOLDERS				PidTagSubFolders
+0x360b0003  PR_STATUS
+0x360c001e  PR_ANR
+0x360d1003  PR_CONTENTS_SORT_ORDER
+0x360e000d  PR_CONTAINER_HIERARCHY
+0x360f000d  PR_CONTAINER_CONTENTS
+0x3610000d  PR_FOLDER_ASSOCIATED_CONTENTS
+0x36110102  PR_DEF_CREATE_DL
+0x36120102  PR_DEF_CREATE_MAILUSER
+0x3613001e  PR_CONTAINER_CLASS
+0x36140014  PR_CONTAINER_MODIFY_VERSION
+0x36150102  PR_AB_PROVIDER_ID
+0x36160102  PR_DEFAULT_VIEW_ENTRYID
+0x36170003  PR_ASSOC_CONTENT_COUNT
+0x361c0102  PR_PACKED_NAME_PROPS
+0x36d00102  PR_IPM_APPOINTMENT_ENTRYID			PidTagIpmAppointmentEntryId
+0x36d10102  PR_IPM_CONTACT_ENTRYID			PidTagIpmContactEntryId
+0x36d20102  PR_IPM_JOURNAL_ENTRYID			PidTagIpmJournalEntryId
+0x36d30102  PR_IPM_NOTE_ENTRYID				PidTagIpmNoteEntryId
+0x36d40102  PR_IPM_TASK_ENTRYID				PidTagIpmTaskEntryId
+0x36d50102  PR_REMINDERS_ONLINE_ENTRYID			PidTagRemindersOnlineEntryId
+0x36d60102  PR_REMINDERS_OFFLINE_ENTRYID
+0x36d70102  PR_IPM_DRAFTS_ENTRYID			PidTagIpmDraftsEntryId
+0x36d81102  PR_OUTLOOK_2003_ENTRYIDS
+0x36df0102  PR_FOLDER_WEBVIEWINFO
+0x36e00102  PR_FOLDER_XVIEWINFO_E
+0x36e10003  PR_FOLDER_VIEWS_ONLY
+0x36e41102  PR_FREEBUSY_ENTRYIDS
+0x36e5001e  PR_DEF_MSG_CLASS
+0x36e6001e  PR_DEF_FORM_NAME
+0x36e9000b  PR_GENERATE_EXCHANGE_VIEWS
+0x36eb0102  PR_FOLDER_VIEWLIST
+0x36ec0003  PR_AGING_PERIOD
+0x36ee0003  PR_AGING_GRANULARITY
+0x37000102  PR_ATTACHMENT_X400_PARAMETERS
+0x3701000d  PR_ATTACH_DATA_OBJ
+0x37010102  PR_ATTACH_DATA_BIN
+0x37020102  PR_ATTACH_ENCODING
+0x3703001e  PR_ATTACH_EXTENSION
+0x3704001e  PR_ATTACH_FILENAME
+0x37050003  PR_ATTACH_METHOD
+0x3707001e  PR_ATTACH_LONG_FILENAME
+0x3708001e  PR_ATTACH_PATHNAME
+0x37090102  PR_ATTACH_RENDERING
+0x370a0102  PR_ATTACH_TAG
+0x370b0003  PR_RENDERING_POSITION
+0x370c001e  PR_ATTACH_TRANSPORT_NAME
+0x370d001e  PR_ATTACH_LONG_PATHNAME
+0x370e001e  PR_ATTACH_MIME_TAG
+0x370f0102  PR_ATTACH_ADDITIONAL_INFO
+0x3712001e  PR_ATTACH_CONTENT_ID
+0x3713001e  PR_ATTACH_CONTENT_LOCATION
+0x37140003  PR_ATTACH_FLAGS
+0x3716001e  PR_ATTACH_CONTENT_DISPOSITION
+0x38800102  PR_SYNCEVENT_SUPPRESS_GUID
+0x39000003  PR_DISPLAY_TYPE
+0x39020102  PR_TEMPLATEID
+0x39040102  PR_PRIMARY_CAPABILITY
+0x39fe001e  PR_SMTP_ADDRESS
+0x39ff001e  PR_7BIT_DISPLAY_NAME
+0x3a00001e  PR_ACCOUNT
+0x3a010102  PR_ALTERNATE_RECIPIENT
+0x3a02001e  PR_CALLBACK_TELEPHONE_NUMBER
+0x3a03000b  PR_CONVERSION_PROHIBITED
+0x3a04000b  PR_DISCLOSE_RECIPIENTS
+0x3a05001e  PR_GENERATION
+0x3a06001e  PR_GIVEN_NAME
+0x3a07001e  PR_GOVERNMENT_ID_NUMBER
+0x3a08001e  PR_OFFICE_TELEPHONE_NUMBER
+0x3a09001e  PR_HOME_TELEPHONE_NUMBER
+0x3a0a001e  PR_INITIALS
+0x3a0b001e  PR_KEYWORD
+0x3a0c001e  PR_LANGUAGE
+0x3a0d001e  PR_LOCATION
+0x3a0e000b  PR_MAIL_PERMISSION
+0x3a0f001e  PR_MHS_COMMON_NAME
+0x3a10001e  PR_ORGANIZATIONAL_ID_NUMBER
+0x3a11001e  PR_SURNAME
+0x3a120102  PR_ORIGINAL_ENTRYID
+0x3a13001e  PR_ORIGINAL_DISPLAY_NAME
+0x3a140102  PR_ORIGINAL_SEARCH_KEY
+0x3a15001e  PR_POSTAL_ADDRESS
+0x3a16001e  PR_COMPANY_NAME
+0x3a17001e  PR_TITLE
+0x3a18001e  PR_DEPARTMENT_NAME
+0x3a19001e  PR_OFFICE_LOCATION
+0x3a1a001e  PR_PRIMARY_TELEPHONE_NUMBER
+0x3a1b001e  PR_OFFICE2_TELEPHONE_NUMBER
+0x3a1c001e  PR_MOBILE_TELEPHONE_NUMBER
+0x3a1d001e  PR_RADIO_TELEPHONE_NUMBER
+0x3a1e001e  PR_CAR_TELEPHONE_NUMBER
+0x3a1f001e  PR_OTHER_TELEPHONE_NUMBER
+0x3a20001e  PR_TRANSMITTABLE_DISPLAY_NAME
+0x3a21001e  PR_PAGER_TELEPHONE_NUMBER
+0x3a220102  PR_USER_CERTIFICATE
+0x3a23001e  PR_PRIMARY_FAX_NUMBER
+0x3a24001e  PR_BUSINESS_FAX_NUMBER
+0x3a25001e  PR_HOME_FAX_NUMBER
+0x3a26001e  PR_COUNTRY
+0x3a27001e  PR_LOCALITY
+0x3a28001e  PR_STATE_OR_PROVINCE
+0x3a29001e  PR_STREET_ADDRESS
+0x3a2a001e  PR_POSTAL_CODE
+0x3a2b001e  PR_POST_OFFICE_BOX
+0x3a2c001e  PR_TELEX_NUMBER
+0x3a2d001e  PR_ISDN_NUMBER
+0x3a2e001e  PR_ASSISTANT_TELEPHONE_NUMBER
+0x3a2f001e  PR_HOME2_TELEPHONE_NUMBER
+0x3a30001e  PR_ASSISTANT
+0x3a40000b  PR_SEND_RICH_INFO
+0x3a410040  PR_WEDDING_ANNIVERSARY
+0x3a420040  PR_BIRTHDAY
+0x3a43001e  PR_HOBBIES
+0x3a44001e  PR_MIDDLE_NAME
+0x3a45001e  PR_DISPLAY_NAME_PREFIX
+0x3a46001e  PR_PROFESSION
+0x3a47001e  PR_PREFERRED_BY_NAME
+0x3a48001e  PR_SPOUSE_NAME
+0x3a49001e  PR_COMPUTER_NETWORK_NAME
+0x3a4a001e  PR_CUSTOMER_ID
+0x3a4b001e  PR_TTYTDD_PHONE_NUMBER
+0x3a4c001e  PR_FTP_SITE
+0x3a4d0002  PR_GENDER
+0x3a4e001e  PR_MANAGER_NAME
+0x3a4f001e  PR_NICKNAME
+0x3a50001e  PR_PERSONAL_HOME_PAGE
+0x3a51001e  PR_BUSINESS_HOME_PAGE
+0x3a520048  PR_CONTACT_VERSION
+0x3a531102  PR_CONTACT_ENTRYIDS
+0x3a54101e  PR_CONTACT_ADDRTYPES
+0x3a550003  PR_CONTACT_DEFAULT_ADDRESS_INDEX
+0x3a56101e  PR_CONTACT_EMAIL_ADDRESSES
+0x3a57001e  PR_COMPANY_MAIN_PHONE_NUMBER
+0x3a58101e  PR_CHILDRENS_NAMES
+0x3a59001e  PR_HOME_ADDRESS_CITY
+0x3a5a001e  PR_HOME_ADDRESS_COUNTRY
+0x3a5b001e  PR_HOME_ADDRESS_POSTAL_CODE
+0x3a5c001e  PR_HOME_ADDRESS_STATE_OR_PROVINCE
+0x3a5d001e  PR_HOME_ADDRESS_STREET
+0x3a5e001e  PR_HOME_ADDRESS_POST_OFFICE_BOX
+0x3a5f001e  PR_OTHER_ADDRESS_CITY
+0x3a60001e  PR_OTHER_ADDRESS_COUNTRY
+0x3a61001e  PR_OTHER_ADDRESS_POSTAL_CODE
+0x3a62001e  PR_OTHER_ADDRESS_STATE_OR_PROVINCE
+0x3a63001e  PR_OTHER_ADDRESS_STREET
+0x3a64001e  PR_OTHER_ADDRESS_POST_OFFICE_BOX
+0x3a701102  PR_USER_X509_CERTIFICATE
+0x3a710003  PR_SEND_INTERNET_ENCODING
+0x3d000102  PR_STORE_PROVIDERS
+0x3d010102  PR_AB_PROVIDERS
+0x3d020102  PR_TRANSPORT_PROVIDERS
+0x3d04000b  PR_DEFAULT_PROFILE
+0x3d051102  PR_AB_SEARCH_PATH
+0x3d060102  PR_AB_DEFAULT_DIR
+0x3d070102  PR_AB_DEFAULT_PAB
+0x3d080102  PR_FILTERING_HOOKS
+0x3d09001e  PR_SERVICE_NAME
+0x3d0a001e  PR_SERVICE_DLL_NAME
+0x3d0b001e  PR_SERVICE_ENTRY_NAME
+0x3d0c0102  PR_SERVICE_UID
+0x3d0d0102  PR_SERVICE_EXTRA_UIDS
+0x3d0e0102  PR_SERVICES
+0x3d0f101e  PR_SERVICE_SUPPORT_FILES
+0x3d10101e  PR_SERVICE_DELETE_FILES
+0x3d110102  PR_AB_SEARCH_PATH_UPDATE
+0x3d12001e  PR_PROFILE_NAME
+0x3d13001e  PR_SERVICE_INSTALL_ID
+0x3d210102  PR_ADMIN_SECURITY_DESCRIPTOR
+0x3e00001e  PR_IDENTITY_DISPLAY
+0x3e010102  PR_IDENTITY_ENTRYID
+0x3e020003  PR_RESOURCE_METHODS
+0x3e030003  PR_RESOURCE_TYPE
+0x3e040003  PR_STATUS_CODE
+0x3e050102  PR_IDENTITY_SEARCH_KEY
+0x3e060102  PR_OWN_STORE_ENTRYID
+0x3e07001e  PR_RESOURCE_PATH
+0x3e08001e  PR_STATUS_STRING
+0x3e09000b  PR_X400_DEFERRED_DELIVERY_CANCEL
+0x3e0a0102  PR_HEADER_FOLDER_ENTRYID
+0x3e0b0003  PR_REMOTE_PROGRESS
+0x3e0c001e  PR_REMOTE_PROGRESS_TEXT
+0x3e0d000b  PR_REMOTE_VALIDATE_OK
+0x3f000003  PR_CONTROL_FLAGS
+0x3f010102  PR_CONTROL_STRUCTURE
+0x3f020003  PR_CONTROL_TYPE
+0x3f030003  PR_DELTAX
+0x3f040003  PR_DELTAY
+0x3f050003  PR_XPOS
+0x3f060003  PR_YPOS
+0x3f070102  PR_CONTROL_ID
+0x3f080003  PR_INITIAL_DETAILS_PANE
+0x3f800014  PR_DID
+0x3f810014  PR_SEQID
+0x3f820014  PR_DRAFTID
+0x3f830040  PR_CHECK_IN_TIME
+0x3f84001e  PR_CHECK_IN_COMMENT
+0x3f850003  PR_VERSION_OP_CODE
+0x3f860102  PR_VERSION_OP_DATA
+0x3f870003  PR_VERSION_SEQUENCE_NUMBER
+0x3f880014  PR_ATTACH_ID
+0x3f8d001e  PR_PKM_DOC_STATUS
+0x3f8e101e  PR_MV_PKM_OPERATION_REQ
+0x3f8f001e  PR_PKM_DOC_INTERNAL_STATE
+0x3f900002  PR_VERSIONING_FLAGS
+0x3f910102  PR_PKM_LAST_UNAPPROVED_VID
+0x3f92101e  PR_MV_PKM_VERSION_LABELS
+0x3f93101e  PR_MV_PKM_VERSION_STATUS
+0x3f940102  PR_PKM_INTERNAL_DATA
+0x3fc90102  PR_LAST_CONFLICT
+0x3fca0102  PR_CONFLICT_MSG_KEY
+0x3fd00102  PR_REPL_HEADER
+0x3fd10102  PR_REPL_STATUS
+0x3fd20102  PR_REPL_CHANGES
+0x3fd30102  PR_REPL_RGM
+0x3fd40102  PR_RMI
+0x3fd50102  PR_INTERNAL_POST_REPLY
+0x3fd60040  PR_NTSD_MODIFICATION_TIME
+0x3fd8001e  PR_PREVIEW_UNREAD
+0x3fd9001e  PR_PREVIEW
+0x3fda001e  PR_ABSTRACT
+0x3fdb0003  PR_DL_REPORT_FLAGS
+0x3fdc0102  PR_BILATERAL_INFO
+0x3fdd0003  PR_MSG_BODY_ID
+0x3fde0003  PR_INTERNET_CPID
+0x3fdf0003  PR_AUTO_RESPONSE_SUPPRESS
+0x3fe0000d  PR_ACL_TABLE
+0x3fe00102  PR_ACL_DATA
+0x3fe1000d  PR_RULES_TABLE
+0x3fe10102  PR_RULES_DATA
+0x3fe20003  PR_FOLDER_DESIGN_FLAGS
+0x3fe3000b  PR_DELEGATED_BY_RULE
+0x3fe4000b  PR_DESIGN_IN_PROGRESS
+0x3fe5000b  PR_SECURE_ORIGINATION
+0x3fe6000b  PR_PUBLISH_IN_ADDRESS_BOOK
+0x3fe70003  PR_RESOLVE_METHOD
+0x3fe8001e  PR_ADDRESS_BOOK_DISPLAY_NAME
+0x3fe90003  PR_EFORMS_LOCALE_ID
+0x3fea000b  PR_HAS_DAMS
+0x3feb0003  PR_DEFERRED_SEND_NUMBER
+0x3fec0003  PR_DEFERRED_SEND_UNITS
+0x3fed0003  PR_EXPIRY_NUMBER
+0x3fee0003  PR_EXPIRY_UNITS
+0x3fef0040  PR_DEFERRED_SEND_TIME
+0x3ff00102  PR_CONFLICT_ENTRYID
+0x3ff10003  PR_MESSAGE_LOCALE_ID
+0x3ff20102  PR_RULE_TRIGGER_HISTORY
+0x3ff30102  PR_MOVE_TO_STORE_ENTRYID
+0x3ff40102  PR_MOVE_TO_FOLDER_ENTRYID
+0x3ff50003  PR_STORAGE_QUOTA_LIMIT
+0x3ff60003  PR_EXCESS_STORAGE_USED
+0x3ff7001e  PR_SVR_GENERATING_QUOTA_MSG
+0x3ff8001e  PR_CREATOR_NAME
+0x3ff90102  PR_CREATOR_ENTRYID
+0x3ffa001e  PR_LAST_MODIFIER_NAME
+0x3ffb0102  PR_LAST_MODIFIER_ENTRYID
+0x3ffc001e  PR_REPLY_RECIPIENT_SMTP_PROXIES
+0x3ffd0003  PR_MESSAGE_CODEPAGE
+0x3ffe0102  PR_EXTENDED_ACL_DATA
+0x3fff000b  PR_FROM_I_HAVE
+0x40000003  PR_NEW_ATTACH
+0x40010003  PR_START_EMBED
+0x40020003  PR_END_EMBED
+0x40030003  PR_START_RECIP
+0x40040003  PR_END_RECIP
+0x40050003  PR_END_CC_RECIP
+0x40060003  PR_END_BCC_RECIP
+0x40070003  PR_END_P1_RECIP
+0x40090003  PR_START_TOP_FLD
+0x400a0003  PR_START_SUB_FLD
+0x400b0003  PR_END_FOLDER
+0x400c0003  PR_START_MESSAGE
+0x400d0003  PR_END_MESSAGE
+0x400e0003  PR_END_ATTACH
+0x400f0003  PR_EC_WARNING
+0x40100003  PR_START_FAI_MSG
+0x40110102  PR_NEW_FX_FOLDER
+0x40120003  PR_INCR_SYNC_CHG
+0x40130003  PR_INCR_SYNC_DEL
+0x40140003  PR_INCR_SYNC_END
+0x40150003  PR_INCR_SYNC_MSG
+0x40160003  PR_FX_DEL_PROP
+0x40170003  PR_IDSET_GIVEN
+0x40190003  PR_SENDER_FLAGS
+0x401a0003  PR_SENT_REPRESENTING_FLAGS
+0x401b0003  PR_RCVD_BY_FLAGS
+0x401c0003  PR_RCVD_REPRESENTING_FLAGS
+0x401d0003  PR_ORIGINAL_SENDER_FLAGS
+0x401e0003  PR_ORIGINAL_SENT_REPRESENTING_FLAGS
+0x401f0003  PR_REPORT_FLAGS
+0x40200003  PR_READ_RECEIPT_FLAGS
+0x4021000b  PR_SOFT_DELETES
+0x402c0102  PR_MESSAGE_SUBMISSION_ID_FROM_CLIENT
+0x4030001e  PR_SENDER_SIMPLE_DISP_NAME
+0x4031001e  PR_SENT_REPRESENTING_SIMPLE_DISP_NAME
+0x4038001e  PR_CREATOR_SIMPLE_DISP_NAME
+0x403d001e  PR_ORG_ADDR_TYPE
+0x403e001e  PR_ORG_EMAIL_ADDR
+0x40590003  PR_CREATOR_FLAGS
+0x405a0003  PR_MODIFIER_FLAGS
+0x405b0003  PR_ORIGINATOR_FLAGS
+0x405c0003  PR_REPORT_DESTINATION_FLAGS
+0x405d0003  PR_ORIGINAL_AUTHOR_FLAGS
+0x40610102  PR_ORIGINATOR_SEARCH_KEY
+0x40640102  PR_REPORT_DESTINATION_SEARCH_KEY
+0x40650003  PR_ER_FLAG
+0x40680102  PR_INTERNET_SUBJECT
+0x40690102  PR_INTERNET_SENT_REPRESENTING_NAME
+0x40760003  PR_CONTENT_FILTER_SCL
+0x59020003  PR_INET_MAIL_OVERRIDE_FORMAT
+0x59090003  PR_MSG_EDITOR_FORMAT
+0x5ff6001e  PR_RECIPIENT_DISPLAY_NAME
+0x5ff70102  PR_RECIPIENT_ENTRYID
+0x5ffb0040  PR_RECIPIENT_TRACKSTATUS_ME
+0x5ffd0003  PR_RECIPIENTS_FLAGS
+0x5fff0003  PR_RECIPIENT_TRACKSTATUS
+0x60010003  PR_DOTSTUFF_STATE
+0x65a00014  PR_RULE_SERVER_RULE_ID
+0x65c20102  PR_REPLY_TEMPLATE_ID
+0x65e00102  PR_SOURCE_KEY
+0x65e10102  PR_PARENT_SOURCE_KEY
+0x65e20102  PR_CHANGE_KEY
+0x65e30102  PR_PREDECESSOR_CHANGE_LIST
+0x65e40003  PR_SYNCHRONIZE_FLAGS
+0x65e5000b  PR_AUTO_ADD_NEW_SUBS
+0x65e6000b  PR_NEW_SUBS_GET_AUTO_ADD
+0x65e7001e  PR_MESSAGE_SITE_NAME
+0x65e8000b  PR_MESSAGE_PROCESSED
+0x65e90003  PR_RULE_MSG_STATE
+0x65ea0003  PR_RULE_MSG_USER_FLAGS
+0x65eb001e  PR_RULE_MSG_PROVIDER
+0x65ec001e  PR_RULE_MSG_NAME
+0x65ed0003  PR_RULE_MSG_LEVEL
+0x65ee0102  PR_RULE_MSG_PROVIDER_DATA
+0x65ef0102  PR_RULE_MSG_ACTIONS
+0x65f00102  PR_RULE_MSG_CONDITION
+0x65f10003  PR_RULE_MSG_CONDITION_LCID
+0x65f20002  PR_RULE_MSG_VERSION
+0x65f30003  PR_RULE_MSG_SEQUENCE
+0x65f4000b  PR_PREVENT_MSG_CREATE
+0x65f50040  PR_IMAP_INTERNAL_DATE
+0x66000003  PR_PROFILE_VERSION
+0x66010003  PR_PROFILE_CONFIG_FLAGS
+0x6602001e  PR_PROFILE_HOME_SERVER
+0x6603001e  PR_PROFILE_USER
+0x66040003  PR_PROFILE_CONNECT_FLAGS
+0x66050003  PR_PROFILE_TRANSPORT_FLAGS
+0x66060003  PR_PROFILE_UI_STATE
+0x6607001e  PR_PROFILE_UNRESOLVED_NAME
+0x6608001e  PR_PROFILE_UNRESOLVED_SERVER
+0x66090003  PR_PROFILE_OPEN_FLAGS
+0x6609001e  PR_PROFILE_BINDING_ORDER
+0x660a0003  PR_PROFILE_TYPE
+0x660b001e  PR_PROFILE_MAILBOX
+0x660c001e  PR_PROFILE_SERVER
+0x660d0003  PR_PROFILE_MAX_RESTRICT
+0x660e001e  PR_PROFILE_AB_FILES_PATH
+0x660f001e  PR_PROFILE_FAVFLD_DISPLAY_NAME
+0x6610001e  PR_PROFILE_OFFLINE_STORE_PATH
+0x66110102  PR_PROFILE_OFFLINE_INFO
+0x6612001e  PR_PROFILE_HOME_SERVER_DN
+0x6613101e  PR_PROFILE_HOME_SERVER_ADDRS
+0x6614001e  PR_PROFILE_SERVER_DN
+0x6615001e  PR_PROFILE_FAVFLD_COMMENT
+0x6616001e  PR_PROFILE_ALLPUB_DISPLAY_NAME
+0x6617001e  PR_PROFILE_ALLPUB_COMMENT
+0x66180003  PR_DISABLE_WINSOCK
+0x6618000b  PR_IN_TRANSIT
+0x66190003  PR_PROFILE_AUTH_PACKAGE
+0x66190102  PR_USER_ENTRYID
+0x661a001e  PR_USER_NAME
+0x661b0102  PR_MAILBOX_OWNER_ENTRYID
+0x661c001e  PR_MAILBOX_OWNER_NAME
+0x661d000b  PR_OOF_STATE
+0x661e0102  PR_SCHEDULE_FOLDER_ENTRYID
+0x661f0102  PR_IPM_DAF_ENTRYID
+0x66200102  PR_NON_IPM_SUBTREE_ENTRYID
+0x66210102  PR_EFORMS_REGISTRY_ENTRYID
+0x66220102  PR_SPLUS_FREE_BUSY_ENTRYID
+0x6623001e  PR_HIERARCHY_SERVER
+0x66230102  PR_OFFLINE_ADDRBOOK_ENTRYID
+0x66240102  PR_EFORMS_FOR_LOCALE_ENTRYID
+0x66250102  PR_FREE_BUSY_FOR_LOCAL_SITE_ENTRYID
+0x66260102  PR_ADDRBOOK_FOR_LOCAL_SITE_ENTRYID
+0x66270102  PR_OFFLINE_MESSAGE_ENTRYID
+0x66280102  PR_GW_MTSIN_ENTRYID
+0x66290102  PR_GW_MTSOUT_ENTRYID
+0x662a000b  PR_TRANSFER_ENABLED
+0x662b0102  PR_TEST_LINE_SPEED
+0x662c000d  PR_HIERARCHY_SYNCHRONIZER
+0x662d000d  PR_CONTENTS_SYNCHRONIZER
+0x662e000d  PR_COLLECTOR
+0x662f000d  PR_FAST_TRANSFER
+0x66300102  PR_IPM_FAVORITES_ENTRYID
+0x66310102  PR_IPM_PUBLIC_FOLDERS_ENTRYID
+0x6632000b  PR_STORE_OFFLINE
+0x6634000d  PR_CHANGE_ADVISOR
+0x6635001e  PR_FAVORITES_DEFAULT_NAME
+0x66360102  PR_SYS_CONFIG_FOLDER_ENTRYID
+0x66370048  PR_CHANGE_NOTIFICATION_GUID
+0x66380003  PR_FOLDER_CHILD_COUNT
+0x66390003  PR_RIGHTS
+0x663a000b  PR_HAS_RULES
+0x663b0102  PR_ADDRESS_BOOK_ENTRYID
+0x663c0102  PR_PUBLIC_FOLDER_ENTRYID
+0x663d0003  PR_OFFLINE_FLAGS
+0x663e0003  PR_HIERARCHY_CHANGE_NUM
+0x663f000b  PR_HAS_MODERATOR_RULES
+0x66400003  PR_DELETED_MSG_COUNT
+0x66410003  PR_DELETED_FOLDER_COUNT
+0x66420040  PR_OLDEST_DELETED_ON
+0x66430003  PR_DELETED_ASSOC_MSG_COUNT
+0x6644001e  PR_REPLICA_SERVER
+0x66450102  PR_CLIENT_ACTIONS
+0x66460102  PR_DAM_ORIGINAL_ENTRYID
+0x6647000b  PR_DAM_BACK_PATCHED
+0x66480003  PR_RULE_ERROR
+0x66490003  PR_RULE_ACTION_TYPE
+0x664a000b  PR_HAS_NAMED_PROPERTIES
+0x664b0014  PR_REPLICA_VERSION
+0x66500003  PR_RULE_ACTION_NUMBER
+0x66510102  PR_RULE_FOLDER_ENTRYID
+0x66520102  PR_ACTIVE_USER_ENTRYID
+0x66530003  PR_0X400_ENVELOPE_TYPE
+0x66540040  PR_MSG_FOLD_TIME
+0x66550102  PR_ICS_CHANGE_KEY
+0x66580003  PR_GW_ADMIN_OPERATIONS
+0x66590102  PR_INTERNET_CONTENT
+0x665a000b  PR_HAS_ATTACH_FROM_IMAIL
+0x665b001e  PR_ORIGINATOR_NAME
+0x665c001e  PR_ORIGINATOR_ADDR
+0x665d001e  PR_ORIGINATOR_ADDRTYPE
+0x665e0102  PR_ORIGINATOR_ENTRYID
+0x665f0040  PR_ARRIVAL_TIME
+0x66600102  PR_TRACE_INFO
+0x66610102  PR_SUBJECT_TRACE_INFO
+0x66620003  PR_RECIPIENT_NUMBER
+0x66630102  PR_MTS_SUBJECT_ID
+0x6664001e  PR_REPORT_DESTINATION_NAME
+0x66650102  PR_REPORT_DESTINATION_ENTRYID
+0x66660102  PR_CONTENT_SEARCH_KEY
+0x66670102  PR_FOREIGN_ID
+0x66680102  PR_FOREIGN_REPORT_ID
+0x66690102  PR_FOREIGN_SUBJECT_ID
+0x666a0102  PR_INTERNAL_TRACE_INFO
+0x666c000b  PR_IN_CONFLICT
+0x66700102  PR_LONGTERM_ENTRYID_FROM_TABLE
+0x66710014  PR_MEMBER_ID
+0x6672001e  PR_MEMBER_NAME
+0x66730003  PR_MEMBER_RIGHTS
+0x66740014  PR_RULE_ID
+0x66750102  PR_RULE_IDS
+0x66760003  PR_RULE_SEQUENCE
+0x66770003  PR_RULE_STATE
+0x66780003  PR_RULE_USER_FLAGS
+0x667900fd  PR_RULE_CONDITION
+0x667b001e  PR_PROFILE_MOAB
+0x667c001e  PR_PROFILE_MOAB_GUID
+0x667d0003  PR_PROFILE_MOAB_SEQ
+0x667f1102  PR_IMPLIED_RESTRICTIONS
+0x668000fe  PR_RULE_ACTIONS
+0x6681001e  PR_RULE_PROVIDER
+0x6682001e  PR_RULE_NAME
+0x66830003  PR_RULE_LEVEL
+0x66840102  PR_RULE_PROVIDER_DATA
+0x66850040  PR_LAST_FULL_BACKUP
+0x66870102  PR_PROFILE_ADDR_INFO
+0x66890102  PR_PROFILE_OPTIONS_DATA
+0x668a0102  PR_EVENTS_ROOT_FOLDER_ENTRYID
+0x668d001e  PR_INBOUND_NEWSFEED_DN
+0x668e001e  PR_OUTBOUND_NEWSFEED_DN
+0x668f0040  PR_DELETED_ON
+0x66900003  PR_REPLICATION_STYLE
+0x66910102  PR_REPLICATION_SCHEDULE
+0x66920003  PR_REPLICATION_MESSAGE_PRIORITY
+0x66930003  PR_OVERALL_MSG_AGE_LIMIT
+0x66940003  PR_REPLICATION_ALWAYS_INTERVAL
+0x66950003  PR_REPLICATION_MSG_SIZE
+0x6696000b  PR_IS_NEWSGROUP_ANCHOR
+0x6697000b  PR_IS_NEWSGROUP
+0x66980102  PR_REPLICA_LIST
+0x66990003  PR_OVERALL_AGE_LIMIT
+0x669a001e  PR_INTERNET_CHARSET
+0x669b0014  PR_DELETED_MESSAGE_SIZE_EXTENDED
+0x669c0014  PR_DELETED_NORMAL_MESSAGE_SIZE_EXTENDED
+0x669d0014  PR_DELETED_ASSOC_MESSAGE_SIZE_EXTENDED
+0x669e000b  PR_SECURE_IN_SITE
+0x66a0001e  PR_NT_USER_NAME
+0x66a10003  PR_LOCALE_ID
+0x66a20040  PR_LAST_LOGON_TIME
+0x66a30040  PR_LAST_LOGOFF_TIME
+0x66a40003  PR_STORAGE_LIMIT_INFORMATION
+0x66a5001e  PR_NEWSGROUP_COMPONENT
+0x66a60102  PR_NEWSFEED_INFO
+0x66a7001e  PR_INTERNET_NEWSGROUP_NAME
+0x66a80003  PR_FOLDER_FLAGS
+0x66a90040  PR_LAST_ACCESS_TIME
+0x66aa0003  PR_RESTRICTION_COUNT
+0x66ab0003  PR_CATEG_COUNT
+0x66ac0003  PR_CACHED_COLUMN_COUNT
+0x66ad0003  PR_NORMAL_MSG_W_ATTACH_COUNT
+0x66ae0003  PR_ASSOC_MSG_W_ATTACH_COUNT
+0x66af0003  PR_RECIPIENT_ON_NORMAL_MSG_COUNT
+0x66b00003  PR_RECIPIENT_ON_ASSOC_MSG_COUNT
+0x66b10003  PR_ATTACH_ON_NORMAL_MSG_COUNT
+0x66b20003  PR_ATTACH_ON_ASSOC_MSG_COUNT
+0x66b30003  PR_NORMAL_MESSAGE_SIZE
+0x66b30014  PR_NORMAL_MESSAGE_SIZE_EXTENDED
+0x66b40003  PR_ASSOC_MESSAGE_SIZE
+0x66b40014  PR_ASSOC_MESSAGE_SIZE_EXTENDED
+0x66b5001e  PR_FOLDER_PATHNAME
+0x66b60003  PR_OWNER_COUNT
+0x66b70003  PR_CONTACT_COUNT
+0x66c30003  PR_CODE_PAGE_ID
+0x66c40003  PR_RETENTION_AGE_LIMIT
+0x66c5000b  PR_DISABLE_PERUSER_READ
+0x66c60102  PR_INTERNET_PARSE_STATE
+0x66c70102  PR_INTERNET_MESSAGE_INFO
+0x6700001e  PR_PST_PATH
+0x6701000b  PR_PST_REMEMBER_PW
+0x67020003  PR_OST_ENCRYPTION
+0x6703001e  PR_PST_PW_SZ_OLD
+0x6704001e  PR_PST_PW_SZ_NEW
+0x67050003  PR_SORT_LOCALE_ID
+0x6707001e  PR_URL_NAME
+0x67090040  PR_LOCAL_COMMIT_TIME
+0x670a0040  PR_LOCAL_COMMIT_TIME_MAX
+0x670b0003  PR_DELETED_COUNT_TOTAL
+0x670c0048  PR_AUTO_RESET
+0x67100003  PR_URL_COMP_NAME_HASH
+0x67110003  PR_MSG_FOLDER_TEMPLATE_RES_2
+0x67120003  PR_RANK
+0x6713000b  PR_MSG_FOLDER_TEMPLATE_RES_4
+0x6714000b  PR_MSG_FOLDER_TEMPLATE_RES_5
+0x6715000b  PR_MSG_FOLDER_TEMPLATE_RES_6
+0x67160102  PR_MSG_FOLDER_TEMPLATE_RES_7
+0x67170102  PR_MSG_FOLDER_TEMPLATE_RES_8
+0x67180102  PR_MSG_FOLDER_TEMPLATE_RES_9
+0x6719001e  PR_MSG_FOLDER_TEMPLATE_RES_10
+0x671a001e  PR_MSG_FOLDER_TEMPLATE_RES_11
+0x671b001e  PR_MSG_FOLDER_TEMPLATE_RES_12
+0x671e000b  PR_PF_PLATINUM_HOME_MDB
+0x671f000b  PR_PF_PROXY_REQUIRED
+0x67200102  PR_INTERNET_FREE_DOC_INFO
+0x67210003  PR_PF_OVER_HARD_QUOTA_LIMIT
+0x67220003  PR_PF_MSG_SIZE_LIMIT
+0x67430003  PR_CONNECTION_MODULUS
+0x6744001e  PR_DELIVER_TO_DN
+0x67460003  PR_MIME_SIZE
+0x67470014  PR_FILE_SIZE_EXTENDED
+0x67480014  PR_FID					PidTagFolderId
+0x67490014  PR_PARENT_FID				PidTagParentFolderId
+0x674a0014  PR_MID
+0x674b0014  PR_CATEG_ID
+0x674c0014  PR_PARENT_CATEG_ID
+0x674d0014  PR_INST_ID
+0x674e0003  PR_INSTANCE_NUM
+0x674f0014  PR_ADDRBOOK_MID
+0x67500003  PR_ICS_NOTIF
+0x67510003  PR_ARTICLE_NUM_NEXT
+0x67520003  PR_IMAP_LAST_ARTICLE_ID
+0x6753000b  PR_NOT_822_RENDERABLE
+0x67580102  PR_LTID
+0x67590102  PR_CN_EXPORT
+0x675a0102  PR_PCL_EXPORT
+0x675b1102  PR_CN_MV_EXPORT
+0x67790003  PR_PF_QUOTA_STYLE
+0x677b0003  PR_PF_STORAGE_QUOTA
+0x67830003  PR_SEARCH_FLAGS
+0x67aa000b  PR_ASSOCIATED
+0x67f00102  PR_PROFILE_SECURE_MAILBOX
+0x6800001e  PR_MAILBEAT_BOUNCE_SERVER
+0x68010040  PR_MAILBEAT_REQUEST_SENT
+0x6802001e  PR_USENET_SITE_NAME
+0x68030040  PR_MAILBEAT_REQUEST_RECEIVED
+0x68040040  PR_MAILBEAT_REQUEST_PROCESSED
+0x68050003  PR_SHUTOFFQUOTA
+0x68060040  PR_MAILBEAT_REPLY_SENT
+0x68070040  PR_MAILBEAT_REPLY_SUBMIT
+0x68080040  PR_MAILBEAT_REPLY_RECEIVED
+0x68090040  PR_MAILBEAT_REPLY_PROCESSED
+0x68340003  PR_VIEW_STYLE
+0x683A0003  PR_VIEW_MAJORVERSION
+0x6844101e  PR_DELEGATES_DISPLAY_NAMES
+0x68451102  PR_DELEGATES_ENTRYIDS
+0x68470003  PR_FREEBUSY_START_RANGE
+0x68480003  PR_FREEBUSY_END_RANGE
+0x6849001e  PR_FREEBUSY_EMAIL_ADDRESS
+0x684f1003  PR_FREEBUSY_ALL_MONTHS
+0x68501102  PR_FREEBUSY_ALL_EVENTS
+0x68511003  PR_FREEBUSY_TENTATIVE_MONTHS
+0x68521102  PR_FREEBUSY_TENTATIVE_EVENTS
+0x68531003  PR_FREEBUSY_BUSY_MONTHS
+0x68541102  PR_FREEBUSY_BUSY_EVENTS
+0x68551003  PR_FREEBUSY_OOF_MONTHS
+0x68561102  PR_FREEBUSY_OOF_EVENTS
+0x68680040  PR_FREEBUSY_LAST_MODIFIED
+0x68690003  PR_FREEBUSY_NUM_MONTHS
+0x686b1003  PR_DELEGATES_SEE_PRIVATE
+0x686c0102  PR_PERSONAL_FREEBUSY
+0x686d000b  PR_PROCESS_MEETING_REQUESTS
+0x686e000b  PR_DECLINE_RECURRING_MEETING_REQUESTS
+0x686f000b  PR_DECLINE_CONFLICTING_MEETING_REQUESTS
+0x70010102  PR_VD_BINARY
+0x7002001e  PR_VD_STRINGS
+0x70030003  PR_VD_FLAGS
+0x70040102  PR_VD_LINK_TO
+0x70050102  PR_VD_VIEW_FOLDER
+0x7006001e  PR_VD_NAME
+0x70070003  PR_VD_VERSION
+0x7c00001e  PR_FAV_DISPLAY_NAME_A
+0x7c020102  PR_FAV_PUBLIC_SOURCE_KEY
+0x7c040102  PR_OST_OSTID
+0x7c0a000b  PR_STORE_SLOWLINK
+0x7d010003  PR_FAV_AUTOSUBFOLDERS
+0x7d01000b  PR_PROCESSED
+0x7d020102  PR_FAV_PARENT_SOURCE_KEY
+0x7d030003  PR_FAV_LEVEL_MASK
+0x7d070003  PR_FAV_INHERIT_AUTO
+0x7d080102  PR_FAV_DEL_SUBS
+0x7ffa0003  PR_ATTACHMENT_LINKID
+0x7ffb0040  PR_EXCEPTION_STARTTIME
+0x7ffc0040  PR_EXCEPTION_ENDTIME
+0x7ffd0003  PR_ATTACHMENT_FLAGS
+0x7ffe000b  PR_ATTACHMENT_HIDDEN
+0x8001000b  PR_EMS_AB_DISPLAY_NAME_OVERRIDE
+0x80031102  PR_EMS_AB_CA_CERTIFICATE
+0x8004001e  PR_EMS_AB_FOLDER_PATHNAME
+0x8005000d  PR_EMS_AB_MANAGER
+0x8005001e  PR_EMS_AB_MANAGER_T
+0x8006000d  PR_EMS_AB_HOME_MDB_O
+0x8006001e  PR_EMS_AB_HOME_MDB
+0x8007000d  PR_EMS_AB_HOME_MTA_O
+0x8007001e  PR_EMS_AB_HOME_MTA
+0x8008000d  PR_EMS_AB_IS_MEMBER_OF_DL
+0x8008001e  PR_EMS_AB_IS_MEMBER_OF_DL_T
+0x8009000d  PR_EMS_AB_MEMBER
+0x8009001e  PR_EMS_AB_MEMBER_T
+0x800a001e  PR_EMS_AB_AUTOREPLY_MESSAGE
+0x800b000b  PR_EMS_AB_AUTOREPLY
+0x800c000d  PR_EMS_AB_OWNER_O
+0x800c001e  PR_EMS_AB_OWNER
+0x800d000d  PR_EMS_AB_KM_SERVER_O
+0x800d001e  PR_EMS_AB_KM_SERVER
+0x800e000d  PR_EMS_AB_REPORTS
+0x800f101e  PR_EMS_AB_PROXY_ADDRESSES
+0x80100102  PR_EMS_AB_HELP_DATA32
+0x8011001e  PR_EMS_AB_TARGET_ADDRESS
+0x8012101e  PR_EMS_AB_TELEPHONE_NUMBER
+0x80130102  PR_EMS_AB_NT_SECURITY_DESCRIPTOR
+0x8014000d  PR_EMS_AB_HOME_MDB_BL_O
+0x8014101e  PR_EMS_AB_HOME_MDB_BL
+0x8015000d  PR_EMS_AB_PUBLIC_DELEGATES
+0x8015001e  PR_EMS_AB_PUBLIC_DELEGATES_T
+0x80160102  PR_EMS_AB_CERTIFICATE_REVOCATION_LIST
+0x80170102  PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE
+0x80180102  PR_EMS_AB_ADDRESS_SYNTAX
+0x80230102  PR_EMS_AB_BUSINESS_ROLES
+0x8024000d  PR_EMS_AB_OWNER_BL_O
+0x8024101e  PR_EMS_AB_OWNER_BL
+0x80251102  PR_EMS_AB_CROSS_CERTIFICATE_PAIR
+0x80261102  PR_EMS_AB_AUTHORITY_REVOCATION_LIST
+0x80270102  PR_EMS_AB_ASSOC_NT_ACCOUNT
+0x80280040  PR_EMS_AB_EXPIRATION_TIME
+0x80290003  PR_EMS_AB_USN_CHANGED
+0x802d001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_1
+0x802e001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_2
+0x802f001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_3
+0x8030001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_4
+0x8031001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_5
+0x8032001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_6
+0x8033001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_7
+0x8034001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_8
+0x8035001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_9
+0x8036001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_10
+0x80371102  PR_EMS_AB_SECURITY_PROTOCOL
+0x8038000d  PR_EMS_AB_PF_CONTACTS_O
+0x8038101e  PR_EMS_AB_PF_CONTACTS
+0x803a0102  PR_EMS_AB_HELP_DATA16
+0x803b001e  PR_EMS_AB_HELP_FILE_NAME
+0x803c000d  PR_EMS_AB_OBJ_DIST_NAME_O
+0x803c001e  PR_EMS_AB_OBJ_DIST_NAME
+0x803d001e  PR_EMS_AB_ENCRYPT_ALG_SELECTED_OTHER
+0x803e001e  PR_EMS_AB_AUTOREPLY_SUBJECT
+0x803f000d  PR_EMS_AB_HOME_PUBLIC_SERVER_O
+0x803f001e  PR_EMS_AB_HOME_PUBLIC_SERVER
+0x8040101e  PR_EMS_AB_ENCRYPT_ALG_LIST_NA
+0x8041101e  PR_EMS_AB_ENCRYPT_ALG_LIST_OTHER
+0x8042001e  PR_EMS_AB_IMPORTED_FROM
+0x8043001e  PR_EMS_AB_ENCRYPT_ALG_SELECTED_NA
+0x80440003  PR_EMS_AB_ACCESS_CATEGORY
+0x80450102  PR_EMS_AB_ACTIVATION_SCHEDULE
+0x80460003  PR_EMS_AB_ACTIVATION_STYLE
+0x80470102  PR_EMS_AB_ADDRESS_ENTRY_DISPLAY_TABLE_MSDOS
+0x8048001e  PR_EMS_AB_ADDRESS_TYPE
+0x8049001e  PR_EMS_AB_ADMD
+0x804a001e  PR_EMS_AB_ADMIN_DESCRIPTION
+0x804b001e  PR_EMS_AB_ADMIN_DISPLAY_NAME
+0x804c001e  PR_EMS_AB_ADMIN_EXTENSION_DLL
+0x804d000d  PR_EMS_AB_ALIASED_OBJECT_NAME_O
+0x804d001e  PR_EMS_AB_ALIASED_OBJECT_NAME
+0x804e000d  PR_EMS_AB_ALT_RECIPIENT_O
+0x804e001e  PR_EMS_AB_ALT_RECIPIENT
+0x804f000d  PR_EMS_AB_ALT_RECIPIENT_BL_O
+0x804f101e  PR_EMS_AB_ALT_RECIPIENT_BL
+0x80500102  PR_EMS_AB_ANCESTOR_ID
+0x8051000d  PR_EMS_AB_ASSOC_REMOTE_DXA_O
+0x8051101e  PR_EMS_AB_ASSOC_REMOTE_DXA
+0x80520003  PR_EMS_AB_ASSOCIATION_LIFETIME
+0x8053000d  PR_EMS_AB_AUTH_ORIG_BL_O
+0x8053101e  PR_EMS_AB_AUTH_ORIG_BL
+0x8054001e  PR_EMS_AB_AUTHORIZED_DOMAIN
+0x80550102  PR_EMS_AB_AUTHORIZED_PASSWORD
+0x8056001e  PR_EMS_AB_AUTHORIZED_USER
+0x8057101e  PR_EMS_AB_BUSINESS_CATEGORY
+0x8058000d  PR_EMS_AB_CAN_CREATE_PF_O
+0x8058101e  PR_EMS_AB_CAN_CREATE_PF
+0x8059000d  PR_EMS_AB_CAN_CREATE_PF_BL_O
+0x8059101e  PR_EMS_AB_CAN_CREATE_PF_BL
+0x805a000d  PR_EMS_AB_CAN_CREATE_PF_DL_O
+0x805a101e  PR_EMS_AB_CAN_CREATE_PF_DL
+0x805b000d  PR_EMS_AB_CAN_CREATE_PF_DL_BL_O
+0x805b101e  PR_EMS_AB_CAN_CREATE_PF_DL_BL
+0x805c000d  PR_EMS_AB_CAN_NOT_CREATE_PF_O
+0x805c101e  PR_EMS_AB_CAN_NOT_CREATE_PF
+0x805d000d  PR_EMS_AB_CAN_NOT_CREATE_PF_BL_O
+0x805d101e  PR_EMS_AB_CAN_NOT_CREATE_PF_BL
+0x805e000d  PR_EMS_AB_CAN_NOT_CREATE_PF_DL_O
+0x805e101e  PR_EMS_AB_CAN_NOT_CREATE_PF_DL
+0x805f000d  PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL_O
+0x805f101e  PR_EMS_AB_CAN_NOT_CREATE_PF_DL_BL
+0x8060000b  PR_EMS_AB_CAN_PRESERVE_DNS
+0x80610003  PR_EMS_AB_CLOCK_ALERT_OFFSET
+0x8062000b  PR_EMS_AB_CLOCK_ALERT_REPAIR
+0x80630003  PR_EMS_AB_CLOCK_WARNING_OFFSET
+0x8064000b  PR_EMS_AB_CLOCK_WARNING_REPAIR
+0x8065001e  PR_EMS_AB_COMPUTER_NAME
+0x8066101e  PR_EMS_AB_CONNECTED_DOMAINS
+0x80670003  PR_EMS_AB_CONTAINER_INFO
+0x80680003  PR_EMS_AB_COST
+0x8069001e  PR_EMS_AB_COUNTRY_NAME
+0x806a0003  PR_EMS_AB_DELIV_CONT_LENGTH
+0x806b1102  PR_EMS_AB_DELIV_EITS
+0x806c1102  PR_EMS_AB_DELIV_EXT_CONT_TYPES
+0x806d000b  PR_EMS_AB_DELIVER_AND_REDIRECT
+0x806e0003  PR_EMS_AB_DELIVERY_MECHANISM
+0x806f101e  PR_EMS_AB_DESCRIPTION
+0x8070101e  PR_EMS_AB_DESTINATION_INDICATOR
+0x8071001e  PR_EMS_AB_DIAGNOSTIC_REG_KEY
+0x8072000d  PR_EMS_AB_DL_MEM_REJECT_PERMS_BL_O
+0x8072101e  PR_EMS_AB_DL_MEM_REJECT_PERMS_BL
+0x8073000d  PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL_O
+0x8073101e  PR_EMS_AB_DL_MEM_SUBMIT_PERMS_BL
+0x80741102  PR_EMS_AB_DL_MEMBER_RULE
+0x8075000d  PR_EMS_AB_DOMAIN_DEF_ALT_RECIP_O
+0x8075001e  PR_EMS_AB_DOMAIN_DEF_ALT_RECIP
+0x8076001e  PR_EMS_AB_DOMAIN_NAME
+0x80770102  PR_EMS_AB_DSA_SIGNATURE
+0x8078000b  PR_EMS_AB_DXA_ADMIN_COPY
+0x8079000b  PR_EMS_AB_DXA_ADMIN_FORWARD
+0x807a0003  PR_EMS_AB_DXA_ADMIN_UPDATE
+0x807b000b  PR_EMS_AB_DXA_APPEND_REQCN
+0x807c000d  PR_EMS_AB_DXA_CONF_CONTAINER_LIST_O
+0x807c101e  PR_EMS_AB_DXA_CONF_CONTAINER_LIST
+0x807d0040  PR_EMS_AB_DXA_CONF_REQ_TIME
+0x807e001e  PR_EMS_AB_DXA_CONF_SEQ
+0x807f0003  PR_EMS_AB_DXA_CONF_SEQ_USN
+0x80800003  PR_EMS_AB_DXA_EXCHANGE_OPTIONS
+0x8081000b  PR_EMS_AB_DXA_EXPORT_NOW
+0x80820003  PR_EMS_AB_DXA_FLAGS
+0x8083001e  PR_EMS_AB_DXA_IMP_SEQ
+0x80840040  PR_EMS_AB_DXA_IMP_SEQ_TIME
+0x80850003  PR_EMS_AB_DXA_IMP_SEQ_USN
+0x8086000b  PR_EMS_AB_DXA_IMPORT_NOW
+0x8087101e  PR_EMS_AB_DXA_IN_TEMPLATE_MAP
+0x8088000d  PR_EMS_AB_DXA_LOCAL_ADMIN_O
+0x8088001e  PR_EMS_AB_DXA_LOCAL_ADMIN
+0x80890003  PR_EMS_AB_DXA_LOGGING_LEVEL
+0x808a001e  PR_EMS_AB_DXA_NATIVE_ADDRESS_TYPE
+0x808b101e  PR_EMS_AB_DXA_OUT_TEMPLATE_MAP
+0x808c001e  PR_EMS_AB_DXA_PASSWORD
+0x808d0003  PR_EMS_AB_DXA_PREV_EXCHANGE_OPTIONS
+0x808e000b  PR_EMS_AB_DXA_PREV_EXPORT_NATIVE_ONLY
+0x808f0003  PR_EMS_AB_DXA_PREV_IN_EXCHANGE_SENSITIVITY
+0x8090000d  PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES_O
+0x8090001e  PR_EMS_AB_DXA_PREV_REMOTE_ENTRIES
+0x80910003  PR_EMS_AB_DXA_PREV_REPLICATION_SENSITIVITY
+0x80920003  PR_EMS_AB_DXA_PREV_TEMPLATE_OPTIONS
+0x80930003  PR_EMS_AB_DXA_PREV_TYPES
+0x8094001e  PR_EMS_AB_DXA_RECIPIENT_CP
+0x8095000d  PR_EMS_AB_DXA_REMOTE_CLIENT_O
+0x8095001e  PR_EMS_AB_DXA_REMOTE_CLIENT
+0x8096001e  PR_EMS_AB_DXA_REQ_SEQ
+0x80970040  PR_EMS_AB_DXA_REQ_SEQ_TIME
+0x80980003  PR_EMS_AB_DXA_REQ_SEQ_USN
+0x8099001e  PR_EMS_AB_DXA_REQNAME
+0x809a001e  PR_EMS_AB_DXA_SVR_SEQ
+0x809b0040  PR_EMS_AB_DXA_SVR_SEQ_TIME
+0x809c0003  PR_EMS_AB_DXA_SVR_SEQ_USN
+0x809d0003  PR_EMS_AB_DXA_TASK
+0x809e0003  PR_EMS_AB_DXA_TEMPLATE_OPTIONS
+0x809f0040  PR_EMS_AB_DXA_TEMPLATE_TIMESTAMP
+0x80a00003  PR_EMS_AB_DXA_TYPES
+0x80a1000d  PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST_O
+0x80a1101e  PR_EMS_AB_DXA_UNCONF_CONTAINER_LIST
+0x80a20003  PR_EMS_AB_ENCAPSULATION_METHOD
+0x80a3000b  PR_EMS_AB_ENCRYPT
+0x80a4000b  PR_EMS_AB_EXPAND_DLS_LOCALLY
+0x80a5000d  PR_EMS_AB_EXPORT_CONTAINERS_O
+0x80a5101e  PR_EMS_AB_EXPORT_CONTAINERS
+0x80a6000b  PR_EMS_AB_EXPORT_CUSTOM_RECIPIENTS
+0x80a7000b  PR_EMS_AB_EXTENDED_CHARS_ALLOWED
+0x80a81102  PR_EMS_AB_EXTENSION_DATA
+0x80a9101e  PR_EMS_AB_EXTENSION_NAME
+0x80aa101e  PR_EMS_AB_EXTENSION_NAME_INHERITED
+0x80ab1102  PR_EMS_AB_FACSIMILE_TELEPHONE_NUMBER
+0x80ac0102  PR_EMS_AB_FILE_VERSION
+0x80ad000b  PR_EMS_AB_FILTER_LOCAL_ADDRESSES
+0x80ae000d  PR_EMS_AB_FOLDERS_CONTAINER_O
+0x80ae001e  PR_EMS_AB_FOLDERS_CONTAINER
+0x80af0003  PR_EMS_AB_GARBAGE_COLL_PERIOD
+0x80b0001e  PR_EMS_AB_GATEWAY_LOCAL_CRED
+0x80b1001e  PR_EMS_AB_GATEWAY_LOCAL_DESIG
+0x80b2101e  PR_EMS_AB_GATEWAY_PROXY
+0x80b30102  PR_EMS_AB_GATEWAY_ROUTING_TREE
+0x80b40040  PR_EMS_AB_GWART_LAST_MODIFIED
+0x80b5000d  PR_EMS_AB_HAS_FULL_REPLICA_NCS_O
+0x80b5101e  PR_EMS_AB_HAS_FULL_REPLICA_NCS
+0x80b6000d  PR_EMS_AB_HAS_MASTER_NCS_O
+0x80b6101e  PR_EMS_AB_HAS_MASTER_NCS
+0x80b70003  PR_EMS_AB_HEURISTICS
+0x80b8000b  PR_EMS_AB_HIDE_DL_MEMBERSHIP
+0x80b9000b  PR_EMS_AB_HIDE_FROM_ADDRESS_BOOK
+0x80ba000d  PR_EMS_AB_IMPORT_CONTAINER_O
+0x80ba001e  PR_EMS_AB_IMPORT_CONTAINER
+0x80bb0003  PR_EMS_AB_IMPORT_SENSITIVITY
+0x80bc000d  PR_EMS_AB_INBOUND_SITES_O
+0x80bc101e  PR_EMS_AB_INBOUND_SITES
+0x80bd0003  PR_EMS_AB_INSTANCE_TYPE
+0x80be101e  PR_EMS_AB_INTERNATIONAL_ISDN_NUMBER
+0x80bf0102  PR_EMS_AB_INVOCATION_ID
+0x80c0000b  PR_EMS_AB_IS_DELETED
+0x80c1000b  PR_EMS_AB_IS_SINGLE_VALUED
+0x80c21102  PR_EMS_AB_KCC_STATUS
+0x80c3101e  PR_EMS_AB_KNOWLEDGE_INFORMATION
+0x80c40003  PR_EMS_AB_LINE_WRAP
+0x80c50003  PR_EMS_AB_LINK_ID
+0x80c6001e  PR_EMS_AB_LOCAL_BRIDGE_HEAD
+0x80c7001e  PR_EMS_AB_LOCAL_BRIDGE_HEAD_ADDRESS
+0x80c8000b  PR_EMS_AB_LOCAL_INITIAL_TURN
+0x80c9000d  PR_EMS_AB_LOCAL_SCOPE_O
+0x80c9101e  PR_EMS_AB_LOCAL_SCOPE
+0x80ca001e  PR_EMS_AB_LOG_FILENAME
+0x80cb0003  PR_EMS_AB_LOG_ROLLOVER_INTERVAL
+0x80cc000b  PR_EMS_AB_MAINTAIN_AUTOREPLY_HISTORY
+0x80cd0003  PR_EMS_AB_MAPI_DISPLAY_TYPE
+0x80ce0003  PR_EMS_AB_MAPI_ID
+0x80cf0003  PR_EMS_AB_MDB_BACKOFF_INTERVAL
+0x80d00003  PR_EMS_AB_MDB_MSG_TIME_OUT_PERIOD
+0x80d10003  PR_EMS_AB_MDB_OVER_QUOTA_LIMIT
+0x80d20003  PR_EMS_AB_MDB_STORAGE_QUOTA
+0x80d30003  PR_EMS_AB_MDB_UNREAD_LIMIT
+0x80d4000b  PR_EMS_AB_MDB_USE_DEFAULTS
+0x80d5000b  PR_EMS_AB_MESSAGE_TRACKING_ENABLED
+0x80d6000b  PR_EMS_AB_MONITOR_CLOCK
+0x80d7000b  PR_EMS_AB_MONITOR_SERVERS
+0x80d8000b  PR_EMS_AB_MONITOR_SERVICES
+0x80d9000d  PR_EMS_AB_MONITORED_CONFIGURATIONS_O
+0x80d9101e  PR_EMS_AB_MONITORED_CONFIGURATIONS
+0x80da000d  PR_EMS_AB_MONITORED_SERVERS_O
+0x80da101e  PR_EMS_AB_MONITORED_SERVERS
+0x80db101e  PR_EMS_AB_MONITORED_SERVICES
+0x80dc0003  PR_EMS_AB_MONITORING_ALERT_DELAY
+0x80dd0003  PR_EMS_AB_MONITORING_ALERT_UNITS
+0x80de0003  PR_EMS_AB_MONITORING_AVAILABILITY_STYLE
+0x80df0102  PR_EMS_AB_MONITORING_AVAILABILITY_WINDOW
+0x80e0000d  PR_EMS_AB_MONITORING_CACHED_VIA_MAIL_O
+0x80e0101e  PR_EMS_AB_MONITORING_CACHED_VIA_MAIL
+0x80e1000d  PR_EMS_AB_MONITORING_CACHED_VIA_RPC_O
+0x80e1101e  PR_EMS_AB_MONITORING_CACHED_VIA_RPC
+0x80e21102  PR_EMS_AB_MONITORING_ESCALATION_PROCEDURE
+0x80e30003  PR_EMS_AB_MONITORING_HOTSITE_POLL_INTERVAL
+0x80e40003  PR_EMS_AB_MONITORING_HOTSITE_POLL_UNITS
+0x80e50003  PR_EMS_AB_MONITORING_MAIL_UPDATE_INTERVAL
+0x80e60003  PR_EMS_AB_MONITORING_MAIL_UPDATE_UNITS
+0x80e70003  PR_EMS_AB_MONITORING_NORMAL_POLL_INTERVAL
+0x80e80003  PR_EMS_AB_MONITORING_NORMAL_POLL_UNITS
+0x80e9000d  PR_EMS_AB_MONITORING_RECIPIENTS_O
+0x80e9101e  PR_EMS_AB_MONITORING_RECIPIENTS
+0x80ea000d  PR_EMS_AB_MONITORING_RECIPIENTS_NDR_O
+0x80ea101e  PR_EMS_AB_MONITORING_RECIPIENTS_NDR
+0x80eb0003  PR_EMS_AB_MONITORING_RPC_UPDATE_INTERVAL
+0x80ec0003  PR_EMS_AB_MONITORING_RPC_UPDATE_UNITS
+0x80ed0003  PR_EMS_AB_MONITORING_WARNING_DELAY
+0x80ee0003  PR_EMS_AB_MONITORING_WARNING_UNITS
+0x80ef001e  PR_EMS_AB_MTA_LOCAL_CRED
+0x80f0001e  PR_EMS_AB_MTA_LOCAL_DESIG
+0x80f10102  PR_EMS_AB_N_ADDRESS
+0x80f20003  PR_EMS_AB_N_ADDRESS_TYPE
+0x80f3001e  PR_EMS_AB_NT_MACHINE_NAME
+0x80f40003  PR_EMS_AB_NUM_OF_OPEN_RETRIES
+0x80f50003  PR_EMS_AB_NUM_OF_TRANSFER_RETRIES
+0x80f60003  PR_EMS_AB_OBJECT_CLASS_CATEGORY
+0x80f70003  PR_EMS_AB_OBJECT_VERSION
+0x80f8000d  PR_EMS_AB_OFF_LINE_AB_CONTAINERS_O
+0x80f8101e  PR_EMS_AB_OFF_LINE_AB_CONTAINERS
+0x80f90102  PR_EMS_AB_OFF_LINE_AB_SCHEDULE
+0x80fa000d  PR_EMS_AB_OFF_LINE_AB_SERVER_O
+0x80fa001e  PR_EMS_AB_OFF_LINE_AB_SERVER
+0x80fb0003  PR_EMS_AB_OFF_LINE_AB_STYLE
+0x80fc0003  PR_EMS_AB_OID_TYPE
+0x80fd0102  PR_EMS_AB_OM_OBJECT_CLASS
+0x80fe0003  PR_EMS_AB_OM_SYNTAX
+0x80ff000b  PR_EMS_AB_OOF_REPLY_TO_ORIGINATOR
+0x81000003  PR_EMS_AB_OPEN_RETRY_INTERVAL
+0x8101101e  PR_EMS_AB_ORGANIZATION_NAME
+0x8102101e  PR_EMS_AB_ORGANIZATIONAL_UNIT_NAME
+0x81030102  PR_EMS_AB_ORIGINAL_DISPLAY_TABLE
+0x81040102  PR_EMS_AB_ORIGINAL_DISPLAY_TABLE_MSDOS
+0x8105000d  PR_EMS_AB_OUTBOUND_SITES_O
+0x8105101e  PR_EMS_AB_OUTBOUND_SITES
+0x81060102  PR_EMS_AB_P_SELECTOR
+0x81070102  PR_EMS_AB_P_SELECTOR_INBOUND
+0x81080102  PR_EMS_AB_PER_MSG_DIALOG_DISPLAY_TABLE
+0x81090102  PR_EMS_AB_PER_RECIP_DIALOG_DISPLAY_TABLE
+0x810a0102  PR_EMS_AB_PERIOD_REP_SYNC_TIMES
+0x810b0003  PR_EMS_AB_PERIOD_REPL_STAGGER
+0x810c1102  PR_EMS_AB_POSTAL_ADDRESS
+0x810d1003  PR_EMS_AB_PREFERRED_DELIVERY_METHOD
+0x810e001e  PR_EMS_AB_PRMD
+0x810f001e  PR_EMS_AB_PROXY_GENERATOR_DLL
+0x8110000d  PR_EMS_AB_PUBLIC_DELEGATES_BL_O
+0x8110101e  PR_EMS_AB_PUBLIC_DELEGATES_BL
+0x81110102  PR_EMS_AB_QUOTA_NOTIFICATION_SCHEDULE
+0x81120003  PR_EMS_AB_QUOTA_NOTIFICATION_STYLE
+0x81130003  PR_EMS_AB_RANGE_LOWER
+0x81140003  PR_EMS_AB_RANGE_UPPER
+0x8115001e  PR_EMS_AB_RAS_CALLBACK_NUMBER
+0x8116001e  PR_EMS_AB_RAS_PHONE_NUMBER
+0x8117001e  PR_EMS_AB_RAS_PHONEBOOK_ENTRY_NAME
+0x8118001e  PR_EMS_AB_RAS_REMOTE_SRVR_NAME
+0x81191102  PR_EMS_AB_REGISTERED_ADDRESS
+0x811a001e  PR_EMS_AB_REMOTE_BRIDGE_HEAD
+0x811b001e  PR_EMS_AB_REMOTE_BRIDGE_HEAD_ADDRESS
+0x811c000d  PR_EMS_AB_REMOTE_OUT_BH_SERVER_O
+0x811c001e  PR_EMS_AB_REMOTE_OUT_BH_SERVER
+0x811d000d  PR_EMS_AB_REMOTE_SITE_O
+0x811d001e  PR_EMS_AB_REMOTE_SITE
+0x811e0003  PR_EMS_AB_REPLICATION_SENSITIVITY
+0x811f0003  PR_EMS_AB_REPLICATION_STAGGER
+0x8120000b  PR_EMS_AB_REPORT_TO_ORIGINATOR
+0x8121000b  PR_EMS_AB_REPORT_TO_OWNER
+0x81220003  PR_EMS_AB_REQ_SEQ
+0x8123000d  PR_EMS_AB_RESPONSIBLE_LOCAL_DXA_O
+0x8123001e  PR_EMS_AB_RESPONSIBLE_LOCAL_DXA
+0x8124000d  PR_EMS_AB_RID_SERVER_O
+0x8124001e  PR_EMS_AB_RID_SERVER
+0x8125000d  PR_EMS_AB_ROLE_OCCUPANT_O
+0x8125101e  PR_EMS_AB_ROLE_OCCUPANT
+0x8126101e  PR_EMS_AB_ROUTING_LIST
+0x81270003  PR_EMS_AB_RTS_CHECKPOINT_SIZE
+0x81280003  PR_EMS_AB_RTS_RECOVERY_TIMEOUT
+0x81290003  PR_EMS_AB_RTS_WINDOW_SIZE
+0x812a000d  PR_EMS_AB_RUNS_ON_O
+0x812a101e  PR_EMS_AB_RUNS_ON
+0x812b0102  PR_EMS_AB_S_SELECTOR
+0x812c0102  PR_EMS_AB_S_SELECTOR_INBOUND
+0x812d0003  PR_EMS_AB_SEARCH_FLAGS
+0x812e1102  PR_EMS_AB_SEARCH_GUIDE
+0x812f000d  PR_EMS_AB_SEE_ALSO_O
+0x812f101e  PR_EMS_AB_SEE_ALSO
+0x8130101e  PR_EMS_AB_SERIAL_NUMBER
+0x81310003  PR_EMS_AB_SERVICE_ACTION_FIRST
+0x81320003  PR_EMS_AB_SERVICE_ACTION_OTHER
+0x81330003  PR_EMS_AB_SERVICE_ACTION_SECOND
+0x81340003  PR_EMS_AB_SERVICE_RESTART_DELAY
+0x8135001e  PR_EMS_AB_SERVICE_RESTART_MESSAGE
+0x81360003  PR_EMS_AB_SESSION_DISCONNECT_TIMER
+0x8137101e  PR_EMS_AB_SITE_AFFINITY
+0x8138101e  PR_EMS_AB_SITE_PROXY_SPACE
+0x81390040  PR_EMS_AB_SPACE_LAST_COMPUTED
+0x813a001e  PR_EMS_AB_STREET_ADDRESS
+0x813b000d  PR_EMS_AB_SUB_REFS_O
+0x813b101e  PR_EMS_AB_SUB_REFS
+0x813c0003  PR_EMS_AB_SUBMISSION_CONT_LENGTH
+0x813d1102  PR_EMS_AB_SUPPORTED_APPLICATION_CONTEXT
+0x813e000d  PR_EMS_AB_SUPPORTING_STACK_O
+0x813e101e  PR_EMS_AB_SUPPORTING_STACK
+0x813f000d  PR_EMS_AB_SUPPORTING_STACK_BL_O
+0x813f101e  PR_EMS_AB_SUPPORTING_STACK_BL
+0x81400102  PR_EMS_AB_T_SELECTOR
+0x81410102  PR_EMS_AB_T_SELECTOR_INBOUND
+0x8142101e  PR_EMS_AB_TARGET_MTAS
+0x81431102  PR_EMS_AB_TELETEX_TERMINAL_IDENTIFIER
+0x81440003  PR_EMS_AB_TEMP_ASSOC_THRESHOLD
+0x81450003  PR_EMS_AB_TOMBSTONE_LIFETIME
+0x8146001e  PR_EMS_AB_TRACKING_LOG_PATH_NAME
+0x81470003  PR_EMS_AB_TRANS_RETRY_MINS
+0x81480003  PR_EMS_AB_TRANS_TIMEOUT_MINS
+0x81490003  PR_EMS_AB_TRANSFER_RETRY_INTERVAL
+0x814a0003  PR_EMS_AB_TRANSFER_TIMEOUT_NON_URGENT
+0x814b0003  PR_EMS_AB_TRANSFER_TIMEOUT_NORMAL
+0x814c0003  PR_EMS_AB_TRANSFER_TIMEOUT_URGENT
+0x814d0003  PR_EMS_AB_TRANSLATION_TABLE_USED
+0x814e000b  PR_EMS_AB_TRANSPORT_EXPEDITED_DATA
+0x814f0003  PR_EMS_AB_TRUST_LEVEL
+0x81500003  PR_EMS_AB_TURN_REQUEST_THRESHOLD
+0x8151000b  PR_EMS_AB_TWO_WAY_ALTERNATE_FACILITY
+0x8152000d  PR_EMS_AB_UNAUTH_ORIG_BL_O
+0x8152101e  PR_EMS_AB_UNAUTH_ORIG_BL
+0x81531102  PR_EMS_AB_USER_PASSWORD
+0x81540003  PR_EMS_AB_USN_CREATED
+0x81550003  PR_EMS_AB_USN_DSA_LAST_OBJ_REMOVED
+0x81560003  PR_EMS_AB_USN_LAST_OBJ_REM
+0x81570003  PR_EMS_AB_USN_SOURCE
+0x8158101e  PR_EMS_AB_X121_ADDRESS
+0x81590102  PR_EMS_AB_X25_CALL_USER_DATA_INCOMING
+0x815a0102  PR_EMS_AB_X25_CALL_USER_DATA_OUTGOING
+0x815b0102  PR_EMS_AB_X25_FACILITIES_DATA_INCOMING
+0x815c0102  PR_EMS_AB_X25_FACILITIES_DATA_OUTGOING
+0x815d0102  PR_EMS_AB_X25_LEASED_LINE_PORT
+0x815e000b  PR_EMS_AB_X25_LEASED_OR_SWITCHED
+0x815f001e  PR_EMS_AB_X25_REMOTE_MTA_PHONE
+0x81600102  PR_EMS_AB_X400_ATTACHMENT_TYPE
+0x81610003  PR_EMS_AB_X400_SELECTOR_SYNTAX
+0x81620102  PR_EMS_AB_X500_ACCESS_CONTROL_LIST
+0x81630003  PR_EMS_AB_XMIT_TIMEOUT_NON_URGENT
+0x81640003  PR_EMS_AB_XMIT_TIMEOUT_NORMAL
+0x81650003  PR_EMS_AB_XMIT_TIMEOUT_URGENT
+0x81660102  PR_EMS_AB_SITE_FOLDER_GUID
+0x8167000d  PR_EMS_AB_SITE_FOLDER_SERVER_O
+0x8167001e  PR_EMS_AB_SITE_FOLDER_SERVER
+0x81680003  PR_EMS_AB_REPLICATION_MAIL_MSG_SIZE
+0x81690102  PR_EMS_AB_MAXIMUM_OBJECT_ID
+0x8170101e  PR_EMS_AB_NETWORK_ADDRESS
+0x8171101e  PR_EMS_AB_LDAP_DISPLAY_NAME
+0x81730003  PR_EMS_AB_SCHEMA_FLAGS
+0x8174000d  PR_EMS_AB_BRIDGEHEAD_SERVERS_O
+0x8174101e  PR_EMS_AB_BRIDGEHEAD_SERVERS
+0x8175001e  PR_EMS_AB_WWW_HOME_PAGE
+0x8176001e  PR_EMS_AB_NNTP_CONTENT_FORMAT
+0x8177001e  PR_EMS_AB_POP_CONTENT_FORMAT
+0x81780003  PR_EMS_AB_LANGUAGE
+0x8179001e  PR_EMS_AB_POP_CHARACTER_SET
+0x817a0003  PR_EMS_AB_USN_INTERSITE
+0x817b001e  PR_EMS_AB_SUB_SITE
+0x817c1003  PR_EMS_AB_SCHEMA_VERSION
+0x817d001e  PR_EMS_AB_NNTP_CHARACTER_SET
+0x817e000b  PR_EMS_AB_USE_SERVER_VALUES
+0x817f0003  PR_EMS_AB_ENABLED_PROTOCOLS
+0x81800102  PR_EMS_AB_CONNECTION_LIST_FILTER
+0x8181101e  PR_EMS_AB_AVAILABLE_AUTHORIZATION_PACKAGES
+0x8182101e  PR_EMS_AB_CHARACTER_SET_LIST
+0x8183000b  PR_EMS_AB_USE_SITE_VALUES
+0x8184101e  PR_EMS_AB_ENABLED_AUTHORIZATION_PACKAGES
+0x8185001e  PR_EMS_AB_CHARACTER_SET
+0x81860003  PR_EMS_AB_CONTENT_TYPE
+0x8187000b  PR_EMS_AB_ANONYMOUS_ACCESS
+0x81880102  PR_EMS_AB_CONTROL_MSG_FOLDER_ID
+0x8189001e  PR_EMS_AB_USENET_SITE_NAME
+0x818a0102  PR_EMS_AB_CONTROL_MSG_RULES
+0x818b001e  PR_EMS_AB_AVAILABLE_DISTRIBUTIONS
+0x818d0102  PR_EMS_AB_OUTBOUND_HOST
+0x818e101e  PR_EMS_AB_INBOUND_HOST
+0x818f0003  PR_EMS_AB_OUTGOING_MSG_SIZE_LIMIT
+0x81900003  PR_EMS_AB_INCOMING_MSG_SIZE_LIMIT
+0x8191000b  PR_EMS_AB_SEND_TNEF
+0x81920102  PR_EMS_AB_AUTHORIZED_PASSWORD_CONFIRM
+0x8193001e  PR_EMS_AB_INBOUND_NEWSFEED
+0x81940003  PR_EMS_AB_NEWSFEED_TYPE
+0x8195001e  PR_EMS_AB_OUTBOUND_NEWSFEED
+0x81960102  PR_EMS_AB_NEWSGROUP_LIST
+0x8197101e  PR_EMS_AB_NNTP_DISTRIBUTIONS
+0x8198001e  PR_EMS_AB_NEWSGROUP
+0x8199001e  PR_EMS_AB_MODERATOR
+0x819a001e  PR_EMS_AB_AUTHENTICATION_TO_USE
+0x819b000b  PR_EMS_AB_HTTP_PUB_GAL
+0x819c0003  PR_EMS_AB_HTTP_PUB_GAL_LIMIT
+0x819e1102  PR_EMS_AB_HTTP_PUB_PF
+0x81a1001e  PR_EMS_AB_X500_RDN
+0x81a2001e  PR_EMS_AB_X500_NC
+0x81a3101e  PR_EMS_AB_REFERRAL_LIST
+0x81a4000b  PR_EMS_AB_NNTP_DISTRIBUTIONS_FLAG
+0x81a5000d  PR_EMS_AB_ASSOC_PROTOCOL_CFG_NNTP_O
+0x81a5001e  PR_EMS_AB_ASSOC_PROTOCOL_CFG_NNTP
+0x81a6000d  PR_EMS_AB_NNTP_NEWSFEEDS_O
+0x81a6101e  PR_EMS_AB_NNTP_NEWSFEEDS
+0x81a8000b  PR_EMS_AB_ENABLED_PROTOCOL_CFG
+0x81a9101e  PR_EMS_AB_HTTP_PUB_AB_ATTRIBUTES
+0x81ab101e  PR_EMS_AB_HTTP_SERVERS
+0x81ac000b  PR_EMS_AB_MODERATED
+0x81ad001e  PR_EMS_AB_RAS_ACCOUNT
+0x81ae0102  PR_EMS_AB_RAS_PASSWORD
+0x81af0102  PR_EMS_AB_INCOMING_PASSWORD
+0x81b0000b  PR_EMS_AB_OUTBOUND_HOST_TYPE
+0x81b1000b  PR_EMS_AB_PROXY_GENERATION_ENABLED
+0x81b20102  PR_EMS_AB_ROOT_NEWSGROUPS_FOLDER_ID
+0x81b3000b  PR_EMS_AB_CONNECTION_TYPE
+0x81b40003  PR_EMS_AB_CONNECTION_LIST_FILTER_TYPE
+0x81b50003  PR_EMS_AB_PORT_NUMBER
+0x81b6101e  PR_EMS_AB_PROTOCOL_SETTINGS
+0x81b7001e  PR_EMS_AB_GROUP_BY_ATTR_1
+0x81b8001e  PR_EMS_AB_GROUP_BY_ATTR_2
+0x81b9001e  PR_EMS_AB_GROUP_BY_ATTR_3
+0x81ba001e  PR_EMS_AB_GROUP_BY_ATTR_4
+0x81be001e  PR_EMS_AB_VIEW_SITE
+0x81bf001e  PR_EMS_AB_VIEW_CONTAINER_1
+0x81c0001e  PR_EMS_AB_VIEW_CONTAINER_2
+0x81c1001e  PR_EMS_AB_VIEW_CONTAINER_3
+0x81c20040  PR_EMS_AB_PROMO_EXPIRATION
+0x81c3101e  PR_EMS_AB_DISABLED_GATEWAY_PROXY
+0x81c40102  PR_EMS_AB_COMPROMISED_KEY_LIST
+0x81c5000d  PR_EMS_AB_INSADMIN_O
+0x81c5001e  PR_EMS_AB_INSADMIN
+0x81c6000b  PR_EMS_AB_OVERRIDE_NNTP_CONTENT_FORMAT
+0x81c7000d  PR_EMS_AB_OBJ_VIEW_CONTAINERS_O
+0x81c7101e  PR_EMS_AB_OBJ_VIEW_CONTAINERS
+0x8c180003  PR_EMS_AB_VIEW_FLAGS
+0x8c19001e  PR_EMS_AB_GROUP_BY_ATTR_VALUE_STR
+0x8c1a000d  PR_EMS_AB_GROUP_BY_ATTR_VALUE_DN_O
+0x8c1a001e  PR_EMS_AB_GROUP_BY_ATTR_VALUE_DN
+0x8c1b1102  PR_EMS_AB_VIEW_DEFINITION
+0x8c1c0102  PR_EMS_AB_MIME_TYPES
+0x8c1d0003  PR_EMS_AB_LDAP_SEARCH_CFG
+0x8c1e000d  PR_EMS_AB_INBOUND_DN_O
+0x8c1e001e  PR_EMS_AB_INBOUND_DN
+0x8c1f000b  PR_EMS_AB_INBOUND_NEWSFEED_TYPE
+0x8c20000b  PR_EMS_AB_INBOUND_ACCEPT_ALL
+0x8c21000b  PR_EMS_AB_ENABLED
+0x8c22000b  PR_EMS_AB_PRESERVE_INTERNET_CONTENT
+0x8c23000b  PR_EMS_AB_DISABLE_DEFERRED_COMMIT
+0x8c24000b  PR_EMS_AB_CLIENT_ACCESS_ENABLED
+0x8c25000b  PR_EMS_AB_REQUIRE_SSL
+0x8c26001e  PR_EMS_AB_ANONYMOUS_ACCOUNT
+0x8c270102  PR_EMS_AB_CERTIFICATE_CHAIN_V3
+0x8c280102  PR_EMS_AB_CERTIFICATE_REVOCATION_LIST_V3
+0x8c290102  PR_EMS_AB_CERTIFICATE_REVOCATION_LIST_V1
+0x8c301102  PR_EMS_AB_CROSS_CERTIFICATE_CRL
+0x8c31000b  PR_EMS_AB_SEND_EMAIL_MESSAGE
+0x8c32000b  PR_EMS_AB_ENABLE_COMPATIBILITY
+0x8c33101e  PR_EMS_AB_SMIME_ALG_LIST_NA
+0x8c34101e  PR_EMS_AB_SMIME_ALG_LIST_OTHER
+0x8c35001e  PR_EMS_AB_SMIME_ALG_SELECTED_NA
+0x8c36001e  PR_EMS_AB_SMIME_ALG_SELECTED_OTHER
+0x8c37000b  PR_EMS_AB_DEFAULT_MESSAGE_FORMAT
+0x8c38001e  PR_EMS_AB_TYPE
+0x8c3a0003  PR_EMS_AB_DO_OAB_VERSION
+0x8c3b0102  PR_EMS_AB_VOICE_MAIL_SYSTEM_GUID
+0x8c3c001e  PR_EMS_AB_VOICE_MAIL_USER_ID
+0x8c3d001e  PR_EMS_AB_VOICE_MAIL_PASSWORD
+0x8c3e0102  PR_EMS_AB_VOICE_MAIL_RECORDED_NAME
+0x8c3f101e  PR_EMS_AB_VOICE_MAIL_GREETINGS
+0x8c401102  PR_EMS_AB_VOICE_MAIL_FLAGS
+0x8c410003  PR_EMS_AB_VOICE_MAIL_VOLUME
+0x8c420003  PR_EMS_AB_VOICE_MAIL_SPEED
+0x8c431003  PR_EMS_AB_VOICE_MAIL_RECORDING_LENGTH
+0x8c44001e  PR_EMS_AB_DISPLAY_NAME_SUFFIX
+0x8c451102  PR_EMS_AB_ATTRIBUTE_CERTIFICATE
+0x8c461102  PR_EMS_AB_DELTA_REVOCATION_LIST
+0x8c471102  PR_EMS_AB_SECURITY_POLICY
+0x8c48000b  PR_EMS_AB_SUPPORT_SMIME_SIGNATURES
+0x8c49000b  PR_EMS_AB_DELEGATE_USER
+0x8c50000b  PR_EMS_AB_LIST_PUBLIC_FOLDERS
+0x8c51001e  PR_EMS_AB_LABELEDURI
+0x8c52000b  PR_EMS_AB_RETURN_EXACT_MSG_SIZE
+0x8c53001e  PR_EMS_AB_GENERATION_QUALIFIER
+0x8c54001e  PR_EMS_AB_HOUSE_IDENTIFIER
+0x8c550102  PR_EMS_AB_SUPPORTED_ALGORITHMS
+0x8c56001e  PR_EMS_AB_DMD_NAME
+0x8c57001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_11
+0x8c58001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_12
+0x8c59001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_13
+0x8c60001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_14
+0x8c61001e  PR_EMS_AB_EXTENSION_ATTRIBUTE_15
+0x8c620003  PR_EMS_AB_REPLICATED_OBJECT_VERSION
+0x8c63001e  PR_EMS_AB_MAIL_DROP
+0x8c64001e  PR_EMS_AB_FORWARDING_ADDRESS
+0x8c650102  PR_EMS_AB_FORM_DATA
+0x8c66001e  PR_EMS_AB_OWA_SERVER
+0x8c67001e  PR_EMS_AB_EMPLOYEE_NUMBER
+0x8c68001e  PR_EMS_AB_TELEPHONE_PERSONAL_PAGER
+0x8c69001e  PR_EMS_AB_EMPLOYEE_TYPE
+0x8c6a1102  PR_EMS_AB_TAGGED_X509_CERT
+0x8c6b001e  PR_EMS_AB_PERSONAL_TITLE
+0x8c6c001e  PR_EMS_AB_LANGUAGE_ISO639
+0x8c6d001e  PR_EMS_AB_OBJECT_GUID
+0x8c8e001e  PR_EMS_AB_PHONETIC_GIVEN_NAME
+0x8c8f001e  PR_EMS_AB_PHONETIC_SURNAME
+0x8c90001e  PR_EMS_AB_PHONETIC_DEPARTMENT_NAME
+0x8c91001e  PR_EMS_AB_PHONETIC_COMPANY_NAME
+0x8c92001e  PR_EMS_AB_PHONETIC_DISPLAY_NAME
+0x8c96001e  PR_EMS_AB_ROOM_CONTAINERS
+0xf000000d  PR_EMS_AB_OTHER_RECIPS
+0xfff8101e  PR_EMS_AB_CHILD_RDNS
+0xfff9001e  PR_EMS_AB_HIERARCHY_PATH
+0xfffa0102  PR_EMS_AB_OBJECT_OID
+0xfffb000b  PR_EMS_AB_IS_MASTER
+0xfffc0102  PR_EMS_AB_PARENT_ENTRYID
+0xfffd0003  PR_EMS_AB_CONTAINERID
+0xfffe001e  PR_EMS_AB_SERVER

Added: trunk/openchange/libmapi/conf/mparse.pl
===================================================================
--- trunk/openchange/libmapi/conf/mparse.pl	                        (rev 0)
+++ trunk/openchange/libmapi/conf/mparse.pl	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,877 @@
+#!/usr/bin/perl -w
+
+###################################################
+# package to parse the mapi-properties files and 
+# generate code for libmapi in OpenChange
+#
+# Perl code based on pidl one from Andrew Tridgell and the Samba team
+#
+# Copyright (C) Julien Kerihuel 2005-2008
+# released under the GNU GPL
+
+use strict;
+use Getopt::Long;
+
+my $ret = "";
+my $tabs = "";
+
+sub indent() { $tabs.="\t"; }
+sub deindent() { $tabs = substr($tabs, 1); }
+sub mparse($) { $ret .= $tabs.(shift)."\n"; }
+
+my($opt_outputdir) = '.';
+my($opt_parser) = '';
+
+my	%prop_types = (
+    0x0		=> "PT_UNSPECIFIED",
+    0x1		=> "PT_NULL",
+    0x2		=> "PT_SHORT",
+    0x3		=> "PT_LONG",
+    0x4		=> "PT_FLOAT",
+    0x5		=> "PT_DOUBLE",
+    0x6		=> "PT_CURRENCY",
+    0x7		=> "PT_APPTIME",
+    0xa		=> "PT_ERROR",
+    0xb		=> "PT_BOOLEAN",
+    0xd		=> "PT_OBJECT",
+    0x14	=> "PT_I8",
+    0x1e	=> "PT_STRING8",
+    0x1f	=> "PT_UNICODE",
+    0x40	=> "PT_SYSTIME",
+    0x48	=> "PT_CLSID",
+    0x102	=> "PT_BINARY",
+# Multi-valued property types
+    0x1002	=> "PT_MV_SHORT",
+    0x1003	=> "PT_MV_LONG",
+    0x1004	=> "PT_MV_FLOAT",
+    0x1005	=> "PT_MV_DOUBLE",
+    0x1006	=> "PT_MV_CURRENCY",
+    0x1007	=> "PT_MV_APPTIME",
+    0x1014	=> "PT_MV_I8",
+    0x101e	=> "PT_MV_STRING8",
+    0x101f	=> "PT_MV_UNICODE",
+    0x1040	=> "PT_MV_SYSTIME",
+    0x1048	=> "PT_MV_CLSID",
+    0x1102	=> "PT_MV_BINARY"
+);
+
+my	%prop_names = (
+    "PT_UNSPECIFIED"	=>	0x0,
+    "PT_NULL"		=>	0x1,
+    "PT_SHORT"		=>	0x2,
+    "PT_LONG"		=>	0x3,
+    "PT_FLOAT"		=>	0x4,
+    "PT_DOUBLE"		=>	0x5,
+    "PT_CURRENCY"	=>	0x6,
+    "PT_APPTIME"	=>	0x7,
+    "PT_ERROR"		=>	0xa,
+    "PT_BOOLEAN"	=>	0xb,
+    "PT_OBJECT"		=>	0xd,
+    "PT_I8"		=>	0x14,
+    "PT_STRING8"	=>	0x1e,
+    "PT_UNICODE"	=>	0x1f,
+    "PT_SYSTIME"	=>	0x40,
+    "PT_CLSID"		=>	0x48,
+    "PT_BINARY"		=>	0x102,
+# Multi-valued property types
+    "PT_MV_SHORT"	=>	0x1002,
+    "PT_MV_LONG"	=>	0x1003,
+    "PT_MV_FLOAT"	=>	0x1004,
+    "PT_MV_DOUBLE"	=>	0x1005,
+    "PT_MV_CURRENCY"	=>	0x1006,
+    "PT_MV_APPTIME"	=>	0x1007,
+    "PT_MV_I8"		=>	0x1014,
+    "PT_MV_STRING8"	=>	0x101e,
+    "PT_MV_UNICODE"	=>	0x101f,
+    "PT_MV_SYSTIME"	=>	0x1040,
+    "PT_MV_CLSID"	=>	0x1048,
+    "PT_MV_BINARY"	=>	0x1102
+);
+
+# main program
+
+my $result = GetOptions (
+			 'outputdir=s' => \$opt_outputdir,
+			 'parser=s' => \$opt_parser
+			 );
+
+if (not $result) {
+    exit(1);
+}
+
+#####################################################################
+# read a file into a string
+sub FileLoad($)
+{
+    my($filename) = shift;
+    local(*INPUTFILE);
+    open(INPUTFILE, $filename) || return undef;
+    my($saved_delim) = $/;
+    undef $/;
+    my($data) = <INPUTFILE>;
+    close(INPUTFILE);
+    $/ = $saved_delim;
+    return $data;
+}
+
+#####################################################################
+# write a string into a file
+sub FileSave($$)
+{
+    my($filename) = shift;
+    my($v) = shift;
+    local(*FILE);
+    open(FILE, ">$filename") || die "can't open $filename";    
+    print FILE $v;
+    close(FILE);
+}
+
+#####################################################################
+# generate mapitags.h file
+sub mapitags_header($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my $prop_value;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __MAPITAGS_H__";
+    mparse "#define __MAPITAGS_H__";
+    mparse "";
+
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    $prop_type = hex $prop[0];
+	    $prop_type &= 0xFFFF;
+	    $prop_value = hex $prop[0];
+	    $prop_value = ($prop_value >> 16) & 0xFFFF;
+
+	    mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", $prop[1], $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type});
+	    if (($prop_type == 0x1e) || ($prop_type == 0x101e)){
+		$prop_type++;
+		$prop[0] = sprintf "0x%.8x", ((hex $prop[0]) & 0xFFFF0000) + $prop_type;
+		mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", "$prop[1]_UNICODE", $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type});
+	    }
+	    $prop_type = 0xa;
+	    $prop[0] = sprintf "0x%.8x", ((hex $prop[0]) & 0xFFFF0000) + $prop_type;
+	    mparse sprintf "#define %-51s PROP_TAG(%-13s, 0x%.04x) /* %s */", "$prop[1]_ERROR", $prop_types{$prop_type}, $prop_value, $prop[0] if ($prop_types{$prop_type});
+	}
+    }
+    mparse "";
+    mparse "#endif /* !__MAPITAGS_H__ */";
+
+    return $ret;
+    
+}
+
+
+#####################################################################
+# generate mapitags.c file
+sub mapitags_interface($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my $prop_value;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#include <libmapi/libmapi.h>";
+    mparse "#include <libmapi/proto_private.h>";
+    mparse "#include <gen_ndr/ndr_exchange.h>";
+    mparse "#include <libmapi/mapitags.h>";
+    mparse "";
+    mparse "struct mapi_proptags";
+    mparse "{";
+    indent;
+    mparse "uint32_t	proptag;";
+    mparse "uint32_t	proptype;";
+    mparse "const char	*propname;";
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "static struct mapi_proptags mapitags[] = {";
+    indent;
+    
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    $prop_type = hex $prop[0];
+	    $prop_type &= 0xFFFF;
+	    $prop_value = hex $prop[0];
+	    $prop_value = ($prop_value >> 16) & 0xFFFF;
+	    if ($prop_types{$prop_type}) {
+		mparse sprintf "{ %-51s, %-13s, \"%s\" },", $prop[1], $prop_types{$prop_type}, $prop[1];
+		if (($prop_type == 0x1e) || ($prop_type == 0x101e)) {
+		    $prop_type++;
+		    mparse sprintf "{ %-51s, %-13s, \"%s\" },", "$prop[1]_UNICODE", $prop_types{$prop_type}, "$prop[1]_UNICODE";
+		}
+		$prop_type = 0xa;
+		mparse sprintf "{ %-51s, %-13s, \"%s\" },", "$prop[1]_ERROR", $prop_types{$prop_type}, $prop[1];
+	    }
+	}
+    }
+
+    mparse sprintf "{ %-51s, %-13d, \"NULL\"}", 0, 0;
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "_PUBLIC_ const char *get_proptag_name(uint32_t proptag)";
+    mparse "{";
+    indent;
+    mparse "uint32_t idx;";
+    mparse "";
+    mparse "for (idx = 0; mapitags[idx].proptag; idx++) {";
+    indent;
+    mparse "if (mapitags[idx].proptag == proptag) { ";
+    indent;
+    mparse "return mapitags[idx].propname;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "_PUBLIC_ uint32_t get_proptag_value(const char *propname)";
+    mparse "{";
+    indent;
+    mparse "uint32_t idx;";
+    mparse "";
+    mparse "for (idx = 0; mapitags[idx].proptag; idx++) {";
+    indent;
+    mparse "if (!strcmp(mapitags[idx].propname, propname)) { ";
+    indent;
+    mparse "return mapitags[idx].proptag;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return 0;";
+    deindent;
+    mparse "}";
+    mparse "";
+
+    return $ret;
+    
+}
+
+#####################################################################
+# generate mapitags_enum.idl file
+sub mapitags_enum($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my %hash;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "";
+
+    mparse "typedef [v1_enum, flag(NDR_PAHEX)] enum {";
+    indent;
+    
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    $prop_type = hex $prop[0];
+	    $prop_type &= 0xFFFF;
+
+	    mparse sprintf "%-51s = %s,", $prop[1], $prop[0];
+
+	    if (($prop_type == 0x1e) || ($prop_type == 0x101e)) {
+		$prop_type = hex $prop[0];
+		$prop_type++;
+		mparse sprintf "%-51s = 0x%.8x,", "$prop[1]_UNICODE", $prop_type;
+	    }
+	    if (!exists($hash{((hex $prop[0]) & 0xFFFF0000)})) {
+		$prop_type = 0xa;
+		$prop_type += ((hex $prop[0]) & 0xFFFF0000);
+		mparse sprintf "%-51s = 0x%.8x,", "$prop[1]_ERROR", $prop_type;
+		$hash{((hex $prop[0]) & 0xFFFF0000)} = 1;
+	    }
+	}
+    }
+    mparse sprintf "%-51s = %s", "MAPI_PROP_RESERVED", "0xFFFFFFFF";
+    deindent;
+    mparse "} MAPITAGS;";    
+    mparse "";
+    
+    return $ret;
+}
+
+#####################################################################
+# generate swig_mapitags.h file
+sub mapitags_swig($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my $prop_value;
+    my %hash;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __SWIG_MAPITAGS_H__";
+    mparse "#define __SWIG_MAPITAGS_H__";
+    mparse "";
+
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    $prop_type = hex $prop[0];
+	    $prop_type &= 0xFFFF;
+
+	    mparse sprintf "#define %-51s %s", $prop[1], $prop[0];
+
+	    if (($prop_type == 0x1e) || ($prop_type == 0x101e)) {
+		$prop_type = hex $prop[0];
+		$prop_type++;
+		mparse sprintf "#define %-51s 0x%.8x", "$prop[1]_UNICODE", $prop_type;
+	    }
+	    if (!exists($hash{((hex $prop[0]) & 0xFFFF0000)})) {
+		$prop_type = 0xa;
+		$prop_type += ((hex $prop[0]) & 0xFFFF0000);
+		mparse sprintf "#define %-51s 0x%.8x", "$prop[1]_ERROR", $prop_type;
+		$hash{((hex $prop[0]) & 0xFFFF0000)} = 1;
+	    }
+	}
+    }
+
+    mparse "";
+    mparse "#endif /* !__SWIG_MAPITAGS_H__ */";
+
+    return $ret;  
+}
+
+#####################################################################
+# generate mapi_nameid_private.h file
+sub mapi_nameid_private_header($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_OOM;
+    my $prop_ID;
+    my $prop_Type;
+    my $prop_name;
+    my $prop_Kind;
+    my $prop_OLEGUID;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __MAPI_NAMEID_PRIVATE_H__";
+    mparse "#define __MAPI_NAMEID_PRIVATE_H__";
+    mparse "";
+    mparse "static struct mapi_nameid_tags mapi_nameid_tags[] = {";
+    indent;
+    
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+
+	    if ($prop[1] ne "NULL") {
+		$prop[1] = sprintf "\"%s\"", $prop[1];
+	    }
+	    if ($prop[3] ne "NULL") {
+		$prop[3] = sprintf "\"%s\"", $prop[3]
+	    }
+	    if ($prop[0] eq "NULL") {
+		$prop[0] = "0x00000000";
+	    }
+	    mparse sprintf "{ %-51s, %-40s, %-15s, %-30s, %-30s, %-15s, %-20s, 0x0 },", 
+	    $prop[0], $prop[1], $prop[2], $prop[3], $prop[4], $prop[5], $prop[6];
+	}
+    }
+
+    mparse sprintf "{ 0x00000000, NULL, 0x0, NULL, PT_UNSPECIFIED, 0x0, NULL, 0x0 }";
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "#endif /* !MAPI_NAMEID_PRIVATE_H__ */";
+
+    return $ret;
+}
+
+#####################################################################
+# generate mapi_nameid.h file
+sub mapi_nameid_header($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $propID;
+    my $proptype;
+    my $property;
+    my $counter = 0;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __MAPI_NAMEID_H__";
+    mparse "#define __MAPI_NAMEID_H__";
+    mparse "";
+
+    mparse "/* NOTE TO DEVELOPERS: If this is a MNID_STRING named property,";
+    mparse " * then we use the arbitrary 0xa000-0afff property ID range for";
+    mparse " * internal mapping purpose only.";
+    mparse " */";
+
+    mparse "";
+    mparse "struct mapi_nameid_tags {";
+    indent;
+    mparse "uint32_t			proptag;";
+    mparse "const char			*OOM;";
+    mparse "uint16_t			lid;";
+    mparse "const char			*Name;";
+    mparse "uint32_t			propType;";
+    mparse "uint8_t				ulKind;";
+    mparse "const char			*OLEGUID;";
+    mparse "uint32_t			position;";
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "struct mapi_nameid {";
+    indent;
+    mparse "struct MAPINAMEID		*nameid;";
+    mparse "uint16_t			count;";
+    mparse "struct mapi_nameid_tags		*entries;";
+    deindent;
+    mparse "};";
+    mparse "";
+
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    if ($prop[0] ne "NULL") {
+		$proptype = $prop_names{$prop[4]};
+		$propID = hex $prop[2];
+		if ($propID == 0) {
+		    # 40960 == 0xa000
+		    $propID = 40960 + $counter;
+		    $counter++;
+		}
+		$property = sprintf "0x%.8x", ($propID << 16) | $proptype;
+		mparse sprintf "#define %-51s %s", $prop[0], $property; 
+	    }
+	}
+    }
+
+    mparse "";
+    mparse "#endif /* !MAPI_NAMEID_H__ */";
+
+    return $ret;
+}
+
+#####################################################################
+# generate mapicode.h file
+sub mapicodes_header($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $error;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __MAPICODE_H__";
+    mparse "#define __MAPICODE_H__";
+    mparse "";
+    mparse "#define MAPI_RETVAL_IF(x,e,c)	\\";
+    mparse "do {				\\";
+    mparse "	if (x) {			\\";
+    mparse "		errno = (e);		\\";
+    mparse "		if (c) {		\\";
+    mparse "			talloc_free(c);	\\";
+    mparse "		}			\\";
+    mparse "		return -1;		\\";
+    mparse "	}				\\";
+    mparse "} while (0);";
+    mparse "";
+    mparse "#define OPENCHANGE_RETVAL_IF(x,e,c)	\\";
+    mparse "do {				\\";
+    mparse "	if (x) {			\\";
+    mparse "		set_errno(e);		\\";
+    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);			\\";
+    mparse "	if (c) {			\\";
+    mparse "		talloc_free(c);		\\";
+    mparse "	}				\\";
+    mparse "	return (e);			\\";
+    mparse "} while (0);";
+    mparse "";
+    mparse "/* Status macros for MAPI */";
+    mparse "typedef unsigned long	SCODE;";
+    mparse "";
+    mparse "";
+    mparse "#define SEVERITY_ERROR	1";
+    mparse "#define SEVERITY_WARN	0";
+    mparse "";
+    mparse "#define FACILITY_ITF	4";
+    mparse "#define	MAKE_MAPI_CODE(sev, fac, code) \\";
+    mparse "(((SCODE)(sev)<<31)|((SCODE)(fac)<<16)|((SCODE)(code)))";
+    mparse "";
+    mparse "#define	MAKE_MAPI_E(code) (MAKE_MAPI_CODE(SEVERITY_ERROR, FACILITY_ITF, code))";
+    mparse "#define	MAKE_MAPI_S(code) (MAKE_MAPI_CODE(SEVERITY_WARN, FACILITY_ITF, code))";
+    mparse "";
+    mparse "#define	MAPI_STATUS_V(x) ((SCODE)x)";
+    mparse "";
+    mparse "#define	MAPI_STATUS_IS_OK(x) (MAPI_STATUS_V(x) == 0)";
+    mparse "#define	MAPI_STATUS_IS_ERR(x) ((MAPI_STATUS_V(x) & 0xc0000000) == 0xc0000000)";
+    mparse "#define	MAPI_STATUS_EQUAL(x,y) (MAPI_STATUS_V(x) == MAPI_STATUS_V(y))";
+    mparse "";
+    mparse "#define	MAPI_STATUS_IS_OK_RETURN(x) do { \\";
+    mparse "		if (MAPI_STATUS_IS_OK(x)) {\\";
+    mparse "			return x;\\";
+    mparse "		}\\";
+    mparse "} while (0)";
+    mparse "";
+    mparse "#define	MAPI_STATUS_NOT_OK_RETURN(x) do { \\";
+    mparse "		if (!MAPI_STATUS_IS_OK(x)) {\\";
+    mparse "			return x;\\";
+    mparse "		}\\";
+    mparse "} while (0)";
+    mparse "";
+    mparse "#define	MAPI_STATUS_IS_ERR_RETURN(x) do { \\";
+    mparse "		if (MAPI_STATUS_IS_ERR(x)) {\\";
+    mparse "			return x;\\";
+    mparse "		}\\";
+    mparse "} while (0)";
+    mparse "";
+    mparse "#define	MAPI_STATUS_NOT_ERR_RETURN(x) do { \\";
+    mparse "		if (!MAPI_STATUS_IS_ERR(x)) {\\";
+    mparse "			return x;\\";
+    mparse "		}\\";
+    mparse "} while (0)";
+    mparse "";
+    mparse "";
+    mparse "#endif /* !__MAPICODE_H__ */";
+
+    return $ret;
+    
+}
+
+#####################################################################
+# generate mapicode.c file
+
+sub mapicodes_interface($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @errors;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#include <libmapi/libmapi.h>";
+    mparse "#include <libmapi/proto_private.h>";
+    mparse "#include <gen_ndr/ndr_exchange.h>";
+    mparse "";
+    mparse "void set_errno(enum MAPISTATUS status)";
+    mparse "{";
+    indent;
+    mparse "errno = status;";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "struct mapi_retval {";
+    indent;
+    mparse "uint32_t	err;";
+    mparse "const char	*name;";
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "static const struct mapi_retval mapi_retval[] = {";
+    indent;
+
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @errors = split(/\s+/, $line);
+	    mparse sprintf "{ %8s, \"%s\" },", $errors[0], $errors[1];
+	}
+    }
+
+
+    mparse " { 0x00000000, NULL }";
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "_PUBLIC_ void mapi_errstr(const char *function, uint32_t mapi_code)";
+    mparse "{";
+    indent;
+    mparse "struct ndr_print	ndr_print;";
+    mparse "";
+    mparse "ndr_print.depth = 1;";
+    mparse "ndr_print.print = ndr_print_debug_helper;";
+    mparse "ndr_print_MAPISTATUS(&ndr_print, function, mapi_code);";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "_PUBLIC_ const char *mapi_get_errstr(uint32_t mapi_code)";
+    mparse "{";
+    indent;
+    mparse "uint32_t i;";
+    mparse "";
+    mparse "for (i = 0; mapi_retval[i].name; i++) {";
+    indent;
+    mparse "if (mapi_retval[i].err == mapi_code) {";
+    indent;
+    mparse "return mapi_retval[i].name;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+}
+
+#####################################################################
+# generate mapicodes_enum.idl file
+sub mapicodes_enum($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "";
+
+    mparse "typedef [public, v1_enum, flag(NDR_PAHEX)] enum {";
+    indent;
+    
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    mparse sprintf "%-51s = %s,", $prop[1], $prop[0];
+	}
+    }
+    mparse sprintf "%-51s = %s", "MAPI_E_RESERVED", "0xFFFFFFFF";
+    deindent;
+    mparse "} MAPISTATUS;";    
+    mparse "";
+    
+    return $ret;
+}
+
+#####################################################################
+# generate openchangedb_property.c file
+sub openchangedb_property($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my $prop_value;
+    my $pidtag;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#include <mapiproxy/dcesrv_mapiproxy.h>";
+    mparse "#include \"libmapiproxy.h\"";
+    mparse "#include <libmapi/libmapi.h>";
+    mparse "#include <libmapi/proto_private.h>";
+    mparse "#include <libmapi/defs_private.h>";
+    mparse "";
+    mparse "struct pidtags {";
+    mparse "	uint32_t	proptag;";
+    mparse "	const char	*pidtag;";
+    mparse "};";
+    mparse "";
+    mparse "static struct pidtags pidtags[] = {";
+    indent;
+    
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    $prop_type = hex $prop[0];
+	    $prop_type &= 0xFFFF;
+	    $prop_value = hex $prop[0];
+	    $prop_value = ($prop_value >> 16) & 0xFFFF;
+	    if ($prop_types{$prop_type}) {
+		if ($prop[2]) {
+		    mparse sprintf "{ %-51s, \"%s\"},", $prop[1], $prop[2];
+		} else {
+		    mparse sprintf "{ %-51s, \"0x%.8x\"},", $prop[1], hex $prop[0];
+		}
+
+		if (($prop_type == 0x1e) ||  ($prop_type == 0x101e)) {
+		    if ($prop[2]) {
+			mparse sprintf "{ %-51s, \"%s\"},", "$prop[1]_UNICODE", $prop[2];
+		    } else {
+			mparse sprintf "{ %-51s, \"0x%.8x\"},", "$prop[1]_UNICODE", hex $prop[0];
+		    }
+		}
+	    }
+	}
+    }
+
+    mparse sprintf "{ %-51s, NULL }", 0;
+    deindent;
+    mparse "};";
+    mparse "";
+    mparse "_PUBLIC_ const char *openchangedb_property_get_attribute(uint32_t proptag)";
+    mparse "{";
+    indent;
+    mparse "uint32_t i;";
+    mparse "";
+    mparse "for (i = 0; pidtags[i].pidtag; i++) {";
+    indent;
+    mparse "if (pidtags[i].proptag == proptag) {";
+    indent;
+    mparse "return pidtags[i].pidtag;";
+    deindent;
+    mparse "}";
+    deindent;
+    mparse "}";
+    mparse "DEBUG(0, (\"[%s:%d]: Unsupported property tag '0x%.8x'\\n\", __FUNCTION__, __LINE__, proptag));";
+    mparse "";
+    mparse "return NULL;";
+    deindent;
+    mparse "}";
+}
+
+#####################################################################
+# generate swig_mapicodes.h file
+sub mapicodes_swig($)
+{
+    my $contents = shift;
+    my $line;
+    my @lines;
+    my @prop;
+    my $prop_type;
+    my $prop_value;
+
+    mparse "/* parser auto-generated by mparse */";
+    mparse "#ifndef __SWIG_MAPICODES_H__";
+    mparse "#define __SWIG_MAPICODES_H__";
+    mparse "";
+
+    @lines = split(/\n/, $contents);
+    foreach $line (@lines) {
+	$line =~ s/^\#+.*$//;
+	if ($line) {
+	    @prop = split(/\s+/, $line);
+	    mparse sprintf "#define %-51s %s", $prop[1], $prop[0];
+	}
+    }
+    mparse sprintf "#define %-51s %s", "MAPI_E_RESERVED", "0xFFFFFFFF";
+    mparse "";
+    mparse "#endif /* !__SWIG_MAPITAGS_H__ */";
+
+    return $ret;  
+}
+
+sub process_file($)
+{
+    my $mapi_file = shift;
+    my $outputdir = $opt_outputdir;
+
+    print "Parsing $mapi_file\n";
+    my $contents = FileLoad($mapi_file);
+    defined $contents || return undef;
+
+    
+    if ($opt_parser eq "mapitags") {
+	print "Generating $outputdir" . "mapitags.h\n";
+	my $parser = ("$outputdir/mapitags.h");
+	FileSave($parser, mapitags_header($contents));
+	
+	print "Generating $outputdir" . "mapitags.c\n";
+	$ret = '';
+	my $code_parser = ("$outputdir/mapitags.c");
+	FileSave($code_parser, mapitags_interface($contents));
+	
+	print "Generating mapitags_enum.h\n";
+	$ret = '';
+	my $enum_parser = ("mapitags_enum.h");
+	FileSave($enum_parser, mapitags_enum($contents));
+    }
+
+    if ($opt_parser eq "mapicodes") {
+	print "Generating $outputdir" . "mapicode.h\n";
+	my $parser = ("$outputdir/mapicode.h");
+	FileSave($parser, mapicodes_header($contents));
+
+	print "Generating $outputdir" . "mapicode.c\n";
+	$ret = '';
+	my $code_parser = ("$outputdir/mapicode.c");
+	FileSave($code_parser, mapicodes_interface($contents));
+
+	print "Generating mapicodes_enum.h\n";
+	$ret = '';
+	my $enum_parser = ("mapicodes_enum.h");
+	FileSave($enum_parser, mapicodes_enum($contents));
+    }
+
+    if ($opt_parser eq "mapi_nameid") {
+	print "Generating $outputdir" . "mapi_nameid_private.h\n";
+	$ret = '';
+	my $parser = ("$outputdir/mapi_nameid_private.h");
+	FileSave($parser, mapi_nameid_private_header($contents));
+
+	print "Generating $outputdir" . "mapi_nameid.h\n";
+	$ret = '';
+	my $nameid_parser = ("$outputdir/mapi_nameid.h");
+	FileSave($nameid_parser, mapi_nameid_header($contents));
+    }
+
+    if ($opt_parser eq "swig_mapitags") {
+	print "Generating $outputdir" . "swig_mapitags.h\n";
+	$ret = '';
+	my $swig_parser_tag = ("$outputdir/swig_mapitags.h");
+	FileSave($swig_parser_tag, mapitags_swig($contents));
+    }
+    
+    if ($opt_parser eq "swig_mapicodes") {
+	print "Generating $outputdir" . "swig_mapicodes.h\n";
+	my $swig_parser_code = ("$outputdir/swig_mapicodes.h");
+	FileSave($swig_parser_code, mapicodes_swig($contents));
+    }
+
+    if ($opt_parser eq "openchangedb_property") {
+	print "Generating $outputdir" . "openchangedb_property.c\n";
+	my $openchangedb_parser = ("$outputdir/openchangedb_property.c");
+	FileSave($openchangedb_parser, openchangedb_property($contents));
+    }
+}
+
+process_file($_) foreach (@ARGV);


Property changes on: trunk/openchange/libmapi/conf/mparse.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/libmapi/defs_private.h
===================================================================
--- trunk/openchange/libmapi/defs_private.h	                        (rev 0)
+++ trunk/openchange/libmapi/defs_private.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,43 @@
+/*
+   OpenChange MAPI implementation.
+   Private definitions
+
+   Copyright (C) Brad Hards <bradh at frogmouth.net> 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	_DEFS_PRIVATE_H
+#define	_DEFS_PRIVATE_H
+
+/* These are essentially local versions of part of the 
+   C99 __STDC_FORMAT_MACROS */
+#ifndef PRIx64
+#if __WORDSIZE == 64
+  #define PRIx64        "lx"
+#else
+  #define PRIx64        "llx"
+#endif
+#endif
+
+#ifndef PRIX64
+#if __WORDSIZE == 64
+  #define PRIX64        "lX"
+#else
+  #define PRIX64        "llX"
+#endif
+#endif
+
+
+#endif	/* ! _DEFS_PRIVATE_H */

Added: trunk/openchange/libmapi/dlinklist.h
===================================================================
--- trunk/openchange/libmapi/dlinklist.h	                        (rev 0)
+++ trunk/openchange/libmapi/dlinklist.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,110 @@
+/* 
+   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)

Added: trunk/openchange/libmapi/emsmdb.c
===================================================================
--- trunk/openchange/libmapi/emsmdb.c	                        (rev 0)
+++ trunk/openchange/libmapi/emsmdb.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,835 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005 - 2008.
+   Copyright (C) Jelmer Vernooij 2005.
+ 
+   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 <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <gen_ndr/ndr_exchange_c.h>
+#include <gen_ndr/ndr_misc.h>
+
+#include <param.h>
+#include <credentials.h>
+
+/**
+   \file emsmdb.c
+
+   \brief EMSMDB stack functions
+ */
+
+
+/**
+   \details Hash a string and returns a unsigned integer hash value
+
+   \param str the string to hash
+
+   \return a hash value greater than 0 on success, otherwise 0
+
+   \note This function is based on the hash algorithm from gdbm and
+   from Samba4 TDB code.
+ */
+static unsigned int emsmdb_hash(const char *str)
+{
+	uint32_t	value;	/* Used to compute the hash value.  */
+	uint32_t	i;	/* Used to cycle through random values. */
+	uint32_t	len;
+
+	/* Sanity check */
+	if (!str) return 0;
+
+	len = strlen(str);
+
+	/* Set the initial value from the key size. */
+	for (value = 0x238F13AF * len, i = 0; i < len; i++)
+		value = (value + (str[i] << (i * 5 % 24)));
+
+	return (1103515243 * value + 12345);  
+}
+
+
+/**
+   \details Establishes a new Session Context with the server on the
+   exchange_emsmdb pipe
+
+   \param parent_mem_ctx pointer to the memory context
+   \param session pointer to the MAPI session context
+   \param p pointer to the DCERPC pipe
+   \param cred pointer to the user credentials
+
+   \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)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct EcDoConnect	r;
+	struct emsmdb_context	*ret;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	uint32_t		pullTimeStamp = 0;
+
+	/* Sanity Checks */
+	if (!session) return NULL;
+	if (!p) return NULL;
+	if (!cred) return NULL;
+
+	mem_ctx = talloc_named(NULL, 0, "emsmdb_connect");
+
+	ret = talloc_zero(parent_mem_ctx, struct emsmdb_context);
+	ret->rpc_connection = p;
+	ret->mem_ctx = parent_mem_ctx;
+
+	ret->cache_requests = talloc(parent_mem_ctx, struct EcDoRpc_MAPI_REQ *);
+	ret->info.szDisplayName = NULL;
+	ret->info.szDNPrefix = NULL;
+
+	r.in.szUserDN = session->profile->mailbox;
+	r.in.ulFlags = 0x00000000;
+	r.in.ulConMod = emsmdb_hash(r.in.szUserDN);
+	r.in.cbLimit = 0x00000000;
+	r.in.ulCpid = session->profile->codepage;
+	r.in.ulLcidString = session->profile->language;
+	r.in.ulLcidSort = session->profile->method;
+	r.in.ulIcxrLink = 0xFFFFFFFF;
+	r.in.usFCanConvertCodePages = 0x1;
+	r.in.rgwClientVersion[0] = 0x000c;
+	r.in.rgwClientVersion[1] = 0x183e;
+	r.in.rgwClientVersion[2] = 0x03e8;
+	r.in.pullTimeStamp = &pullTimeStamp;
+
+	r.out.handle = &ret->handle;
+	r.out.pcmsPollsMax = &ret->info.pcmsPollsMax;
+	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) {
+		mapi_errstr("EcDoConnect", retval);
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	ret->info.szDisplayName = talloc_strdup(parent_mem_ctx, r.out.szDisplayName);
+	ret->info.szDNPrefix = talloc_strdup(parent_mem_ctx, r.out.szDNPrefix);
+
+	ret->cred = cred;
+	ret->max_data = 0xFFF0;
+	ret->setup = false;
+
+	talloc_free(mem_ctx);
+
+	return ret;
+}
+
+
+/**
+   \details Destructor for the EMSMDB context. Call the EcDoDisconnect
+   function.
+
+   \param data generic pointer to data with mapi_provider information
+
+   \return MAPI_E_SUCCESS on success, otherwise -1
+ */
+int emsmdb_disconnect_dtor(void *data)
+{
+	struct mapi_provider	*provider = (struct mapi_provider *)data;
+	struct emsmdb_context	*emsmdb_ctx;
+
+	emsmdb_ctx = (struct emsmdb_context *)provider->ctx;
+	emsmdb_disconnect(provider->ctx);	
+
+	talloc_free(emsmdb_ctx->cache_requests);
+
+	if (emsmdb_ctx->info.szDisplayName) {
+		talloc_free(emsmdb_ctx->info.szDisplayName);
+	}
+
+	if (emsmdb_ctx->info.szDNPrefix) {
+		talloc_free(emsmdb_ctx->info.szDNPrefix);
+	}
+
+	return 0;
+}
+
+
+/**
+   \details Destroy the EMSMDB context handle
+
+   \param emsmdb_ctx pointer to the EMSMDB context
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+enum MAPISTATUS emsmdb_disconnect(struct emsmdb_context *emsmdb_ctx)
+{
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	struct EcDoDisconnect	r;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!emsmdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	r.in.handle = r.out.handle = &emsmdb_ctx->handle;
+
+	status = dcerpc_EcDoDisconnect(emsmdb_ctx->rpc_connection, emsmdb_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Send an empty MAPI packet - useful to keep connection up
+   or force notifications.
+
+   \param emsmdb_ctx pointer to the EMSMDB connection context
+   \param res pointer on pointer to a MAPI response structure
+
+   \return NT_STATUS_OK on success, otherwise NT status error
+ */
+_PUBLIC_ NTSTATUS emsmdb_transaction_null(struct emsmdb_context *emsmdb_ctx, 
+					  struct mapi_response **res)
+{
+	struct EcDoRpc		r;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	NTSTATUS		status;
+	uint16_t		*length;
+
+	/* Sanity checks */
+	if(!emsmdb_ctx) return NT_STATUS_INVALID_PARAMETER;
+	if (!res) return NT_STATUS_INVALID_PARAMETER;
+
+	mapi_request = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_request);
+	mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response);
+
+	r.in.mapi_request = mapi_request;
+	r.in.mapi_request->mapi_len = 2;
+	r.in.mapi_request->length = 2;
+
+	r.in.handle = r.out.handle = &emsmdb_ctx->handle;
+	r.in.size = emsmdb_ctx->max_data;
+	r.in.offset = 0x0;
+	r.in.max_data = emsmdb_ctx->max_data;
+	length = talloc_zero(emsmdb_ctx->mem_ctx, uint16_t);
+	*length = r.in.mapi_request->mapi_len;
+	r.in.length = r.out.length = length;
+
+	r.out.mapi_response = mapi_response;
+
+	status = dcerpc_EcDoRpc(emsmdb_ctx->rpc_connection, emsmdb_ctx->mem_ctx, &r);
+	if (!MAPI_STATUS_IS_OK(NT_STATUS_V(status))) {
+		return status;
+	}
+
+	*res = mapi_response;
+
+	return status;
+}
+
+
+static int mapi_response_destructor(void *data)
+{
+	struct mapi_response	*mapi_response = (struct mapi_response *)data;
+
+	if (mapi_response->handles) {
+		talloc_free(mapi_response->handles);
+	}
+
+	if (mapi_response->mapi_repl) {
+		talloc_free(mapi_response->mapi_repl);
+	}
+
+	return 0;
+}
+
+
+/**
+   \details Make a EMSMDB transaction.
+
+   \param emsmdb_ctx pointer to the EMSMDB connection context
+   \param req pointer to the MAPI request to send
+   \param repl pointer on pointer to the MAPI reply returned by the
+   server
+
+   \return NT_STATUS_OK on success, otherwise NT status error
+ */
+_PUBLIC_ NTSTATUS emsmdb_transaction(struct emsmdb_context *emsmdb_ctx, 
+				     struct mapi_request *req, 
+				     struct mapi_response **repl)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct EcDoRpc		r;
+	struct mapi_response	*mapi_response;
+	uint16_t		*length;
+	NTSTATUS		status;
+	struct EcDoRpc_MAPI_REQ	*multi_req;
+	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;
+
+	mapi_response = talloc_zero(emsmdb_ctx->mem_ctx, struct mapi_response);	
+	talloc_set_destructor((void *)mapi_response, (int (*)(void *))mapi_response_destructor);
+	r.out.mapi_response = mapi_response;
+
+	/* process cached data */
+	if (emsmdb_ctx->cache_count) {
+		multi_req = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REQ, emsmdb_ctx->cache_count + 2);
+		for (i = 0; i < emsmdb_ctx->cache_count; i++) {
+			multi_req[i] = *emsmdb_ctx->cache_requests[i];
+		}
+		multi_req[i] = req->mapi_req[0];
+		req->mapi_req = multi_req;
+	}
+
+	req->mapi_req = talloc_realloc(mem_ctx, req->mapi_req, struct EcDoRpc_MAPI_REQ, emsmdb_ctx->cache_count + 2);
+	req->mapi_req[i+1].opnum = 0;
+
+	r.in.mapi_request = req;
+	r.in.mapi_request->mapi_len += emsmdb_ctx->cache_size;
+	r.in.mapi_request->length += emsmdb_ctx->cache_size;
+	length = talloc_zero(mem_ctx, uint16_t);
+	*length = r.in.mapi_request->mapi_len;
+	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);
+	if (!NT_STATUS_IS_OK(status)) {
+		if (emsmdb_ctx->setup == false) {
+			errno = 0;
+			emsmdb_ctx->max_data = 0x7FFF;
+			emsmdb_ctx->setup = true;
+			talloc_free(mem_ctx);
+			goto start;
+		} else {
+			talloc_free(mem_ctx);
+			return status;
+		}
+	} else {
+		emsmdb_ctx->setup = true;
+	}
+	emsmdb_ctx->cache_size = emsmdb_ctx->cache_count = 0;
+
+	*repl = r.out.mapi_response;
+
+	talloc_free(mem_ctx);
+
+	return status;
+}
+
+
+/**
+   \details Initialize the notify context structure and bind a local
+   UDP port to receive notifications from the server
+
+   \param mem_ctx pointer to the memory context
+
+   \return an allocated mapi_notify_ctx structure on success,
+   otherwise NULL
+ */
+struct mapi_notify_ctx *emsmdb_bind_notification(TALLOC_CTX *mem_ctx)
+{
+	struct interface	*ifaces;
+	struct mapi_notify_ctx	*notify_ctx = NULL;
+	unsigned short		port = DFLT_NOTIF_PORT;
+	const char		*ipaddr = NULL;
+	uint32_t		try = 0;
+
+	/* Sanity Checks */
+	if (!global_mapi_ctx) return NULL;
+	if (!global_mapi_ctx->session) return NULL;
+	if (!global_mapi_ctx->session->profile) return NULL;
+
+	notify_ctx = talloc_zero(mem_ctx, struct mapi_notify_ctx);
+
+	notify_ctx->notifications = talloc_zero((TALLOC_CTX *)notify_ctx, struct notifications);
+	notify_ctx->notifications->prev = NULL;
+	notify_ctx->notifications->next = NULL;
+
+	load_interfaces(mem_ctx, lp_interfaces(global_mapi_ctx->lp_ctx), &ifaces);
+	ipaddr = iface_best_ip(ifaces, global_mapi_ctx->session->profile->server);
+	if (!ipaddr) {
+		talloc_free(notify_ctx->notifications);
+		talloc_free(notify_ctx);
+		return NULL;
+	}
+	notify_ctx->addr = talloc_zero(mem_ctx, struct sockaddr);
+	notify_ctx->addr->sa_family = AF_INET;
+	((struct sockaddr_in *)(notify_ctx->addr))->sin_addr.s_addr = inet_addr(ipaddr);
+retry:
+	if (try) port++;
+	((struct sockaddr_in *)(notify_ctx->addr))->sin_port = htons(port);
+
+	notify_ctx->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (notify_ctx->fd == -1) {
+		talloc_free(notify_ctx->notifications);
+		talloc_free(notify_ctx->addr);
+		talloc_free(notify_ctx);
+		return NULL;
+	}
+
+	if (bind(notify_ctx->fd, notify_ctx->addr, sizeof(struct sockaddr)) == -1) {
+		shutdown(notify_ctx->fd, SHUT_RDWR);
+		close(notify_ctx->fd);
+		if (try < 3) {
+			try++;
+			errno = 0;
+			goto retry;
+		}
+
+		talloc_free(notify_ctx->notifications);
+		talloc_free(notify_ctx->addr);
+		talloc_free(notify_ctx);
+		return NULL;
+	}
+
+	return notify_ctx;
+}
+
+
+/**
+   \details Register for notifications on the server
+   
+   \param notifkey The opaque client-generated context data
+   \param ulEventMask Notification flags. Exchange completely ignores
+   this value and it should be set to 0
+
+   \return NTSTATUS_OK on success, otherwise NT status error
+ */
+NTSTATUS emsmdb_register_notification(struct NOTIFKEY *notifkey, 
+				      uint16_t ulEventMask)
+{
+	struct EcRRegisterPushNotification	request;
+	NTSTATUS				status;
+	enum MAPISTATUS				retval;
+	TALLOC_CTX				*mem_ctx;
+	struct emsmdb_context			*emsmdb_ctx;
+	struct mapi_session			*session;
+	struct mapi_notify_ctx			*notify_ctx;
+	struct policy_handle			handle;
+	uint32_t				hNotification = 0;
+
+	/* Sanity Checks*/
+	if (!global_mapi_ctx) return NT_STATUS_INVALID_PARAMETER;
+	if (!global_mapi_ctx->session) return NT_STATUS_INVALID_PARAMETER;
+	if (!global_mapi_ctx->session->emsmdb) return NT_STATUS_INVALID_PARAMETER;
+	if (!global_mapi_ctx->session->emsmdb->ctx) return NT_STATUS_INVALID_PARAMETER;
+	if (!notifkey) return NT_STATUS_INVALID_PARAMETER;
+
+	session = (struct mapi_session *)global_mapi_ctx->session;
+	emsmdb_ctx = (struct emsmdb_context *)session->emsmdb->ctx;
+	notify_ctx = (struct mapi_notify_ctx *)session->notify_ctx;
+	mem_ctx = talloc_named(NULL, 0, "emsmdb_register_notification");
+
+	request.in.handle = &emsmdb_ctx->handle;
+	request.in.ulEventMask = ulEventMask;
+	request.in.cbContext = notifkey->cb;
+	request.in.rgbContext = talloc_array(mem_ctx, uint8_t, request.in.cbContext);
+	memcpy(request.in.rgbContext, notifkey->ab, request.in.cbContext);
+	request.in.grbitAdviseBits = 0xffffffff;
+	request.in.rgCallbackAddress = talloc_array(mem_ctx, uint8_t, sizeof (struct sockaddr));
+	/* cp address family and length */
+	request.in.rgCallbackAddress[0] = (notify_ctx->addr->sa_family & 0xFF);
+	request.in.rgCallbackAddress[1] = (notify_ctx->addr->sa_family & 0xFF00) >> 8;
+	memcpy(&request.in.rgCallbackAddress[2], notify_ctx->addr->sa_data, 14);
+	request.in.cbCallbackAddress = sizeof (struct sockaddr);
+
+	request.out.handle = &handle;
+	request.out.hNotification = &hNotification;
+
+	status = dcerpc_EcRRegisterPushNotification(emsmdb_ctx->rpc_connection, emsmdb_ctx->mem_ctx, &request);
+	retval = request.out.result;
+	if (!NT_STATUS_IS_OK(status) || retval) {
+		talloc_free(mem_ctx);
+		return status;
+	}
+
+	talloc_free(mem_ctx);
+
+	return status;
+}
+
+
+/**
+   \details Retrieves the EMSMDB context server information structure
+
+   \param session pointer to the MAPI session context
+
+   \return the server info structure on success, otherwise NULL
+ */
+_PUBLIC_ struct emsmdb_info *emsmdb_get_info(struct mapi_session *session)
+{
+	if (!global_mapi_ctx || !session->emsmdb->ctx) {
+		return NULL;
+	}
+
+	return &((struct emsmdb_context *)session->emsmdb->ctx)->info;
+}
+
+
+/**
+   \details Retrieves a property value from a DATA blob
+
+   \param mem_ctx pointer to the memory context
+   \param lp_ctx pointer to the loadparm context
+   \param offset pointer on pointer to the current offset
+   \param tag the property tag which value is to be retrieved
+   \param data pointer to the data
+
+   \return pointer on constant generic data on success, otherwise NULL
+ */
+const void *pull_emsmdb_property(TALLOC_CTX *mem_ctx,
+				 struct loadparm_context *lp_ctx,
+				 uint32_t *offset, 
+				 enum MAPITAGS tag, 
+				 DATA_BLOB *data)
+{
+	struct ndr_pull			*ndr;
+	const char			*pt_string8;
+	const char			*pt_unicode;
+	uint16_t			*pt_i2;
+	uint64_t			*pt_i8;
+	uint32_t			*pt_long;
+	uint8_t				*pt_boolean;
+	struct FILETIME			*pt_filetime;
+	struct GUID			*pt_clsid;
+	struct SBinary_short		pt_binary;
+	struct Binary_r			*sbin;
+	struct mapi_SLPSTRArray		pt_slpstr;
+	struct StringArray_r		*slpstr;
+	struct mapi_MV_LONG_STRUCT	pt_MVl;
+	struct LongArray_r		*MVl;
+	struct mapi_SBinaryArray	pt_MVbin;
+	struct BinaryArray_r		*MVbin;
+	uint32_t			i;
+
+	ndr = talloc_zero(mem_ctx, struct ndr_pull);
+	ndr->offset = *offset;
+	ndr->data = data->data;
+	ndr->data_size = data->length;
+	ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+	ndr->iconv_convenience = lp_iconv_convenience(lp_ctx);
+
+	switch(tag & 0xFFFF) {
+	case PT_I2:
+		pt_i2 = talloc_zero(mem_ctx, uint16_t);
+		ndr_pull_uint16(ndr, NDR_SCALARS, pt_i2);
+		*offset = ndr->offset;
+		talloc_free(ndr);
+		return (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;
+	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;
+	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;
+	case PT_UNICODE:
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+		ndr_pull_string(ndr, NDR_SCALARS, &pt_unicode);
+		*offset = ndr->offset;
+		talloc_free(ndr);
+		return (const void *) pt_unicode;
+	case PT_STRING8:
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM);
+		ndr_pull_string(ndr, NDR_SCALARS, &pt_string8);
+		*offset = ndr->offset;
+		talloc_free(ndr);
+		return (const void *) pt_string8;
+	case PT_SYSTIME:
+		pt_filetime = talloc_zero(mem_ctx, struct FILETIME);
+		ndr_pull_hyper(ndr, NDR_SCALARS, (uint64_t *) pt_filetime);
+		*offset = ndr->offset;
+		talloc_free(ndr);
+		return (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;
+	case 0xFB:
+	case PT_BINARY:
+		ndr_pull_SBinary_short(ndr, NDR_SCALARS, &pt_binary);
+		*offset = ndr->offset;
+		sbin = talloc_zero(mem_ctx, struct Binary_r);
+		sbin->cb = pt_binary.cb;
+		sbin->lpb = talloc_memdup(sbin, pt_binary.lpb, pt_binary.cb);
+		talloc_free(ndr);
+		return (void *) sbin;
+	case PT_MV_LONG:
+		ndr_pull_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, &pt_MVl);
+		*offset = ndr->offset;
+		MVl = talloc_zero(mem_ctx, struct LongArray_r);
+		MVl->cValues = pt_MVl.cValues;
+		MVl->lpl = talloc_array(mem_ctx, uint32_t, pt_MVl.cValues);
+		for (i = 0; i < MVl->cValues; i++) {
+			MVl->lpl[i] = pt_MVl.lpl[i];
+		}
+		talloc_free(ndr);
+		return (const void *) MVl;
+	case PT_MV_STRING8:
+		ndr_pull_mapi_SLPSTRArray(ndr, NDR_SCALARS, &pt_slpstr);
+		*offset = ndr->offset;
+		slpstr = talloc_zero(mem_ctx, struct StringArray_r);
+		slpstr->cValues = pt_slpstr.cValues;
+		slpstr->lppszA = talloc_array(mem_ctx, const char *, pt_slpstr.cValues);
+		for (i = 0; i < slpstr->cValues; i++) {
+			slpstr->lppszA[i] = talloc_strdup(mem_ctx, pt_slpstr.strings[i].lppszA);
+		}
+		talloc_free(ndr);
+		return (const void *) slpstr;
+	case PT_MV_BINARY:
+		ndr_pull_mapi_SBinaryArray(ndr, NDR_SCALARS, &pt_MVbin);
+		*offset = ndr->offset;
+		MVbin = talloc_zero(mem_ctx, struct BinaryArray_r);
+		MVbin->cValues = pt_MVbin.cValues;
+		MVbin->lpbin = talloc_array(mem_ctx, struct Binary_r, pt_MVbin.cValues);
+		for (i = 0; i < MVbin->cValues; i++) {
+			MVbin->lpbin[i].cb = pt_MVbin.bin[i].cb;
+			MVbin->lpbin[i].lpb = talloc_size(mem_ctx, MVbin->lpbin[i].cb);
+			memcpy(MVbin->lpbin[i].lpb, pt_MVbin.bin[i].lpb, MVbin->lpbin[i].cb);
+		}
+		talloc_free(ndr);
+		return (const void *) MVbin;
+	default:
+		return NULL;
+	}	
+}
+
+
+/**
+   \details Get a SPropValue array from a DATA blob
+
+   \param mem_ctx pointer to the memory context
+   \param lp_ctx pointer to the loadparm context
+   \param content pointer to the DATA blob content
+   \param tags pointer to a list of property tags to lookup
+   \param propvals pointer on pointer to the returned SPropValues
+   \param cn_propvals pointer to the number of propvals
+   \param flag describes the type data
+
+   \return MAPI_E_SUCCESS on success
+ */
+enum MAPISTATUS emsmdb_get_SPropValue(TALLOC_CTX *mem_ctx,
+				      struct loadparm_context *lp_ctx,
+				      DATA_BLOB *content,
+				      struct SPropTagArray *tags,
+				      struct SPropValue **propvals, 
+				      uint32_t *cn_propvals,
+				      uint8_t flag)
+{
+	struct SPropValue	*p_propval;
+	uint32_t		i_propval;
+	uint32_t		i_tag;
+	uint32_t		cn_tags;
+	uint32_t		offset = 0;
+	const void		*data;
+
+	i_propval = 0;
+	cn_tags = tags->cValues;
+	*cn_propvals = 0;
+	*propvals = talloc_array(mem_ctx, struct SPropValue, cn_tags + 1);
+
+	for (i_tag = 0; i_tag < cn_tags; i_tag++) {
+		if (flag) { 
+			if (((uint8_t)(*(content->data + offset))) == PT_ERROR) {
+				tags->aulPropTag[i_tag] &= 0xFFFF0000;
+				tags->aulPropTag[i_tag] |= PT_ERROR;
+			}
+			offset += sizeof (uint8_t);
+		}
+
+		data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, tags->aulPropTag[i_tag], content);
+		if (data) {
+			p_propval = &((*propvals)[i_propval]);
+			p_propval->ulPropTag = tags->aulPropTag[i_tag];
+			p_propval->dwAlignPad = 0x0;
+			set_SPropValue(p_propval, data);
+			i_propval++;
+		}
+	}
+
+	(*propvals)[i_propval].ulPropTag = 0x0;
+	*cn_propvals = i_propval;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get a SRowSet from a DATA blob
+
+   \param mem_ctx pointer on the memory context
+   \param lp_ctx pointer on the loadparm context
+   \param rowset pointer on the returned SRowSe
+   \param proptags pointer on a list of property tags to lookup
+   \param content pointer on the DATA blob content
+
+   \return MAPI_E_SUCCESS on success
+
+   \note TODO: this doesn't yet handle the TypedPropertyValue and
+   FlaggedPropertyValueWithTypeSpecified variants
+ */
+_PUBLIC_ void emsmdb_get_SRowSet(TALLOC_CTX *mem_ctx,
+				 struct loadparm_context *lp_ctx,
+				 struct SRowSet *rowset, 
+				 struct SPropTagArray *proptags, 
+				 DATA_BLOB *content)
+{
+	struct SRow		*rows;
+	struct SPropValue	*lpProps;
+	uint32_t		idx;
+	uint32_t		prop;
+	uint32_t		offset = 0;
+	const void		*data;
+	uint32_t		row_count;
+	bool			is_FlaggedPropertyRow = false;
+	bool			havePropertyValue;
+	uint8_t			flag;
+
+	/* caller allocated */
+	rows = rowset->aRow;
+	row_count = rowset->cRows;
+
+	for (idx = 0; idx < row_count; idx++) {
+		if (0x1 == *(content->data + offset)) {
+			is_FlaggedPropertyRow = true;
+		} else {
+			is_FlaggedPropertyRow = false;
+		}
+		++offset;
+
+		lpProps = talloc_array(mem_ctx, struct SPropValue, proptags->cValues);
+		for (prop = 0; prop < proptags->cValues; prop++) {
+			havePropertyValue = true;
+			lpProps[prop].ulPropTag = proptags->aulPropTag[prop];
+			if (is_FlaggedPropertyRow) {
+				flag = (uint8_t)(*(content->data + offset));
+				++offset; /* advance offset for the flag */
+				switch (flag) {
+				case 0x0:
+					/* Property Value is valid */
+					break;
+				case 0x1:
+					/* Property Value is not present */
+					havePropertyValue = false;
+					break;
+				case PT_ERROR:
+					lpProps[prop].ulPropTag = proptags->aulPropTag[prop];
+					lpProps[prop].ulPropTag &= 0xFFFF0000;
+					lpProps[prop].ulPropTag |= PT_ERROR;
+					break;
+				default:
+					/* unknown FlaggedPropertyValue flag */
+					break;
+
+				}
+			}
+			if (havePropertyValue) {
+				lpProps[prop].dwAlignPad = 0x0;
+				data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, lpProps[prop].ulPropTag, content);
+				set_SPropValue(&lpProps[prop], data);
+			}
+		}
+
+		rows[idx].ulAdrEntryPad = 0;
+		rows[idx].cValues = proptags->cValues;
+		rows[idx].lpProps = lpProps;
+	}
+}
+
+
+/**
+   \details Get a SRow from a DATA blob
+
+   \param mem_ctx pointer on the memory context
+   \param lp_ctx pointer on the loadparm context
+   \param aRow pointer on the returned SRow
+   \param proptags pointer on a list of property tags to lookup
+   \param propcount number of SPropValue entries in aRow
+   \param content pointer on the DATA blob content
+   \param flag the type data
+   \param align alignment pad
+
+   \return MAPI_E_SUCCESS on success
+
+   \note TODO: We shouldn't have any alignment pad here
+ */
+void emsmdb_get_SRow(TALLOC_CTX *mem_ctx,
+		     struct loadparm_context *lp_ctx,
+		     struct SRow *aRow, 
+		     struct SPropTagArray *proptags, 
+		     uint16_t propcount, 
+		     DATA_BLOB *content, 
+		     uint8_t flag, 
+		     uint8_t align)
+{
+	uint32_t		i;
+	uint32_t		offset = 0;
+	uint32_t		aulPropTag = 0;
+	const void		*data;
+
+	aRow->cValues = propcount;
+	aRow->lpProps = talloc_array(mem_ctx, struct SPropValue, propcount);
+
+	for (i = 0; i < propcount; i++) {
+		aulPropTag = proptags->aulPropTag[i];
+		if (flag) {
+			if (((uint8_t)(*(content->data + offset))) == PT_ERROR) {
+				aulPropTag &= 0xFFFF0000;
+				aulPropTag |= 0xA;			
+			}
+			offset += align;
+		} 
+
+		data = pull_emsmdb_property(mem_ctx, lp_ctx, &offset, aulPropTag, content);
+		aRow->lpProps[i].ulPropTag = aulPropTag;
+		aRow->lpProps[i].dwAlignPad = 0x0;
+		set_SPropValue(&(aRow->lpProps[i]), data);
+	}
+	if (align) {
+		offset += align;
+	}
+}

Added: trunk/openchange/libmapi/emsmdb.h
===================================================================
--- trunk/openchange/libmapi/emsmdb.h	                        (rev 0)
+++ trunk/openchange/libmapi/emsmdb.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,52 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij 2005.
+   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 __EMSMDB_H__
+#define	__EMSMDB_H__
+
+struct emsmdb_info {
+	char			*szDisplayName;
+	char			*szDNPrefix;
+	uint32_t		pcmsPollsMax;
+	uint32_t		pcRetry;
+	uint32_t		pcmsRetryDelay;
+	uint32_t		picxr;
+	uint16_t		rgwServerVersion[3];
+};
+
+struct emsmdb_context {
+	struct dcerpc_pipe     	*rpc_connection;
+	struct policy_handle   	handle;
+	struct nspi_context    	*nspi;
+	struct cli_credentials	*cred;
+	TALLOC_CTX	       	*mem_ctx;
+	struct EcDoRpc_MAPI_REQ	**cache_requests;
+	uint32_t	       	cache_size;
+	uint8_t			cache_count;
+	uint16_t	       	prop_count;
+	enum MAPITAGS	       	*properties;
+	uint16_t     	       	max_data;
+	bool		       	setup;
+	struct emsmdb_info	info;
+};
+
+#define	MAILBOX_PATH	"/o=%s/ou=%s/cn=Recipients/cn=%s"
+
+#endif /* __EMSMDB_H__ */

Added: trunk/openchange/libmapi/freebusy.c
===================================================================
--- trunk/openchange/libmapi/freebusy.c	                        (rev 0)
+++ trunk/openchange/libmapi/freebusy.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,366 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <ctype.h>
+#include <time.h>
+
+/**
+   \file freebusy.c
+
+   \brief Convenient API to access FreeBusy
+ */
+
+
+/**
+   \details Retrieve FreeBusy data associated with the specified
+   recipient
+
+   \param obj_store pointer to the public folder MAPI object
+   \param recipient name of the recipient to fetch freebusy data
+   \param pSRow pointer to the returned properties
+
+   \note The function returns a SRow structure with the following
+   property tags:
+   -# PR_NORMALIZED_SUBJECT
+   -# PR_FREEBUSY_LAST_MODIFIED
+   -# PR_FREEBUSY_START_RANGE
+   -# PR_FREEBUSY_END_RANGE
+   -# PR_FREEBUSY_ALL_MONTHS
+   -# PR_FREEBUSY_ALL_EVENTS
+   -# PR_FREEBUSY_TENTATIVE_MONTHS
+   -# PR_FREEBUSY_TENTATIVE_EVENTS
+   -# PR_FREEBUSY_BUSY_MONTHS
+   -# PR_FREEBUSY_BUSY_EVENTS
+   -# PR_FREEBUSY_OOF_MONTHS
+   -# PR_FREEBUSY_OOF_EVENTS
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS GetUserFreeBusyData(mapi_object_t *obj_store, 
+					     const char *recipient,
+					     struct SRow *pSRow)
+{
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_session		*session;
+	mapi_id_t			id_freebusy;
+	mapi_object_t			obj_freebusy;
+	mapi_object_t			obj_exfreebusy;
+	mapi_object_t			obj_message;
+	mapi_object_t			obj_htable;
+	mapi_object_t			obj_ctable;
+	struct SRowSet			*pRowSet;
+	struct SRowSet			SRowSet;
+	struct SPropValue		*lpProps;
+	struct mapi_SRestriction	res;
+	struct SSortOrderSet		criteria;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	char				*message_name;
+	char				*folder_name;
+	const char			*email = NULL;
+	char				*o = NULL;
+	char				*ou = NULL;
+	char				*username;
+	const uint64_t			*fid;
+	const uint64_t			*mid;
+	uint32_t			i;
+	uint32_t			count;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!pSRow, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
+
+	mem_ctx = (TALLOC_CTX *) session;
+
+	/* Step 0. Retrieve the user Email Address and build FreeBusy strings */
+	pRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	retval = GetABRecipientInfo(session, recipient, NULL, &pRowSet);
+	OPENCHANGE_RETVAL_IF(retval, retval, pRowSet);
+
+	email = get_SPropValue_SRowSet_data(pRowSet, PR_EMAIL_ADDRESS_UNICODE);
+	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=");
+	
+	/* toupper username */
+	for (i = 0; username[i]; i++) {
+		username[i] = toupper((unsigned char)username[i]);
+	}
+
+	message_name = talloc_asprintf(mem_ctx, FREEBUSY_USER, username);
+	folder_name = talloc_asprintf(mem_ctx, FREEBUSY_FOLDER, o, ou);
+
+	MAPIFreeBuffer(username);
+	MAPIFreeBuffer(o);
+	MAPIFreeBuffer(ou);
+	MAPIFreeBuffer(pRowSet);
+
+	/* Step 1. Open the FreeBusy root folder */
+	retval = GetDefaultPublicFolder(obj_store, &id_freebusy, olFolderPublicFreeBusyRoot);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	mapi_object_init(&obj_freebusy);
+	retval = OpenFolder(obj_store, id_freebusy, &obj_freebusy);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 2. Open the hierarchy table */
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_freebusy, &obj_htable, 0, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 3. Customize Hierarchy Table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
+					  PR_FID,
+					  PR_DISPLAY_NAME);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 4. Find FreeBusy folder row */
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RELOP_EQ;
+	res.res.resProperty.ulPropTag = PR_DISPLAY_NAME;
+	res.res.resProperty.lpProp.ulPropTag = PR_DISPLAY_NAME;
+	res.res.resProperty.lpProp.value.lpszA = folder_name;
+	retval = FindRow(&obj_htable, &res, 0, 0, &SRowSet);
+	MAPIFreeBuffer(folder_name);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 5. Open the folder */
+	fid = (const uint64_t *) get_SPropValue_SRowSet_data(&SRowSet, PR_FID);
+	if (!fid || *fid == MAPI_E_NOT_FOUND) return MAPI_E_NOT_FOUND;
+
+	mapi_object_init(&obj_exfreebusy);
+	retval = OpenFolder(&obj_freebusy, *fid, &obj_exfreebusy);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 6. Open the contents table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_exfreebusy, &obj_ctable, 0, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 7. Customize Contents Table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_ADDRBOOK_MID,
+					  PR_INSTANCE_NUM,
+					  PR_NORMALIZED_SUBJECT);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 8. Sort the table */
+	memset(&criteria, 0x0, sizeof (struct SSortOrderSet));
+	criteria.cSorts = 1;
+	criteria.aSort = talloc_array(mem_ctx, struct SSortOrder, criteria.cSorts);
+	criteria.aSort[0].ulPropTag = PR_NORMALIZED_SUBJECT;
+	criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND;
+	retval = SortTable(&obj_ctable, &criteria);
+	MAPIFreeBuffer(criteria.aSort);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 9. Find the user FreeBusy message row */
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RELOP_EQ;
+	res.res.resProperty.ulPropTag = PR_NORMALIZED_SUBJECT;
+	res.res.resProperty.lpProp.ulPropTag = PR_NORMALIZED_SUBJECT;
+	res.res.resProperty.lpProp.value.lpszA = message_name;
+	retval = FindRow(&obj_ctable, &res, 0, 0, &SRowSet);
+	MAPIFreeBuffer(message_name);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 10. Open the message */
+	fid = (const uint64_t *)get_SPropValue_SRowSet_data(&SRowSet, PR_FID);	
+	mid = (const uint64_t *)get_SPropValue_SRowSet_data(&SRowSet, PR_MID);
+	OPENCHANGE_RETVAL_IF(!fid || *fid == MAPI_E_NOT_FOUND, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!mid || *mid == MAPI_E_NOT_FOUND, MAPI_E_NOT_FOUND, NULL);
+
+	mapi_object_init(&obj_message);
+	retval = OpenMessage(obj_store, *fid, *mid, &obj_message, 0x0);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	/* Step 11. Get FreeBusy properties */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xc, 
+					  PR_NORMALIZED_SUBJECT,
+					  PR_FREEBUSY_LAST_MODIFIED,
+					  PR_FREEBUSY_START_RANGE,
+					  PR_FREEBUSY_END_RANGE,
+					  PR_FREEBUSY_ALL_MONTHS,
+					  PR_FREEBUSY_ALL_EVENTS,
+					  PR_FREEBUSY_TENTATIVE_MONTHS,
+					  PR_FREEBUSY_TENTATIVE_EVENTS,
+					  PR_FREEBUSY_BUSY_MONTHS,
+					  PR_FREEBUSY_BUSY_EVENTS,
+					  PR_FREEBUSY_OOF_MONTHS,
+					  PR_FREEBUSY_OOF_EVENTS);
+	retval = GetProps(&obj_message, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	pSRow->cValues = count;
+	pSRow->lpProps = lpProps;
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_exfreebusy);
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&obj_freebusy);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Check if a date conflicts with existing FreeBusy Busy/Out
+   Of Office events
+
+   \param obj_store pointer to the public folder MAPI object
+   \param date pointer to the date to check
+   \param conflict pointer to the returned boolean value
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS IsFreeBusyConflict(mapi_object_t *obj_store,
+					    struct FILETIME *date,
+					    bool *conflict)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_session		*session;
+	struct SRow			aRow;
+	const struct LongArray_r	*all_months;
+	const struct BinaryArray_r	*all_events;
+	struct Binary_r			bin;
+	const uint32_t			*publish_start;
+	NTTIME				nttime;
+	time_t				time;
+	struct tm			*tm;
+	uint32_t			fbusytime;
+	uint32_t			fmonth;
+	uint32_t			month;
+	int				year;
+	uint32_t			idx;
+	uint32_t			i;
+	bool				found = false;
+	uint32_t			start;
+	uint32_t			end;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!date, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!conflict, MAPI_E_INVALID_PARAMETER, NULL);
+
+	session = mapi_object_get_session(obj_store);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_SESSION_LIMIT, NULL);
+
+	*conflict = false;
+
+	/* Step 1. Retrieve the freebusy data for the user */
+	retval = GetUserFreeBusyData(obj_store, session->profile->username, &aRow);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	publish_start = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_START_RANGE);
+	all_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_ALL_MONTHS);
+	all_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_ALL_EVENTS);
+
+	if (!all_months || (*(const uint32_t *)all_months) == MAPI_E_NOT_FOUND ||
+	    !all_events || (*(const uint32_t *)all_events) == MAPI_E_NOT_FOUND) {
+		return MAPI_E_SUCCESS;
+	}
+
+	/* Step 2. Convert the input date to freebusy */
+	nttime = ((uint64_t) date->dwHighDateTime << 32);
+	nttime |= (uint64_t) date->dwLowDateTime;
+	time = nt_time_to_unix(nttime);
+	tm = localtime(&time);
+
+	fmonth = tm->tm_mon + 1;
+	fbusytime = ((tm->tm_mday - 1) * 60 * 24) + (tm->tm_hour * 60);
+
+	/* Step 3. Check if the years matches */
+	year = GetFreeBusyYear(publish_start);
+
+	if (year != (tm->tm_year + 1900)) {
+		return MAPI_E_SUCCESS;
+	}
+
+	/* Step 4. Check if we have already registered events for the month */
+	
+	for (idx = 0; idx < all_months->cValues; idx++) {
+		month = all_months->lpl[idx] - (year * 16);
+		if (month == fmonth) {
+			found = true;
+			break;
+		}
+	}
+	if (found == false) return MAPI_E_SUCCESS;
+
+	/* Step 5. Check if one this months events conflicts with the date */
+	bin = all_events->lpbin[idx];
+	if (bin.cb % 4) {
+		return MAPI_E_INVALID_PARAMETER;
+	}
+
+	for (i = 0; i < bin.cb; i += 4) {
+		start = (bin.lpb[i + 1] << 8) | bin.lpb[i];
+		end = (bin.lpb[i + 3] << 8) | bin.lpb[i + 2];
+		if ((fbusytime >= start) && (fbusytime <= end)) {
+			*conflict = true;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Return the year associated with the FreeBusy start range
+
+   \param publish_start pointer to the publish start integer
+
+   \return a valid year on success, otherwise 0
+ */
+_PUBLIC_ int GetFreeBusyYear(const uint32_t *publish_start)
+{
+	struct tm	*tm;
+	uint32_t	year;
+	time_t		time;
+	NTTIME		nttime;
+
+	if (!publish_start) return 0;
+
+	nttime = *publish_start;
+	nttime *= 60;
+	nttime *= 10000000;
+	time = nt_time_to_unix(nttime);
+	tm = localtime(&time);
+	year = (tm->tm_year + 1900);
+
+	return year;
+}

Added: trunk/openchange/libmapi/libmapi.h
===================================================================
--- trunk/openchange/libmapi/libmapi.h	                        (rev 0)
+++ trunk/openchange/libmapi/libmapi.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,75 @@
+/*
+   OpenChange MAPI implementation.
+   libmapi public header file
+
+   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/>.
+ */
+
+#ifndef __LIBMAPI_H__
+#define __LIBMAPI_H__
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
+/* Samba4 includes */
+#include <talloc.h>
+#include <dcerpc.h>
+#include <util/debug.h>
+#include <tevent.h>
+#include <param.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>
+#include <libmapi/mapi_ctx.h>
+#include <libmapi/mapi_provider.h>
+#include <libmapi/mapi_object.h>
+#include <libmapi/mapi_id_array.h>
+#include <libmapi/mapi_notification.h>
+#include <libmapi/mapi_profile.h>
+#include <libmapi/mapi_nameid.h>
+#include <libmapi/mapidefs.h>
+#include <libmapi/mapicode.h>
+#include <libmapi/socket/netif.h>
+#include <libmapi/proto.h>
+
+extern struct mapi_ctx *global_mapi_ctx;
+
+#endif /* __LIBMAPI_H__ */

Added: trunk/openchange/libmapi/lzfu.c
===================================================================
--- trunk/openchange/libmapi/lzfu.c	                        (rev 0)
+++ trunk/openchange/libmapi/lzfu.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,237 @@
+/*
+   OpenChange MAPI implementation.
+
+   This work is based on libpst-0.5.2, and the author(s) of
+   that code will also hold appropriate copyrights.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+
+/**
+   \file lzfu.c
+   
+   \brief Compressed RTF related functions
+*/
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+#define LE32_CPU(x)		    \
+  x = ((((x) & 0xff000000) >> 24) | \
+       (((x) & 0x00ff0000) >> 8 ) | \
+       (((x) & 0x0000ff00) << 8 ) | \
+       (((x) & 0x000000ff) << 24));
+#define LE16_CPU(x)	       \
+  x = ((((x) & 0xff00) >> 8) | \
+       (((x) & 0x00ff) << 8));
+#elif BYTE_ORDER == LITTLE_ENDIAN
+#define	LE32_CPU(x) {}
+#define	LE16_CPU(x) {}
+#else
+#error Byte order not supported
+#endif /* BYTE_ORDER */
+
+#define	LZFU_COMPRESSED		0x75465a4c
+#define	LZFU_UNCOMPRESSED	0x414c454d
+
+/* Initial directory */
+#define LZFU_INITDICT					\
+  "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}"	\
+  "{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscrip"	\
+  "t \\fdecor MS Sans SerifSymbolArialTimes Ne"		\
+  "w RomanCourier{\\colortbl\\red0\\green0\\blue0"	\
+  "\r\n\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab"	\
+  "\\tx"
+
+/* initial length of dictionary */
+#define LZFU_INITLENGTH		207
+
+#define	LZFU_DICTLENGTH		0x1000
+#define	LZFU_HEADERLENGTH	0x10
+
+/* header for compressed rtf */
+typedef struct _lzfuheader {
+	uint32_t	cbSize;
+	uint32_t	cbRawSize;
+	uint32_t	dwMagic;
+	uint32_t	dwCRC;
+} lzfuheader;
+
+
+/**
+   \details creates a DATA_BLOB in uncompressed Rich Text Format (RTF)
+   from the compressed format used in the PR_RTF_COMPRESSED property
+   opened in the stream.
+
+   \param obj_stream stream object with RTF stream content
+   \param rtf the output blob with uncompressed content
+
+   \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: obj_stream is not a valid pointer
+   - MAPI_E_CORRUPT_DATA: a problem was encountered while
+     decompressing the RTF compressed data
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+   transaction
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code.
+ 
+   \note rtf->data needs to be freed with MAPIFreeBuffer
+
+   \sa OpenStream
+*/
+_PUBLIC_ enum MAPISTATUS WrapCompressedRTFStream(mapi_object_t *obj_stream, 
+						 DATA_BLOB *rtf)
+{
+	enum MAPISTATUS	retval;
+	TALLOC_CTX	*mem_ctx;
+	uint32_t	in_size;
+	uint8_t		*rtfcomp;
+	uint16_t	read_size;
+	unsigned char	buf[0x1000];
+
+	/* sanity check and init */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+	mem_ctx = global_mapi_ctx->mem_ctx;
+
+	/* Read the stream pointed by obj_stream */
+	read_size = 0;
+	in_size = 0;
+	rtfcomp = talloc_zero(mem_ctx, uint8_t);
+	do {
+		retval = ReadStream(obj_stream, buf, 0x1000, &read_size);
+		OPENCHANGE_RETVAL_IF(retval, GetLastError(), rtf->data);
+		if (read_size) {
+			rtfcomp = talloc_realloc(mem_ctx, rtfcomp, uint8_t, 
+						   in_size + read_size);
+			memcpy(&(rtfcomp[in_size]), buf, read_size);
+			in_size += read_size;
+		}
+	} while (read_size);
+
+	return uncompress_rtf(mem_ctx, rtfcomp, in_size, rtf);
+}
+
+_PUBLIC_ enum MAPISTATUS uncompress_rtf(TALLOC_CTX *mem_ctx, 
+					 uint8_t *rtfcomp, uint32_t in_size,
+					 DATA_BLOB *rtf)
+{
+	lzfuheader	lzfuhdr;
+	uint8_t		dict[4096];
+	uint32_t	out_size = 0;
+	uint32_t	in_pos = 16;
+	uint32_t	out_pos = 0;
+	uint32_t	dict_writeoffset = LZFU_INITLENGTH;
+	uint8_t		bitmask_pos;
+
+	if (in_size < sizeof(lzfuhdr)+1) {
+		OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL);
+	}
+
+	memcpy(dict, LZFU_INITDICT, LZFU_INITLENGTH);
+
+	memcpy(&lzfuhdr, rtfcomp, sizeof(lzfuhdr));
+	LE32_CPU(lzfuhdr.cbSize);   
+	LE32_CPU(lzfuhdr.cbRawSize);
+	LE32_CPU(lzfuhdr.dwMagic);  
+	LE32_CPU(lzfuhdr.dwCRC);
+
+#if 0
+	printf("lzfuhdr.cbSize = %u\n", lzfuhdr.cbSize);
+	printf("lzfuhdr.cbRawSize = %u\n", lzfuhdr.cbRawSize);
+	printf("lzfuhdr.dwMagic = 0x%x\n", lzfuhdr.dwMagic);
+	printf("lzfuhdr.dwCRC = 0x%x\n", lzfuhdr.dwCRC);
+#endif
+
+	if (lzfuhdr.cbSize != in_size - 4) {
+		printf("in_size mismatch:%u\n", in_size);
+		OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL);
+	}
+
+	if ((lzfuhdr.dwMagic != LZFU_COMPRESSED) && (lzfuhdr.dwMagic != LZFU_UNCOMPRESSED)) {
+		printf("bad magic: 0x%x\n", lzfuhdr.dwMagic);
+		OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, NULL);
+	}
+
+	if (lzfuhdr.dwMagic == LZFU_UNCOMPRESSED) {
+		// TODO: handle uncompressed case
+	}
+
+	out_size = lzfuhdr.cbRawSize + LZFU_HEADERLENGTH + 4;
+	rtf->data = talloc_size(mem_ctx, out_size);
+
+	while ((in_pos + 1) < in_size) {
+		uint8_t control;
+		control = rtfcomp[in_pos];
+		++ in_pos;
+		// printf("control: 0x%x\n", control);
+
+		for(bitmask_pos = 0; bitmask_pos < 8; ++bitmask_pos) {
+			if (in_pos > in_size) {
+				break;
+			}
+			if (control & ( 1 << bitmask_pos)) {
+				// it is a dictionary reference
+				uint8_t dictreflength;
+				uint16_t dictrefoffset;
+				int i;
+				dictrefoffset= (rtfcomp[in_pos] << 8) + rtfcomp[in_pos + 1];
+				in_pos += 2; /* for the two bytes we just consumed */
+				dictreflength = dictrefoffset & 0x000F; /* low 4 bits */
+				dictreflength += 2; /* stored as two less than actual length */
+				dictrefoffset &= 0xFFF0; /* high twelve bits */
+				dictrefoffset >>= 4;
+				if (dictrefoffset == dict_writeoffset) {
+					rtf->length = out_pos;
+					OPENCHANGE_RETVAL_ERR(MAPI_E_SUCCESS, NULL);
+				}
+				for (i = 0; i < dictreflength; ++i) {
+					if (out_pos > out_size ) {
+						printf(" overrun on out_pos: %u > %u\n", out_pos, out_size);
+						printf(" overrun data: %s\n", rtf->data);
+						OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, rtf->data);
+					}
+					char c = dict[(dictrefoffset + i) % LZFU_DICTLENGTH];
+					rtf->data[out_pos] = c;
+					dict[dict_writeoffset] = c;
+					dict_writeoffset = (dict_writeoffset + 1) % LZFU_DICTLENGTH;
+					++ out_pos;
+				}
+			} else {
+				// its a literal
+				if ( (out_pos > out_size) || (in_pos > in_size) ) {
+					OPENCHANGE_RETVAL_ERR(MAPI_E_CORRUPT_DATA, rtf->data);
+				}
+				char c = rtfcomp[in_pos];
+				++ in_pos;
+				rtf->data[out_pos] = c;
+				dict[dict_writeoffset] = c;
+				dict_writeoffset = (dict_writeoffset + 1) % LZFU_DICTLENGTH;
+				++ out_pos;
+			}
+		}
+	}
+
+	rtf->length = lzfuhdr.cbRawSize;
+
+	OPENCHANGE_RETVAL_ERR(MAPI_E_SUCCESS, NULL);
+
+}

Added: trunk/openchange/libmapi/mapi_ctx.h
===================================================================
--- trunk/openchange/libmapi/mapi_ctx.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_ctx.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,44 @@
+/*
+   OpenChange MAPI implementation.
+   Status codes returned by MAPI
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#ifndef	_MAPI_CTX_H
+#define	_MAPI_CTX_H
+
+#include <talloc.h>
+
+/**
+ * mapi global context
+ */
+
+struct ldb_context;
+struct mapi_session;
+
+typedef struct mapi_ctx
+{
+  TALLOC_CTX		*mem_ctx;
+  struct ldb_context	*ldb_ctx;
+  struct mapi_session	*session;
+  bool			dumpdata;
+  struct loadparm_context *lp_ctx;
+} mapi_ctx_t;
+
+
+#endif	/* ! _MAPI_CTX_H */

Added: trunk/openchange/libmapi/mapi_id_array.c
===================================================================
--- trunk/openchange/libmapi/mapi_id_array.c	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_id_array.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,297 @@
+/*
+   OpenChange MAPI implementation.
+
+   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 <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+
+/**
+   \file mapi_id_array.c
+
+   \brief mapi_id_array support functions
+*/
+
+
+/**
+   \details Initialize a mapi_id_array structure
+
+   \param id pointer to a mapi_id_array structure
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_release
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_init(mapi_id_array_t *id)
+{
+	TALLOC_CTX	*mem_ctx;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = global_mapi_ctx->mem_ctx;
+
+	id->count = 0;
+	id->lpContainerList = talloc_zero((TALLOC_CTX *)mem_ctx, mapi_container_list_t);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Uninitialize a mapi_id_array structure
+
+   \param id pointer to a mapi_id_array structure
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_init
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_release(mapi_id_array_t *id)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL);
+
+	id->count = 0;
+	talloc_free(id->lpContainerList);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the ContainerList and store it within a uint64_t
+   array.
+
+   \param mem_ctx allocated talloc pointer
+   \param id pointer to a mapi_id_array structure
+   \param ContainerList pointer on a pointer of uint64_t values
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa GetSearchCriteria
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_get(TALLOC_CTX *mem_ctx,
+					   mapi_id_array_t *id, 
+					   mapi_id_t **ContainerList)
+{
+	mapi_container_list_t	*element;
+	uint32_t		i = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ContainerList, MAPI_E_INVALID_PARAMETER, NULL);
+
+	*ContainerList = talloc_array(mem_ctx, uint64_t, id->count + 1);
+
+	element = id->lpContainerList;
+	while (element) {
+		ContainerList[0][i] = element->id;
+		i++;
+		element = element->next;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Add a container ID to the list given its mapi_object_t
+
+   \param id pointer to a mapi_id_array structure
+   \param obj pointer on the mapi object we retrieve the container ID
+   from
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_add_id
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_add_obj(mapi_id_array_t *id, 
+					       mapi_object_t *obj)
+{
+	mapi_container_list_t	*element;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+	element = talloc_zero((TALLOC_CTX *)id->lpContainerList, mapi_container_list_t);
+	element->id = mapi_object_get_id(obj);
+	DLIST_ADD(id->lpContainerList, element);
+	
+	id->count++;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Add a container ID to the list given its container ID
+
+   \param id pointer to a mapi_id_array structure
+   \param fid the container ID
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_add_obj
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_add_id(mapi_id_array_t *id, mapi_id_t fid)
+{
+	mapi_container_list_t	*element;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!fid, MAPI_E_INVALID_PARAMETER, NULL);
+
+	element = talloc_zero((TALLOC_CTX *)id->lpContainerList, mapi_container_list_t);
+	element->id = fid;
+	DLIST_ADD(id->lpContainerList, element);
+	
+	id->count++;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Delete a container ID from the list given its container ID
+
+   \param id pointer to a mapi_id_array structure
+   \param fid the container ID
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_add_id
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_del_id(mapi_id_array_t *id, mapi_id_t fid)
+{
+	mapi_container_list_t	*element;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->count, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL);
+
+	element = id->lpContainerList;
+
+	while (element) {
+		if (element->id == fid) {
+			DLIST_REMOVE(id->lpContainerList, element);
+			return MAPI_E_SUCCESS;
+		}
+		element = element->next;
+	}
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Delete a container ID from the list given its mapi_object_t
+
+   \param id pointer to a mapi_id_array structure
+   \param obj pointer on the mapi object we retrieve the container ID
+   from
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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: The mapi_id_array_t is uninitialized
+   - MAPI_E_CALL_FAILED: A network problem was encountered during the
+     transaction
+
+   \sa mapi_id_array_add_id
+ */
+_PUBLIC_ enum MAPISTATUS mapi_id_array_del_obj(mapi_id_array_t *id, mapi_object_t *obj)
+{
+	mapi_container_list_t	*element;
+	mapi_id_t		fid;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!id->count, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!id->lpContainerList, MAPI_E_NOT_INITIALIZED, NULL);
+
+	fid = mapi_object_get_id(obj);
+	OPENCHANGE_RETVAL_IF(!fid, MAPI_E_NOT_INITIALIZED, NULL);
+
+	element = id->lpContainerList;
+
+	while (element) {
+		if (element->id == fid) {
+			DLIST_REMOVE(id->lpContainerList, element);
+			return MAPI_E_SUCCESS;
+		}
+		element = element->next;
+	}
+	return MAPI_E_NOT_FOUND;
+}

Added: trunk/openchange/libmapi/mapi_id_array.h
===================================================================
--- trunk/openchange/libmapi/mapi_id_array.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_id_array.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,34 @@
+/*
+   OpenChange MAPI implementation.
+
+   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	__MAPI_ID_ARRAY_H
+#define	__MAPI_ID_ARRAY_H
+
+typedef struct mapi_container_list {
+	struct mapi_container_list	*prev;
+	struct mapi_container_list	*next;
+	mapi_id_t			id;
+} mapi_container_list_t;
+
+typedef struct mapi_id_array {
+	uint16_t       		count;
+	mapi_container_list_t	*lpContainerList;
+} mapi_id_array_t;
+
+#endif /* __MAPI_ID_ARRAY_H */

Added: trunk/openchange/libmapi/mapi_nameid.c
===================================================================
--- trunk/openchange/libmapi/mapi_nameid.c	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_nameid.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,873 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/mapi_nameid.h>
+#include <libmapi/mapi_nameid_private.h>
+#include <libmapi/proto_private.h>
+
+
+/**
+   \file mapi_nameid.c
+
+   \brief mapi_nameid convenience API
+*/
+
+
+/**
+   \details Create a new mapi_nameid structure
+
+   \param mem_ctx memory context to use for allocation
+
+   \returns a pointer to an allocated mapi_nameid structure on
+   success, otherwise NULL
+
+   \sa GetIDsFromNames
+*/
+_PUBLIC_ struct mapi_nameid *mapi_nameid_new(TALLOC_CTX *mem_ctx)
+{
+	struct mapi_nameid	*mapi_nameid = NULL;
+
+	/* Sanity check */
+	if (!mem_ctx) return NULL;
+
+	mapi_nameid = talloc_zero(mem_ctx, struct mapi_nameid);
+	if (!mapi_nameid) return NULL;
+
+	mapi_nameid->nameid = NULL;
+	mapi_nameid->entries = NULL;
+	mapi_nameid->count = 0;
+
+	return mapi_nameid;
+}
+
+
+/**
+   \details Add a mapi_nameid entry given its OOM and OLEGUID
+   (MNID_ID|MNID_STRING)
+
+   \param mapi_nameid the structure where results are stored
+   \param OOM the Outlook Object Model matching string
+   \param OLEGUID the property set this entry belongs to
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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 of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: the entry intended to be added was not found
+
+   \sa mapi_nameid_new
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_add(struct mapi_nameid *mapi_nameid,
+					     const char *OOM, 
+					     const char *OLEGUID)
+{
+	uint32_t		i;
+	uint16_t		count;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!OOM, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].OOM &&
+		    !strcmp(OOM, mapi_nameid_tags[i].OOM) && 
+		    !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) {
+			mapi_nameid->nameid = talloc_realloc(mapi_nameid, 
+							     mapi_nameid->nameid, struct MAPINAMEID,
+							     mapi_nameid->count + 1);
+			mapi_nameid->entries = talloc_realloc(mapi_nameid,
+							    mapi_nameid->entries, struct mapi_nameid_tags,
+							    mapi_nameid->count + 1);
+			count = mapi_nameid->count;
+
+			mapi_nameid->entries[count] = mapi_nameid_tags[i];
+
+			mapi_nameid->nameid[count].ulKind = mapi_nameid_tags[i].ulKind;
+			GUID_from_string(mapi_nameid_tags[i].OLEGUID,
+					 &(mapi_nameid->nameid[count].lpguid));
+			switch (mapi_nameid_tags[i].ulKind) {
+			case MNID_ID:
+				mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid;
+				break;
+			case MNID_STRING:
+				mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name;
+				mapi_nameid->nameid[count].kind.lpwstr.NameSize = strlen(mapi_nameid_tags[i].Name) * 2 + 2;
+				break;
+			}
+			mapi_nameid->count++;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Add a mapi_nameid entry given its lid and OLEGUID
+   (MNID_ID)
+
+   \param mapi_nameid the structure where results are stored
+   \param lid the light ID of the name property (used by MNID_ID named
+   props only)
+   \param OLEGUID the property set this entry belongs to
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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 of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: the entry intended to be added was not found
+
+   \sa mapi_nameid_new
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_add(struct mapi_nameid *mapi_nameid,
+					     uint16_t lid, const char *OLEGUID)
+{
+	uint32_t		i;
+	uint16_t		count;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if ((lid == mapi_nameid_tags[i].lid) &&
+		    !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) {
+			mapi_nameid->nameid = talloc_realloc(mapi_nameid, 
+							     mapi_nameid->nameid, struct MAPINAMEID,
+							     mapi_nameid->count + 1);
+			mapi_nameid->entries = talloc_realloc(mapi_nameid,
+							    mapi_nameid->entries, struct mapi_nameid_tags,
+							    mapi_nameid->count + 1);
+			count = mapi_nameid->count;
+
+			mapi_nameid->entries[count] = mapi_nameid_tags[i];
+
+			mapi_nameid->nameid[count].ulKind = mapi_nameid_tags[i].ulKind;
+			GUID_from_string(mapi_nameid_tags[i].OLEGUID,
+					 &(mapi_nameid->nameid[count].lpguid));
+			switch (mapi_nameid_tags[i].ulKind) {
+			case MNID_ID:
+				mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid;
+				break;
+			case MNID_STRING:
+				mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name;
+				mapi_nameid->nameid[count].kind.lpwstr.NameSize = strlen(mapi_nameid_tags[i].Name) * 2 + 2;
+				break;
+			}
+			mapi_nameid->count++;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_NOT_FOUND;	
+}
+
+
+/**
+   \details Add a mapi_nameid entry given its Name and OLEGUID
+   (MNID_STRING)
+
+   \param mapi_nameid the structure where results are stored
+   \param Name the property name (used by MNID_STRING named
+   props only)
+   \param OLEGUID the property set this entry belongs to
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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 of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: the entry intended to be added was not found
+
+   \sa mapi_nameid_new
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_string_add(struct mapi_nameid *mapi_nameid,
+						const char *Name,
+						const char *OLEGUID)
+{
+	uint32_t		i;
+	uint16_t		count;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].Name && 
+		    !strcmp(Name, mapi_nameid_tags[i].Name) &&
+		    !strcmp(OLEGUID, mapi_nameid_tags[i].OLEGUID)) {
+			mapi_nameid->nameid = talloc_realloc(mapi_nameid, 
+							     mapi_nameid->nameid, struct MAPINAMEID,
+							     mapi_nameid->count + 1);
+			mapi_nameid->entries = talloc_realloc(mapi_nameid,
+							    mapi_nameid->entries, struct mapi_nameid_tags,
+							    mapi_nameid->count + 1);
+			count = mapi_nameid->count;
+
+			mapi_nameid->entries[count] = mapi_nameid_tags[i];
+
+			mapi_nameid->nameid[count].ulKind = mapi_nameid_tags[i].ulKind;
+			GUID_from_string(mapi_nameid_tags[i].OLEGUID,
+					 &(mapi_nameid->nameid[count].lpguid));
+			switch (mapi_nameid_tags[i].ulKind) {
+			case MNID_ID:
+				mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid;
+				break;
+			case MNID_STRING:
+				mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name;
+				mapi_nameid->nameid[count].kind.lpwstr.NameSize = strlen(mapi_nameid_tags[i].Name) * 2 + 2;
+				break;
+			}
+			mapi_nameid->count++;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_NOT_FOUND;
+}
+
+/**
+  \details Register and add a custom MNID_ID named property given its
+  lid, proptype and OLEGUID.
+ 
+  \param mapi_nameid the structure where results are stored 
+  \param lid the light ID of the name property (used by MNID_ID named
+  props only)
+  \param propType the named property type
+  \param OLEGUID the property set this entry belongs to
+ 
+  \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ 
+  \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 of the parameter was no set properly
+
+  \sa mapi_nameid_new, mapi_nameid_lid_add
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_lid_add(struct mapi_nameid *mapi_nameid, 
+						    uint16_t lid, uint16_t propType, 
+						    const char *OLEGUID)
+{
+	uint16_t	count;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED,  NULL);
+	OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!propType, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_nameid->nameid = talloc_realloc(mapi_nameid,
+					     mapi_nameid->nameid, struct MAPINAMEID,
+					     mapi_nameid->count + 1);
+	mapi_nameid->entries = talloc_realloc(mapi_nameid, 
+					      mapi_nameid->entries, struct mapi_nameid_tags,
+					      mapi_nameid->count + 1);
+
+	count = mapi_nameid->count;
+	mapi_nameid->entries[count].lid = lid;
+	mapi_nameid->entries[count].propType = propType;
+	mapi_nameid->entries[count].ulKind = MNID_ID;
+	mapi_nameid->entries[count].OLEGUID = OLEGUID;
+
+	mapi_nameid->nameid[count].ulKind = MNID_ID;
+	GUID_from_string(OLEGUID, &(mapi_nameid->nameid[count].lpguid));
+	mapi_nameid->nameid[count].kind.lid = lid;
+
+	mapi_nameid->count++;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Register and add a custom MNID_STRING named property given
+   its string, proptype and OLEGUID.
+ 
+   \param mapi_nameid the structure where results are stored
+   \param Name the property name (used by MNID_STRING named props only)
+   \param propType the named property type
+   \param OLEGUID the property set this entry belongs to
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \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 of the parameter was not set properly.
+
+   \sa mapi_nameid_new, mapi_nameid_string_add
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_custom_string_add(struct mapi_nameid *mapi_nameid,
+						       const char *Name, uint16_t propType,
+						       const char *OLEGUID)
+{
+	uint16_t	count;
+
+	/* Sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!propType, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mapi_nameid->nameid = talloc_realloc(mapi_nameid,
+					     mapi_nameid->nameid, struct MAPINAMEID,
+					     mapi_nameid->count + 1);
+	mapi_nameid->entries = talloc_realloc(mapi_nameid,
+					      mapi_nameid->entries, struct mapi_nameid_tags,
+					      mapi_nameid->count + 1);
+	count = mapi_nameid->count;
+	mapi_nameid->entries[count].Name = Name;
+	mapi_nameid->entries[count].propType = propType;
+	mapi_nameid->entries[count].ulKind = MNID_STRING;
+	mapi_nameid->entries[count].OLEGUID = OLEGUID;
+
+	mapi_nameid->nameid[count].ulKind = MNID_STRING;
+	GUID_from_string(OLEGUID, &(mapi_nameid->nameid[count].lpguid));
+	mapi_nameid->nameid[count].kind.lpwstr.Name = Name;
+	mapi_nameid->nameid[count].kind.lpwstr.NameSize = strlen(Name) * 2 + 2;
+
+	mapi_nameid->count++;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Add a mapi_nameid entry given its canonical property tag
+
+   \param mapi_nameid the structure where results are stored
+   \param proptag the canonical property tag we are searching
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZE: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: the entry intended to be added was not found
+
+   \sa mapi_nameid_new
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_canonical_add(struct mapi_nameid *mapi_nameid,
+						   uint32_t proptag)
+{
+	uint32_t	i;
+	uint16_t	count;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!proptag, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].proptag == proptag) {
+			mapi_nameid->nameid = talloc_realloc(mapi_nameid,
+							     mapi_nameid->nameid, struct MAPINAMEID,
+							     mapi_nameid->count + 1);
+			mapi_nameid->entries = talloc_realloc(mapi_nameid,
+							      mapi_nameid->entries, struct mapi_nameid_tags,
+							      mapi_nameid->count + 1);
+			count = mapi_nameid->count;
+
+			mapi_nameid->entries[count] = mapi_nameid_tags[i];
+
+			mapi_nameid->nameid[count].ulKind = mapi_nameid_tags[i].ulKind;
+			GUID_from_string(mapi_nameid_tags[i].OLEGUID,
+					 &(mapi_nameid->nameid[count].lpguid));
+			switch (mapi_nameid_tags[i].ulKind) {
+			case MNID_ID:
+				mapi_nameid->nameid[count].kind.lid = mapi_nameid_tags[i].lid;
+				break;
+			case MNID_STRING:
+				mapi_nameid->nameid[count].kind.lpwstr.Name = mapi_nameid_tags[i].Name;
+				mapi_nameid->nameid[count].kind.lpwstr.NameSize = strlen(mapi_nameid_tags[i].Name) * 2 + 2;
+				break;
+			}
+			mapi_nameid->count++;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Search for a given OOM,OLEGUID couple and return the
+   associated propType.
+
+   \param OOM The Outlook Object Model
+   \param OLEGUID the named property GUID for this entry
+   \param propType pointer on returned named property type
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
+   - MAPI_E_NOT_FOUND: no named property found
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_OOM_lookup(const char *OOM, const char *OLEGUID,
+						uint16_t *propType)
+{
+	uint32_t	i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!OOM, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].OOM && 
+		    !strcmp(mapi_nameid_tags[i].OOM, OOM) &&
+		    !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) {
+			*propType = mapi_nameid_tags[i].propType;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	errno = MAPI_E_NOT_FOUND;
+	return -1;
+}
+
+
+/**
+   \details Search for a given lid,OLEGUID couple and return the
+   associated propType.
+
+   \param lid the named property light ID
+   \param OLEGUID the named property GUID for this entry
+   \param propType pointer on returned named property type
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
+   - MAPI_E_NOT_FOUND: no named property found
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_lid_lookup(uint16_t lid, const char *OLEGUID,
+						uint16_t *propType)
+{
+	uint32_t	i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!lid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].lid == lid &&
+		    !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) {
+			*propType = mapi_nameid_tags[i].propType;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	errno = MAPI_E_NOT_FOUND;
+	return -1;
+}
+
+
+/**
+   \details Search for a given Name,OLEGUID couple and return the
+   associated propType.
+
+   \param Name the named property name
+   \param OLEGUID the named property GUID for this entry
+   \param propType pointer on returned named property type
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
+
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameter was not set properly.
+   - MAPI_E_NOT_FOUND: no named property found
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_string_lookup(const char *Name, 
+						   const char *OLEGUID,
+						   uint16_t *propType)
+{
+	uint32_t	i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!Name, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!OLEGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; mapi_nameid_tags[i].OLEGUID; i++) {
+		if (mapi_nameid_tags[i].Name &&
+		    !strcmp(mapi_nameid_tags[i].Name, Name) &&
+		    !strcmp(mapi_nameid_tags[i].OLEGUID, OLEGUID)) {
+			*propType = mapi_nameid_tags[i].propType;
+			return MAPI_E_SUCCESS;
+		}
+	}
+	
+	errno = MAPI_E_NOT_FOUND;
+	return -1;
+}
+
+
+/**
+   \details set SPropTagArray ulPropTag property types from
+   mapi_nameid returned by GetIDsFromNames()
+
+   \param mapi_nameid the structure where results are stored
+   \param SPropTagArray the array of property tags returned by
+   previous call to GetIDsFromNames()
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames
+*/
+_PUBLIC_ enum MAPISTATUS mapi_nameid_SPropTagArray(struct mapi_nameid *mapi_nameid,
+						   struct SPropTagArray *SPropTagArray)
+{
+	uint32_t	i;
+
+	/* sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < mapi_nameid->count; i++) {
+		if (mapi_nameid->entries[i].propType) {
+			SPropTagArray->aulPropTag[i] = (SPropTagArray->aulPropTag[i] & 0xFFFF0000) | 
+				mapi_nameid->entries[i].propType;
+		}
+	}
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Replace named property tags in SPropTagArray with the
+   property ID Exchange expects and stored in SPropTagArray2.
+
+   \param mapi_nameid the structure where results are stored
+   \param SPropTagArray the array of property tags with original
+   property tags
+   \param SPropTagArray2 the array of named property tags resolved
+   with GetIDsFromNames
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropTagArray(struct mapi_nameid *mapi_nameid,
+							struct SPropTagArray *SPropTagArray,
+							struct SPropTagArray *SPropTagArray2)
+{
+	uint32_t	i;
+	uint32_t	j;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray2, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < SPropTagArray->cValues; i++) {
+		for (j = 0; j < mapi_nameid->count; j++) {
+			if (mapi_nameid->entries[j].proptag == SPropTagArray->aulPropTag[i]) {
+				SPropTagArray->aulPropTag[i] = (SPropTagArray2->aulPropTag[j] & 0xFFFF0000) |
+					mapi_nameid->entries[j].propType;
+				mapi_nameid->entries[j].position = i;
+			}
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Restore the original SPropTagArray array with the property
+   tags saved in the mapi_nameid structure.
+
+   \param mapi_nameid the structure where results are stored
+   \param SPropTagArray the array of property tags with original
+   property tags
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropTagArray(struct mapi_nameid *mapi_nameid,
+							 struct SPropTagArray *SPropTagArray)
+{
+	uint32_t	i;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	for (i = 0; i < mapi_nameid->count; i++) {
+		if (mapi_nameid->entries[i].position <= SPropTagArray->cValues) {
+			SPropTagArray->aulPropTag[mapi_nameid->entries[i].position] = mapi_nameid->entries[i].proptag;
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Replace named property tags in the SPropValue array with
+   the property ID Exchange expects and stored in SPropTagArray.
+
+   \param mapi_nameid the structure where results are stored
+   \param lpProps pointer on a SPropValue structure with property tags
+   and values
+   \param PropCount count of lpProps elements
+   \param SPropTagArray the array of named property tags resolved
+   with GetIDsFromNames
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_map_SPropValue(struct mapi_nameid *mapi_nameid,
+						    struct SPropValue *lpProps,
+						    uint32_t PropCount,
+						    struct SPropTagArray *SPropTagArray)
+{
+	uint32_t	i;
+	uint32_t	j;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!PropCount, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < PropCount; i++) {
+		for (j = 0; j < mapi_nameid->count; j++) {
+			if (mapi_nameid->entries[j].proptag == lpProps[i].ulPropTag) {
+				lpProps[i].ulPropTag = (SPropTagArray->aulPropTag[j] & 0xFFFF0000) |
+					mapi_nameid->entries[j].propType;
+				mapi_nameid->entries[j].position = i;
+			}
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Restore the original SPropValue array with the property
+   tags saved in the mapi_nameid structure.
+
+   \param mapi_nameid the structure where results are stored
+   \param lpProps the array of SPropValue structures with original
+   property tags
+   \param PropCount count of lpProps elements
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_unmap_SPropValue(struct mapi_nameid *mapi_nameid,
+						      struct SPropValue *lpProps,
+						      uint32_t PropCount)
+{
+	uint32_t	i;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!PropCount, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < mapi_nameid->count; i++) {
+		if (mapi_nameid->entries[i].position <= PropCount) {
+			lpProps[mapi_nameid->entries[i].position].ulPropTag = mapi_nameid->entries[i].proptag;
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Loop over SPropTagArray and look for canonical named
+   property tags we can add to the nameid structure.
+
+   \param nameid the structure where results are stored
+   \param SPropTagArray the array of property tags where to look for
+   canonical named property tags.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: no named property found
+
+   \sa GetIDsFromNames
+
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropTagArray(struct mapi_nameid *nameid,
+							  struct SPropTagArray *SPropTagArray)
+{
+	enum MAPISTATUS	retval;
+	uint32_t	i;
+	uint16_t	proptype;
+	bool		status = false;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < SPropTagArray->cValues; i++) {
+		proptype = (SPropTagArray->aulPropTag[i] & 0xFFFF0000) >> 16;
+		if (((proptype >= 0x8000) && (proptype <= 0x8FFF)) ||
+		    ((proptype >= 0xa000) && (proptype <= 0xaFFF))) {
+			retval = mapi_nameid_canonical_add(nameid, SPropTagArray->aulPropTag[i]);
+			if (retval == MAPI_E_SUCCESS) {
+				status = true;
+			}
+		}
+	}
+
+	return (status == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Loop over lpProps and look for canonical named
+   property tags we can add to the nameid structure.
+
+   \param mapi_nameid the structure where results are stored
+   \param lpProps pointer on a SPropValue structure with the property
+   tags where to look for canonical named property tags
+   \param PropCount count of lpProps elemense
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+   - MAPI_E_NOT_FOUND: no named property found
+
+   \sa GetIDsFromNames
+
+ */
+_PUBLIC_ enum MAPISTATUS mapi_nameid_lookup_SPropValue(struct mapi_nameid *mapi_nameid,
+						       struct SPropValue *lpProps,
+						       unsigned long PropCount)
+{
+	enum MAPISTATUS	retval;
+	uint32_t	i;
+	uint16_t	proptype;
+	bool		status = false;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpProps, MAPI_E_INVALID_PARAMETER, NULL);
+
+	for (i = 0; i < PropCount; i++) {
+		proptype = (lpProps[i].ulPropTag & 0xFFFF0000) >> 16;
+		if (((proptype >= 0x8000) && (proptype <= 0x8FFF)) ||
+		    ((proptype >= 0xa000) && (proptype <= 0xaFFF))) {
+			retval = mapi_nameid_canonical_add(mapi_nameid, lpProps[i].ulPropTag);
+			if (retval == MAPI_E_SUCCESS) {
+				status = true;
+			}
+		}
+	}
+
+	return (status == true) ? MAPI_E_SUCCESS : MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Lookup named properties (MNID_STRING) and return their
+   mapped proptags
+
+   This convenient function calls GetIDsFromNames() and returns
+   property tags with their real property type.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \note Developers may also call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_INVALID_PARAMETER: one of the parameters was not set
+   properly
+
+   \sa GetIDsFromNames, mapi_nameid_SPropTagArray
+*/
+_PUBLIC_ enum MAPISTATUS mapi_nameid_GetIDsFromNames(struct mapi_nameid *mapi_nameid,
+						     mapi_object_t *obj, 
+						     struct SPropTagArray *SPropTagArray)
+{
+	enum MAPISTATUS		retval;
+	uint32_t		i;
+
+	/* sanity check */
+	OPENCHANGE_RETVAL_IF(!mapi_nameid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+
+	retval = GetIDsFromNames(obj, mapi_nameid->count, mapi_nameid->nameid, 0,
+				 &SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, GetLastError(), NULL);
+
+	for (i = 0; i < SPropTagArray->cValues; i++) {
+		SPropTagArray->aulPropTag[i] = (SPropTagArray->aulPropTag[i] & 0xFFFF0000) | 
+			mapi_nameid->entries[i].propType;
+	}
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/mapi_notification.h
===================================================================
--- trunk/openchange/libmapi/mapi_notification.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_notification.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,49 @@
+/*
+   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/>.
+ */
+
+#ifndef	__MAPI_NOTIFICATION_H__
+#define	__MAPI_NOTIFICATION_H__
+
+/* notification which takes:
+ * - ulEvenType = type of notification
+ * - void * = notification data
+ * - void * = private data pointer
+*/
+typedef int (*mapi_notify_callback_t)(uint16_t, void *, void *);
+
+struct notifications {
+	uint32_t		ulConnection;		/* connection number */
+	uint32_t		NotificationFlags;	/* events mask associated */
+	mapi_id_t		parentID;		/* parent EntryID == FID here */
+	mapi_notify_callback_t	callback;		/* callback to run when */
+	struct mapi_object     	obj_notif;		/* notification object */
+	struct notifications	*prev;
+	struct notifications	*next;
+};
+
+struct mapi_notify_ctx {
+	struct NOTIFKEY		key;		/* unique identifier */
+	int			fd;		/* UDP socket file descriptor */
+	struct sockaddr		*addr;
+	struct notifications	*notifications;
+};
+
+#define	DFLT_NOTIF_PORT	2500
+
+#endif /*!__MAPI_NOTIFICATION_H__ */

Added: trunk/openchange/libmapi/mapi_object.c
===================================================================
--- trunk/openchange/libmapi/mapi_object.c	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_object.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,367 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <libmapi/defs_private.h>
+
+/**
+   \file mapi_object.c
+
+   \brief mapi_object_t support functions
+*/
+
+
+/* FIXME: mapi_object functions should return error codes */
+
+
+/**
+   keep intern to this file
+*/
+#define INVALID_HANDLE_VALUE 0xffffffff
+
+
+/**
+   \details Reset a MAPI object structure
+
+   \param obj pointer on the MAPI object to reset
+ */
+static void mapi_object_reset(mapi_object_t *obj)
+{
+	obj->handle = INVALID_HANDLE_VALUE;
+	obj->id = 0;
+	obj->session = NULL;
+	obj->private_data = NULL;
+}
+
+
+/**
+   \details Initialize MAPI object
+
+   This function is required to be called before any 
+   manipulation of this MAPI object.
+
+   \param obj the object to initialize
+   
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+   
+   \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.
+
+   \sa mapi_object_release
+*/
+_PUBLIC_ enum MAPISTATUS mapi_object_init(mapi_object_t *obj)
+{
+	mapi_object_reset(obj);
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Release MAPI object
+
+   This function is required to be called when this MAPI object
+   is no longer required.
+
+   \param obj pointer on the MAPI object to release
+
+   \sa mapi_object_initialize, Release
+*/
+_PUBLIC_ void mapi_object_release(mapi_object_t *obj)
+{
+	enum MAPISTATUS retval;
+
+	if (!obj) return;
+	if (obj->handle == INVALID_HANDLE_VALUE) return;
+
+	retval = Release(obj);
+	if (retval == MAPI_E_SUCCESS) {
+		if (obj->private_data) {
+			talloc_free(obj->private_data);
+		}
+		mapi_object_reset(obj);
+	}
+}
+
+
+/**
+   \details Check if the supplied object has a valid handle
+
+   \param obj pointer on the MAPI object to test
+
+   \return 0 on success, otherwise 1
+ */
+int mapi_object_is_invalid(mapi_object_t *obj)
+{
+	if (mapi_object_get_handle(obj) == INVALID_HANDLE_VALUE) {
+		return 1;
+	}
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Copy MAPI object
+
+   This function copies mapi_object data from source to destination.
+
+   \param dst pointer on the destination MAPI object
+   \param src pointer on the source MAPI object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED
+
+ */
+_PUBLIC_ enum MAPISTATUS mapi_object_copy(mapi_object_t *dst, mapi_object_t *src)
+{
+	mapi_object_reset(dst);
+
+	OPENCHANGE_RETVAL_IF(!dst || !src, MAPI_E_NOT_INITIALIZED, NULL);
+
+	dst->id = src->id;
+	dst->handle = src->handle;
+	dst->private_data = src->private_data;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the session associated to the MAPI object
+
+   \param obj the object to get the session for
+
+   \return pointer on a MAPI session on success, otherwise NULL
+ */
+_PUBLIC_ struct mapi_session *mapi_object_get_session(mapi_object_t *obj)
+{
+	if (!obj) return NULL;
+	if (!obj->session) return NULL;
+
+	return obj->session;
+}
+
+
+/**
+   \details Set the session for a given MAPI object
+
+   \param obj pointer on the object to set the session for
+   \param session pointer on the MAPI session to associate to the MAPI
+   object
+ */
+_PUBLIC_ void mapi_object_set_session(mapi_object_t *obj, 
+				      struct mapi_session *session)
+{
+	if (obj) {
+		obj->session = session;
+	}
+}
+
+
+/**
+   \details Retrieve an object ID for a given MAPI object
+ 
+   \param obj pointer on the MAPI object to get the ID for
+
+   \return the object ID, or -1 if the object does not exist
+*/
+_PUBLIC_ mapi_id_t mapi_object_get_id(mapi_object_t *obj)
+{
+	return (!obj) ? -1 : obj->id;
+}
+
+
+/**
+   \details Set the id for a given MAPI object
+
+   \param obj pointer on the MAPI object to set the session for
+   \param id Identifier to set to the object obj
+ */
+void mapi_object_set_id(mapi_object_t *obj, mapi_id_t id)
+{
+	obj->id = id;
+}
+
+
+/**
+   \details Retrieve the handle associated to a MAPI object
+
+   \param obj pointer on the MAPI object to retrieve the handle from
+
+   \return a valid MAPI object handle on success, otherwise -1.
+ */
+mapi_handle_t mapi_object_get_handle(mapi_object_t *obj)
+{
+	return (!obj) ? -1 : obj->handle;
+}
+
+
+/**
+   \details Associate a handle to a MAPI object
+
+   \param obj pointer on the MAPI object on which handle has to be set
+   \param handle the MAPI handle value
+ */
+void mapi_object_set_handle(mapi_object_t *obj, mapi_handle_t handle)
+{
+	obj->handle = handle;
+}
+
+
+/**
+   \details Dump a MAPI object (for debugging)
+
+   \param obj pointer on the MAPI object to dump out
+*/
+_PUBLIC_ void mapi_object_debug(mapi_object_t *obj)
+{
+	DEBUG(0, ("mapi_object {\n"));
+	DEBUG(0, (" .handle == 0x%x\n", obj->handle));
+	DEBUG(0, (" .id     == 0x%"PRIx64"\n", obj->id));
+	DEBUG(0, ("};\n"));
+}
+
+
+/**
+   \details Initialize MAPI object private data to store a MAPI object
+   table
+
+   \param mem_ctx pointer on the memory context
+   \param obj_table pointer on the MAPI object
+ */
+void mapi_object_table_init(TALLOC_CTX *mem_ctx, mapi_object_t *obj_table)
+{
+	mapi_object_table_t	*table = NULL;
+
+	if (obj_table->private_data == NULL) {
+		obj_table->private_data = talloc_zero((TALLOC_CTX *)mem_ctx, mapi_object_table_t);
+	}
+
+	table = (mapi_object_table_t *) obj_table->private_data;
+
+	if (table->bookmark == NULL) {
+		table->bookmark = talloc_zero((TALLOC_CTX *)table, mapi_object_bookmark_t);
+	}
+
+
+	table->proptags.aulPropTag = 0;
+	table->proptags.cValues = 0;
+	/* start bookmark index after BOOKMARK_END */ 
+	table->bk_last = 3;
+}
+
+
+/**
+   \details Fetch a bookmark within a MAPI object table
+
+   \param obj_table pointer on the MAPI object table
+   \param bkPosition the bookmark position to find
+   \param bin pointer on the Sbinary_short the function fills
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+enum MAPISTATUS mapi_object_bookmark_find(mapi_object_t *obj_table, uint32_t bkPosition,
+					  struct SBinary_short *bin)
+{
+	mapi_object_table_t	*table;
+	mapi_object_bookmark_t	*bookmark;
+
+	table = (mapi_object_table_t *)obj_table->private_data;
+	bookmark = table->bookmark;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(bkPosition > table->bk_last, MAPI_E_INVALID_BOOKMARK, NULL);
+	
+	while (bookmark) {
+		if (bookmark->index == bkPosition) {
+			bin->cb = bookmark->bin.cb;
+			bin->lpb = bookmark->bin.lpb;
+			return MAPI_E_SUCCESS;
+		}
+		bookmark = bookmark->next;
+	}
+	return MAPI_E_INVALID_BOOKMARK;
+}
+
+
+/**
+   \details Retrieve the number of bookmarks stored in a MAPI object table
+
+   \param obj_table pointer to the MAPI object table
+   \param count pointer to the number of bookmarks to return
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_get_count(mapi_object_t *obj_table, 
+							uint32_t *count)
+{
+	mapi_object_table_t	*table;
+
+	table = (mapi_object_table_t *)obj_table->private_data;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
+
+	*count = table->bk_last - 3;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Dump bookmarks associated to a MAPI object table
+
+   \param obj_table pointer on the MAPI object table
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS mapi_object_bookmark_debug(mapi_object_t *obj_table)
+{
+	mapi_object_table_t	*table;
+	mapi_object_bookmark_t	*bookmark;
+
+	table = (mapi_object_table_t *)obj_table->private_data;
+	bookmark = table->bookmark;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL);
+	
+	while (bookmark) {
+		DEBUG(0, ("mapi_object_bookmark {\n"));
+		DEBUG(0, (".index == %u\n", bookmark->index));
+		dump_data(0, bookmark->bin.lpb, bookmark->bin.cb);
+		DEBUG(0, ("};\n"));
+
+		bookmark = bookmark->next;
+	}	
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/mapi_object.h
===================================================================
--- trunk/openchange/libmapi/mapi_object.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_object.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,117 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#ifndef	__MAPI_OBJECT_H
+#define	__MAPI_OBJECT_H
+
+
+#include <gen_ndr/exchange.h>
+
+
+/* forward declarations
+ */
+struct mapi_session;
+
+/* generic mapi object definition
+ */
+
+typedef uint64_t mapi_id_t;
+typedef uint32_t mapi_handle_t;
+
+typedef struct mapi_object {
+	uint64_t		id;
+	mapi_handle_t		handle;
+  struct mapi_session		*session;
+	void			*private_data;
+} mapi_object_t;
+
+
+/*
+ * Interface objects
+ */
+
+
+/**
+ * IMsgStore object 
+ */
+typedef struct mapi_obj_store
+{
+	/* 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;
+	/* 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;
+	/* 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;
+} mapi_object_store_t;
+
+
+/**
+ * IMAPITable object 
+ */
+
+typedef struct mapi_obj_bookmark {
+	uint32_t			index;
+	struct SBinary_short		bin;
+	struct mapi_obj_bookmark	*prev;
+	struct mapi_obj_bookmark	*next;
+} mapi_object_bookmark_t;
+
+
+typedef struct mapi_obj_table {
+	uint32_t			bk_last;
+	mapi_object_bookmark_t		*bookmark;
+	struct SPropTagArray		proptags;
+} mapi_object_table_t;
+
+
+typedef struct mapi_obj_message {
+	uint32_t			cValues;
+	struct SPropTagArray   		SPropTagArray;
+	struct SRowSet			SRowSet;
+} mapi_object_message_t;
+
+#endif /*!__MAPI_OBJECT_H */

Added: trunk/openchange/libmapi/mapi_profile.h
===================================================================
--- trunk/openchange/libmapi/mapi_profile.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_profile.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,58 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#ifndef __MAPI_PROFILE_H
+#define __MAPI_PROFILE_H
+
+
+#include <talloc.h>
+
+
+/* forward decls */
+struct cli_credentials;
+struct ldb_context;
+
+
+/* mapi profile
+ */
+struct mapi_profile
+{
+	struct cli_credentials	*credentials;
+	char			*profname;
+	const char		*org;
+	const char		*ou;
+	const char     		*username;
+	const char     		*password;
+	const char     		*mailbox;
+	const char     		*workstation;
+	const char		*homemdb;
+	const char     		*domain;
+	const char     		*realm;
+	const char     		*server;
+	uint32_t		codepage;
+	uint32_t		language;
+	uint32_t		method;
+};
+
+typedef int (*mapi_profile_callback_t)(struct SRowSet *, const void *);
+
+#define	OC_PROFILE_NOPASSWORD	1
+
+#endif /* ! __MAPI_PROFILE_H__ */

Added: trunk/openchange/libmapi/mapi_provider.h
===================================================================
--- trunk/openchange/libmapi/mapi_provider.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapi_provider.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,58 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#ifndef __MAPI_PROVIDER_H
+#define __MAPI_PROVIDER_H
+
+
+/* forward decls */
+struct mapi_object;
+struct mapi_profile;
+struct mapi_notify_ctx;
+
+enum PROVIDER_ID {
+	PROVIDER_ID_EMSMDB = 0x1,
+	PROVIDER_ID_NSPI = 0x2,
+	PROVIDER_ID_UNKNOWN
+};
+
+struct mapi_provider {
+	enum PROVIDER_ID	id;
+	void			*ctx;
+};
+
+struct mapi_objects {
+	struct mapi_object	*object;
+	struct mapi_objects	*prev;
+	struct mapi_objects	*next;
+};
+
+struct mapi_session {
+	struct mapi_provider		*emsmdb;
+	struct mapi_provider		*nspi;
+	struct mapi_profile		*profile;
+	struct mapi_notify_ctx		*notify_ctx;
+	struct mapi_objects		*objects;
+
+	struct mapi_session		*next;
+	struct mapi_session		*prev;
+};
+
+#endif /* !__MAPI_PROVIDER_H */

Added: trunk/openchange/libmapi/mapidefs.h
===================================================================
--- trunk/openchange/libmapi/mapidefs.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapidefs.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,292 @@
+/*
+   OpenChange MAPI implementation.
+   MAPI definitions
+
+   Copyright (C) Julien Kerihuel 2005 - 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/>.
+ */
+
+#ifndef __MAPIDEFS_H__
+#define __MAPIDEFS_H__
+
+#define PROP_TAG(type, id) (((id << 16))| (type))
+#define MV_FLAG			0x1000
+
+/* UNICODE flags */
+#define	MAPI_UNICODE		0x80000000
+
+/* Property types */
+#define	PT_UNSPECIFIED		0x0
+#define	PT_NULL			0x1
+#define	PT_I2			0x2
+#define	PT_SHORT		0x2
+#define	PT_LONG			0x3
+#define	PT_FLOAT		0x4
+#define	PT_DOUBLE		0x5
+#define	PT_CURRENCY		0x6
+#define	PT_APPTIME		0x7
+#define	PT_ERROR		0xa
+#define	PT_BOOLEAN		0xb
+#define	PT_OBJECT		0xd
+#define	PT_I8			0x14
+#define	PT_STRING8		0x1e
+#define	PT_UNICODE		0x1f
+#define	PT_SYSTIME		0x40
+#define	PT_CLSID		0x48
+#define	PT_SVREID		0xFB
+#define	PT_SRESTRICT		0xFD
+#define	PT_BINARY		0x102
+
+/* Multi valued property types */
+#define	PT_MV_SHORT		(MV_FLAG | PT_SHORT)
+#define	PT_MV_LONG		(MV_FLAG | PT_LONG)
+#define	PT_MV_FLOAT		(MV_FLAG | PT_FLOAT)
+#define	PT_MV_DOUBLE		(MV_FLAG | PT_DOUBLE)
+#define	PT_MV_CURRENCY		(MV_FLAG | PT_CURRENCY)
+#define	PT_MV_APPTIME		(MV_FLAG | PT_APPTIME)
+#define	PT_MV_I8		(MV_FLAG | PT_I8)
+#define	PT_MV_STRING8		(MV_FLAG | PT_STRING8)
+#define	PT_MV_UNICODE		(MV_FLAG | PT_UNICODE)
+#define	PT_MV_SYSTIME		(MV_FLAG | PT_SYSTIME)
+#define PT_MV_CLSID		(MV_FLAG | PT_CLSID)
+#define	PT_MV_BINARY		(MV_FLAG | PT_BINARY)
+
+/* Restriction types */
+#define RES_AND			0
+#define RES_OR			1
+#define RES_NOT			2
+#define RES_CONTENT		3
+#define RES_PROPERTY		4
+#define RES_COMPAREPROPS	5
+#define RES_BITMASK		6
+#define RES_SIZE		7
+#define RES_EXIST		8
+#define RES_SUBRESTRICTION	9
+#define RES_COMMENT		10
+
+/* Resolve types */
+#define MAPI_UNRESOLVED		0x0
+#define MAPI_AMBIGUOUS		0x1
+#define MAPI_RESOLVED		0x2
+
+/* Object Type */
+#define MAPI_STORE		0x1    	/* Message Store */
+#define MAPI_ADDRBOOK		0x2    	/* Address Book */
+#define MAPI_FOLDER		0x3    	/* Folder */
+#define MAPI_ABCONT		0x4    	/* Address Book Container */
+#define MAPI_MESSAGE		0x5    	/* Message */
+#define MAPI_MAILUSER		0x6    	/* Individual Recipient */
+#define MAPI_ATTACH		0x7    	/* Attachment */
+#define MAPI_DISTLIST		0x8    	/* Distribution List Recipient */
+#define MAPI_PROFSECT		0x9    	/* Profile Section */
+#define MAPI_STATUS		0xA    	/* Status Object */
+#define MAPI_SESSION		0xB	/* Session */
+#define MAPI_FORMINFO		0xC	/* Form Information */
+
+/* Display Type */
+#define DT_MAILUSER		0x0
+#define DT_DISTLIST		0x1
+#define DT_FORUM		0x2
+#define DT_AGENT		0x3
+#define DT_ORGANIZATION		0x4
+#define DT_PRIVATE_DISTLIST	0x5
+#define DT_REMOTE_MAILUSER	0x6
+#define	DT_CONTAINER		0x100
+#define	DT_TEMPLATE		0x101
+#define	DT_ADDRESS_TEMPLATE	0x102
+#define	DT_SEARCH		0x200
+
+/* Attachment method */
+#define NO_ATTACHMENT		0
+#define ATTACH_BY_VALUE		1
+#define ATTACH_BY_REFERENCE	2
+#define ATTACH_BY_REF_RESOLVE	3
+#define ATTACH_BY_REF_ONLY	4
+#define ATTACH_EMBEDDED_MSG	5
+#define ATTACH_OLE		6
+
+/* Creation flags */
+#define	MAPI_CREATE		0x2
+
+/* SaveChanges flags */
+#define KEEP_OPEN_READONLY	0x1
+#define KEEP_OPEN_READWRITE	0x2
+#define FORCE_SAVE		0x4
+/* #define MAPI_DEFERRED_ERRORS 0x8 (already defined in the IDL */
+
+/* OpenMessage flags */
+#define	MAPI_MODIFY             0x1
+/* see MAPI_CREATE above */
+
+
+/* GetGALTable flags */
+#define	TABLE_START		0x0
+#define	TABLE_CUR		0x1
+
+/*
+ * ENTRYID flags
+ */
+
+/* definition for abFlags[0] */
+#define MAPI_SHORTTERM          0x80
+#define MAPI_NOTRECIP           0x40
+#define MAPI_THISSESSION        0x20
+#define MAPI_NOW                0x10
+#define MAPI_NOTRESERVED        0x08
+
+/* definition for abFlags[1] */
+#define MAPI_COMPOUND           0x80
+
+/*
+ * Priority
+ */
+
+#define	PRIORITY_LOW		-1
+#define	PRIORITY_NORMAL		0
+#define	PRIORITY_HIGH		1
+
+/*
+ * Importance
+ */
+
+#define	IMPORTANCE_LOW		0
+#define	IMPORTANCE_NORMAL	1
+#define	IMPORTANCE_HIGH		2
+
+/*
+ * Color
+ */
+
+#define	olBlue			0
+#define	olGreen			1
+#define	olPink			2
+#define	olYellow		3
+#define	olWhite			4
+
+
+/*
+ * Appointment flags with PR_APPOINTMENT_BUSY_STATUS
+ */
+
+#define	BUSY_STATUS_FREE	0
+#define	BUSY_STATUS_TENTATIVE	1
+#define	BUSY_STATUS_BUSY	2
+#define	BUSY_STATUS_OUTOFOFFICE	3
+
+/*
+ * Appointment meeting status
+ */
+#define MEETING_STATUS_NONMEETING	0
+#define MEETING_STATUS_MEETING		1
+
+/*
+ * Task status
+ */
+
+#define	olTaskNotStarted		0
+#define	olTaskInProgress		1
+#define	olTaskComplete			2
+#define	olTaskWaiting			3
+#define	olTaskDeferred			4
+
+/*
+ * Task OwnerShip
+ */
+#define	olNewTask			0
+#define	olDelegatedTask			1
+#define	olOwnTask			2
+
+/*
+ * PR_MESSAGE_EDITOR_FORMAT type
+ */
+#define	EDITOR_FORMAT_PLAINTEXT		1
+#define	EDITOR_FORMAT_HTML		2
+#define	EDITOR_FORMAT_RTF		3
+
+#define	olEditorText			1
+#define	olEditorHTML			2
+#define	olEditorRTF			3
+#define	olEditorWord			4
+
+/*
+ * Default folders
+ */
+#define	olFolderTopInformationStore	1
+#define	olFolderDeletedItems		3
+#define	olFolderOutbox			4
+#define	olFolderSentMail		5
+#define	olFolderInbox			6
+#define	olFolderCommonView		8
+#define	olFolderCalendar		9
+#define	olFolderContacts		10
+#define	olFolderJournal			11
+#define	olFolderNotes			12
+#define	olFolderTasks			13
+#define	olFolderDrafts			16
+#define	olPublicFoldersAllPublicFolders	18
+#define	olFolderConflicts		19
+#define	olFolderSyncIssues		20
+#define	olFolderLocalFailures		21
+#define	olFolderServerFailures		22
+#define	olFolderJunk			23
+#define	olFolderFinder			24
+#define	olFolderPublicRoot		25
+#define	olFolderPublicIPMSubtree	26
+#define	olFolderPublicNonIPMSubtree	27
+#define	olFolderPublicEFormsRoot	28
+#define	olFolderPublicFreeBusyRoot	29
+#define	olFolderPublicOfflineAB		30
+#define	olFolderPublicEFormsRegistry	31
+#define	olFolderPublicLocalFreeBusy	32
+#define	olFolderPublicLocalOfflineAB	33
+#define	olFolderPublicNNTPArticle	34
+
+/*
+ * IPF container class
+ */
+
+#define	IPF_APPOINTMENT			"IPF.Appointment"
+#define	IPF_CONTACT			"IPF.Contact"
+#define	IPF_JOURNAL			"IPF.Journal"
+#define	IPF_NOTE			"IPF.Note"
+#define	IPF_STICKYNOTE			"IPF.StickyNote"
+#define	IPF_TASK			"IPF.Task"
+#define	IPF_POST			"IPF.Post"
+
+/*
+ * Common OLEGUID - see MS-OXPROPS, Section 1.3.2
+ */
+
+#define	PSETID_Appointment	"00062002-0000-0000-c000-000000000046"
+#define	PSETID_Task		"00062003-0000-0000-c000-000000000046"
+#define	PSETID_Address		"00062004-0000-0000-c000-000000000046"
+#define	PSETID_Common		"00062008-0000-0000-c000-000000000046"
+#define	PSETID_Note		"0006200e-0000-0000-c000-000000000046"
+#define	PSETID_Log		"0006200a-0000-0000-c000-000000000046"
+#define	PSETID_Sharing		"00062040-0000-0000-c000-000000000046"
+#define	PSETID_PostRss		"00062041-0000-0000-c000-000000000046"
+#define	PSETID_UnifiedMessaging	"4442858e-a9e3-4e80-b900-317a210cc15b"
+#define	PSETID_Meeting		"6ed8da90-450b-101b-98da-00aa003f1305"
+#define	PSETID_AirSync		"71035549-0739-4dcb-9163-00f0580dbbdf"
+#define	PSETID_Attachment	"96357f7f-59e1-47d0-99a7-46515c183b54"
+#define	PS_PUBLIC_STRINGS	"00020329-0000-0000-c000-000000000046"
+#define	PS_INTERNET_HEADERS	"00020386-0000-0000-c000-000000000046"
+#define	PS_MAPI			"00020328-0000-0000-c000-000000000046"
+
+/* FreeBusy strings for Exchange 2003 and below */
+#define	FREEBUSY_FOLDER		"EX:/o=%s/ou=%s"
+#define	FREEBUSY_USER		"USER-/CN=RECIPIENTS/CN=%s"
+
+#endif /*!__MAPIDEFS_H__ */

Added: trunk/openchange/libmapi/mapidump.c
===================================================================
--- trunk/openchange/libmapi/mapidump.c	                        (rev 0)
+++ trunk/openchange/libmapi/mapidump.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,767 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/mapidump.h>
+#include <libmapi/proto_private.h>
+#include <libmapi/defs_private.h>
+#include <time.h>
+
+/**
+   \file mapidump.c
+
+   \brief Functions for displaying various data structures, mainly for debugging
+ */
+
+_PUBLIC_ void mapidump_SPropValue(struct SPropValue lpProp, const char *sep)
+{
+	const char			*proptag;
+	const void			*data;
+	TALLOC_CTX			*mem_ctx = NULL;
+	const struct StringArray_r	*StringArray_r = NULL;
+	uint32_t			i;
+
+	proptag = get_proptag_name(lpProp.ulPropTag);
+	if (!proptag) {
+		mem_ctx = talloc_named(NULL, 0, "mapidump_SPropValue");
+		proptag = talloc_asprintf(mem_ctx, "0x%.8x", lpProp.ulPropTag);
+	}
+	
+
+	switch(lpProp.ulPropTag & 0xFFFF) {
+	case PT_BOOLEAN:
+		data = get_SPropValue_data(&lpProp);
+		printf("%s%s: 0x%x\n", sep?sep:"", proptag, (*(const uint8_t *)data));
+		break;
+	case PT_I8:
+		data = get_SPropValue_data(&lpProp);
+		printf("%s%s: %.16"PRIx64"\n", sep?sep:"", proptag, (*(const uint64_t *)data));
+		break;
+	case PT_STRING8:
+	case PT_UNICODE:
+		data = get_SPropValue_data(&lpProp);
+		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);
+		break;
+	case PT_ERROR:
+		data = get_SPropValue_data(&lpProp);
+		printf("%s%s: 0x%.8x\n", sep?sep:"", proptag, (*(const uint32_t *)data));
+		break;
+	case PT_LONG:
+		data = get_SPropValue_data(&lpProp);
+		printf("%s%s: %u\n", sep?sep:"", proptag, (*(const uint32_t *)data));
+		break;
+	case PT_BINARY:
+		data = get_SPropValue_data(&lpProp);
+		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:
+		StringArray_r = (const struct StringArray_r *) get_SPropValue_data(&lpProp);
+		printf("%s%s: ", sep?sep:"", proptag);
+		for (i = 0; i < StringArray_r->cValues - 1; i++) {
+			printf("%s, ", StringArray_r->lppszA[i]);
+		}
+		printf("%s\n", StringArray_r->lppszA[i]);
+		break;
+	default:
+		break;
+	}
+
+	if (mem_ctx) {
+		talloc_free(mem_ctx);
+	}
+
+}
+
+_PUBLIC_ void mapidump_SPropTagArray(struct SPropTagArray *SPropTagArray)
+{
+	uint32_t	count;
+	const char	*proptag;
+
+	if (!SPropTagArray) return;
+	if (!SPropTagArray->cValues) return;
+
+	for (count = 0; count != SPropTagArray->cValues; count++) {
+		proptag = get_proptag_name(SPropTagArray->aulPropTag[count]);
+		if (proptag) {
+			printf("%s\n", proptag);
+		} else {
+			printf("0x%.8x\n", SPropTagArray->aulPropTag[count]);
+		}
+	}
+}
+
+_PUBLIC_ void mapidump_SRowSet(struct SRowSet *SRowSet, const char *sep)
+{
+	uint32_t		i;
+
+	/* Sanity checks */
+	if (!SRowSet) return;
+	if (!SRowSet->cRows) return;
+
+	for (i = 0; i < SRowSet->cRows; i++) {
+		mapidump_SRow(&(SRowSet->aRow[i]), sep);
+	}
+}
+
+_PUBLIC_ void mapidump_SRow(struct SRow *aRow, const char *sep)
+{
+	uint32_t		i;
+
+	for (i = 0; i < aRow->cValues; i++) {
+		mapidump_SPropValue(aRow->lpProps[i], sep);
+	}
+}
+
+
+_PUBLIC_ void mapidump_PAB_entry(struct SRow *aRow)
+{
+	const char	*addrtype;
+	const char	*name;
+	const char	*email;
+	const char	*account;
+
+	addrtype = (const char *)find_SPropValue_data(aRow, PR_ADDRTYPE_UNICODE);
+	name = (const char *)find_SPropValue_data(aRow, PR_DISPLAY_NAME_UNICODE);
+	email = (const char *)find_SPropValue_data(aRow, PR_EMAIL_ADDRESS_UNICODE);
+	account = (const char *)find_SPropValue_data(aRow, PR_ACCOUNT_UNICODE);
+
+	printf("[%s] %s:\n\tName: %-25s\n\tEmail: %-25s\n", 
+	       addrtype, account, name, email);
+	fflush(0);
+}
+
+
+_PUBLIC_ void mapidump_Recipients(const char **usernames, struct SRowSet *rowset, struct SPropTagArray *flaglist)
+{
+	uint32_t		i;
+	uint32_t		j;
+
+	for (i = 0, j= 0; i < flaglist->cValues; i++) {
+		switch (flaglist->aulPropTag[i]) {
+		case MAPI_UNRESOLVED:
+			printf("\tUNRESOLVED (%s)\n", usernames[i]);
+			break;
+		case MAPI_AMBIGUOUS:
+			printf("\tAMBIGUOUS (%s)\n", usernames[i]);
+			break;
+		case MAPI_RESOLVED:
+			printf("\tRESOLVED (%s)\n", usernames[i]);
+			mapidump_SRow(&rowset->aRow[j], "\t\t[+] ");
+			j++;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+_PUBLIC_ void mapidump_date(struct mapi_SPropValue_array *properties, uint32_t mapitag, const char *label)
+{
+	TALLOC_CTX		*mem_ctx;
+	NTTIME			time;
+	const struct FILETIME	*filetime;
+	const char		*date;
+
+	mem_ctx = talloc_named(NULL, 0, "mapidump_date");
+
+	filetime = (const struct FILETIME *) find_mapi_SPropValue_data(properties, mapitag);
+	if (filetime) {
+		time = filetime->dwHighDateTime;
+		time = time << 32;
+		time |= filetime->dwLowDateTime;
+		date = nt_time_string(mem_ctx, time);
+		printf("\t%-15s:   %s\n", label, date);
+		fflush(0);
+	}
+
+	talloc_free(mem_ctx);
+}
+
+
+_PUBLIC_ void mapidump_date_SPropValue(struct SPropValue lpProp, const char *label)
+{
+	TALLOC_CTX		*mem_ctx;
+	NTTIME			time;
+	const struct FILETIME		*filetime;
+	const char		*date;
+
+	mem_ctx = talloc_named(NULL, 0, "mapidump_date_SPropValue");
+
+	filetime = (const struct FILETIME *) get_SPropValue_data(&lpProp);
+	if (filetime) {
+		time = filetime->dwHighDateTime;
+		time = time << 32;
+		time |= filetime->dwLowDateTime;
+		date = nt_time_string(mem_ctx, time);
+		printf("\t%s:   %s\n", label, date);
+		fflush(0);
+	}
+
+	talloc_free(mem_ctx);
+}
+
+/**
+   \details This function dumps the properties relating to a 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)
+
+   \sa mapidump_appointment, mapidump_contact, mapidump_task, mapidump_note
+*/
+_PUBLIC_ void mapidump_message(struct mapi_SPropValue_array *properties, const char *id)
+{
+	const char			*msgid;
+	const char			*from;
+	const char			*to;
+	const char			*cc;
+	const char			*bcc;
+	const char			*subject;
+	const char			*body;
+	const char			*codepage;
+	const struct SBinary_short	*html = NULL;
+	const uint8_t			*has_attach;
+	const uint32_t       		*cp;
+	ssize_t				len;
+
+	msgid = (const char *)find_mapi_SPropValue_data(properties, PR_INTERNET_MESSAGE_ID);
+	subject = (const char *) find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	body = (const char *) find_mapi_SPropValue_data(properties, PR_BODY);
+	if (!body) {
+		body = (const char *) find_mapi_SPropValue_data(properties, PR_BODY_UNICODE);
+		if (!body) {
+			html = (const struct SBinary_short *) find_mapi_SPropValue_data(properties, PR_HTML);
+		}
+	}
+	from = (const char *) find_mapi_SPropValue_data(properties, PR_SENT_REPRESENTING_NAME);
+	to = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_TO);
+	cc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_CC);
+	bcc = (const char *) find_mapi_SPropValue_data(properties, PR_DISPLAY_BCC);
+
+	has_attach = (const uint8_t *)find_mapi_SPropValue_data(properties, PR_HASATTACH);
+
+	cp = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_MESSAGE_CODEPAGE);
+	switch (cp ? *cp : 0) {
+	case CP_USASCII:
+		codepage = "CP_USASCII";
+		break;
+	case CP_UNICODE:
+		codepage = "CP_UNICODE";
+		break;
+	case CP_JAUTODETECT:
+		codepage = "CP_JAUTODETECT";
+		break;
+	case CP_KAUTODETECT:
+		codepage = "CP_KAUTODETECT";
+		break;
+	case CP_ISO2022JPESC:
+		codepage = "CP_ISO2022JPESC";
+		break;
+	case CP_ISO2022JPSIO:
+		codepage = "CP_ISO2022JPSIO";
+		break;
+	default:
+		codepage = "";
+		break;
+	}
+
+	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 (has_attach) {
+		printf("Attachment: %s\n", *has_attach ? "True" : "False");
+	}
+	printf("Codepage: %s\n", codepage);
+	printf("Body:\n");
+	fflush(0);
+	if (body) {
+		printf("%s\n", body ? body : "");
+	} else if (html) {
+		len = write(1, html->lpb, html->cb);
+		len = write(1, "\n", 1);
+		fflush(0);
+	}
+}
+
+/**
+   \details This function dumps the properties relating to an appointment to standard output
+
+   The expected way to obtain the properties array is to use OpenMessage() to obtain the
+   appointment object, then to use GetPropsAll() to obtain all the properties.
+
+   \param properties array of appointment properties
+   \param id identification to display for the appointment (can be NULL)
+
+   \sa mapidump_message, mapidump_contact, mapidump_task, mapidump_note
+*/
+_PUBLIC_ void mapidump_appointment(struct mapi_SPropValue_array *properties, const char *id)
+{
+	const struct mapi_SLPSTRArray	*contacts = NULL;
+	const char		*subject = NULL;
+	const char		*location= NULL;
+	const char		*timezone = NULL;
+	const uint32_t		*status;
+	const uint8_t	       	*priv = NULL;
+	uint32_t       		i;
+
+	contacts = (const struct mapi_SLPSTRArray *)find_mapi_SPropValue_data(properties, PidLidContacts);
+	subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	timezone = (const char *)find_mapi_SPropValue_data(properties, PidLidTimeZoneDescription);
+	location = (const char *)find_mapi_SPropValue_data(properties, PidLidLocation);
+	status = (const uint32_t *)find_mapi_SPropValue_data(properties, PidLidBusyStatus);
+	priv = (const uint8_t *)find_mapi_SPropValue_data(properties, PidLidPrivate);
+
+	printf("|== %s ==| %s\n", subject?subject:"", id?id:"");
+	fflush(0);
+
+	if (location) {
+		printf("\tLocation: %s\n", location);
+		fflush(0);
+	}
+
+	mapidump_date(properties, PR_START_DATE, "Start time");
+	mapidump_date(properties, PR_END_DATE, "End time");
+
+	if (timezone) {
+		printf("\tTimezone: %s\n", timezone);
+		fflush(0);
+	}
+
+	printf("\tPrivate: %s\n", (priv && (*priv == true)) ? "True" : "False");
+	fflush(0);
+
+	if (status) {
+		printf("\tStatus: %s\n", get_task_status(*status));
+		fflush(0);
+	}
+
+	if (contacts) {
+		printf("\tContacts:\n");
+		fflush(0);
+		for (i = 0; i < contacts->cValues; i++) {
+			printf("\t\tContact: %s\n", contacts->strings[i].lppszA);
+			fflush(0);
+		}
+	}	
+}
+
+/**
+   \details This function dumps the properties relating to a contact (address book entry)
+   to standard output
+
+   The expected way to obtain the properties array is to use OpenMessage() to obtain the
+   contact object, then to use GetPropsAll() to obtain all the properties.
+
+   \param properties array of contact properties
+   \param id identification to display for the contact (can be NULL)
+
+   \sa mapidump_message, mapidump_appointment, mapidump_task, mapidump_note
+*/
+_PUBLIC_ void mapidump_contact(struct mapi_SPropValue_array *properties, const char *id)
+{
+	const char	*card_name =NULL;
+	const char	*topic =NULL;
+	const char	*full_name = NULL;
+	const char	*given_name = NULL;
+	const char	*surname = NULL;
+	const char	*company = NULL;
+	const char	*email = NULL;
+	const char	*title = NULL;
+	const char      *office_phone = NULL;
+	const char      *home_phone = NULL;
+	const char      *mobile_phone = NULL;
+	const char      *postal_address = NULL;
+	const char      *street_address = NULL;
+	const char      *locality = NULL;
+	const char      *state = NULL;
+	const char      *country = NULL;
+	const char      *department = NULL;
+	const char      *business_fax = NULL;
+	const char      *business_home_page = NULL;
+
+	card_name = (const char *)find_mapi_SPropValue_data(properties, PidLidFileUnder);
+	topic = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	company = (const char *)find_mapi_SPropValue_data(properties, PR_COMPANY_NAME);
+	title = (const char *)find_mapi_SPropValue_data(properties, PR_TITLE);
+	full_name = (const char *)find_mapi_SPropValue_data(properties, PR_DISPLAY_NAME);
+	given_name = (const char *)find_mapi_SPropValue_data(properties, PR_GIVEN_NAME);
+	surname = (const char *)find_mapi_SPropValue_data(properties, PR_SURNAME);
+	department = (const char *)find_mapi_SPropValue_data(properties, PR_DEPARTMENT_NAME);
+	email = (const char *)find_mapi_SPropValue_data(properties, PidLidEmail1OriginalDisplayName);
+	office_phone = (const char *)find_mapi_SPropValue_data(properties, PR_OFFICE_TELEPHONE_NUMBER);
+	home_phone = (const char *)find_mapi_SPropValue_data(properties, PR_HOME_TELEPHONE_NUMBER);
+	mobile_phone = (const char *)find_mapi_SPropValue_data(properties, PR_MOBILE_TELEPHONE_NUMBER);
+	business_fax = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_FAX_NUMBER);
+	business_home_page = (const char *)find_mapi_SPropValue_data(properties, PR_BUSINESS_HOME_PAGE);
+	postal_address = (const char*)find_mapi_SPropValue_data(properties, PR_POSTAL_ADDRESS);
+	street_address = (const char*)find_mapi_SPropValue_data(properties, PR_STREET_ADDRESS);
+	locality = (const char*)find_mapi_SPropValue_data(properties, PR_LOCALITY);
+	state = (const char*)find_mapi_SPropValue_data(properties, PR_STATE_OR_PROVINCE);
+	country = (const char*)find_mapi_SPropValue_data(properties, PR_COUNTRY);
+
+	if (card_name) 
+		printf("|== %s ==| %s\n", card_name, id?id:"");
+	else if (topic)
+		printf("|== %s ==| %s\n", topic, id?id:"");
+	else 
+	  printf("|== <Unknown> ==| %s\n", id?id:"");
+	fflush(0);
+	if (topic) printf("Topic: %s\n", topic);
+	fflush(0);
+	if (full_name)
+		printf("Full Name: %s\n", full_name);
+	else if (given_name && surname)
+		printf("Full Name: %s %s\n", given_name, surname); // initials? l10n?
+	fflush(0);
+	if (title) printf("Job Title: %s\n", title);
+	fflush(0);
+	if (department) printf("Department: %s\n", department);
+	fflush(0);
+	if (company) printf("Company: %s\n", company);
+	fflush(0);
+	if (email) printf("E-mail: %s\n", email);
+	fflush(0);
+	if (office_phone) printf("Office phone number: %s\n", office_phone);
+	fflush(0);
+	if (home_phone) printf("Work phone number: %s\n", home_phone);
+	fflush(0);
+	if (mobile_phone) printf("Mobile phone number: %s\n", mobile_phone);
+	fflush(0);
+	if (business_fax) printf("Business fax number: %s\n", business_fax);
+	fflush(0);
+	if (business_home_page) printf("Business home page: %s\n", business_home_page);
+	fflush(0);
+	if (postal_address) printf("Postal address: %s\n", postal_address);
+	fflush(0);
+	if (street_address) printf("Street address: %s\n", street_address);
+	fflush(0);
+	if (locality) printf("Locality: %s\n", locality);
+	fflush(0);
+	if (state) printf("State / Province: %s\n", state);
+	fflush(0);
+	if (country) printf("Country: %s\n", country);
+	fflush(0);
+
+	printf("\n");
+}
+
+_PUBLIC_ const char *get_task_status(uint32_t status)
+{
+	switch (status) {
+	case olTaskNotStarted:
+		return ("Not Started");
+	case olTaskInProgress:
+		return ("In Progress");
+	case olTaskComplete:
+		return ("Completed");
+	case olTaskWaiting:
+		return ("Waiting on someone else");
+	case olTaskDeferred:
+		return ("Deferred");
+	}
+
+	return NULL;
+}
+
+_PUBLIC_ const char *get_importance(uint32_t importance)
+{
+	switch (importance) {
+	case IMPORTANCE_LOW:
+		return ("Low");
+	case IMPORTANCE_NORMAL:
+		return ("Normal");
+	case IMPORTANCE_HIGH:
+		return ("High");
+	}
+	return NULL;
+}
+
+/**
+   \details This function dumps the properties relating to a task (to-do list entry)
+   to standard output
+
+   The expected way to obtain the properties array is to use OpenMessage() to obtain the
+   task object, then to use GetPropsAll() to obtain all the properties.
+
+   \param properties array of task properties
+   \param id identification to display for the task (can be NULL)
+
+   \sa mapidump_message, mapidump_appointment, mapidump_contact, mapidump_note
+*/
+_PUBLIC_ void mapidump_task(struct mapi_SPropValue_array *properties, const char *id)
+{
+	const struct mapi_SLPSTRArray	*contacts = NULL;
+	const char			*subject = NULL;
+	const char			*body = NULL;
+	const double			*complete = 0;
+	const uint32_t			*status;
+	const uint32_t			*importance;
+	const uint8_t			*private;
+	uint32_t       			i;
+
+	contacts = (const struct mapi_SLPSTRArray *)find_mapi_SPropValue_data(properties, PidLidContacts);
+	subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY);
+	complete = (const double *)find_mapi_SPropValue_data(properties, PidLidPercentComplete);
+	status = (const uint32_t *)find_mapi_SPropValue_data(properties, PidLidTaskStatus);
+	importance = (const uint32_t *)find_mapi_SPropValue_data(properties, PR_IMPORTANCE);
+	private = (const uint8_t *)find_mapi_SPropValue_data(properties, PidLidPrivate);
+
+	printf("|== %s ==| %s\n", subject?subject:"", id?id:"");
+	fflush(0);
+
+	printf("\tBody: %s\n", body?body:"none");
+	fflush(0);
+
+	if (complete) {
+		printf("\tComplete: %u %c\n", (uint32_t)(*complete * 100), '%');
+		fflush(0);
+	}
+
+	if (status) {
+		printf("\tStatus: %s\n", get_task_status(*status));
+		fflush(0);
+		if (*status == olTaskComplete) {
+			mapidump_date(properties, PidLidTaskDateCompleted, "Date Completed");
+		}
+	}
+
+	if (importance) {
+		printf("\tImportance: %s\n", get_importance(*importance));
+		fflush(0);
+	}
+
+	mapidump_date(properties, PidLidTaskDueDate,"Due Date");
+	mapidump_date(properties, PidLidTaskStartDate, "Start Date");
+
+	if (private) {
+		printf("\tPrivate: %s\n", (*private == true)?"True":"False");
+		fflush(0);
+	} else {
+		printf("\tPrivate: false\n");
+		fflush(0);
+	}
+
+	if (contacts) {
+		for (i = 0; i < contacts->cValues; i++) {
+			printf("\tContact: %s\n", contacts->strings[i].lppszA);
+			fflush(0);
+		}
+	}
+}
+
+/**
+   \details This function dumps the properties relating to a note to standard output
+
+   The expected way to obtain the properties array is to use OpenMessage() to obtain the
+   note object, then to use GetPropsAll() to obtain all the properties.
+
+   \param properties array of note properties
+   \param id identification to display for the note (can be NULL)
+
+   \sa mapidump_message, mapidump_appointment, mapidump_contact, mapidump_task
+*/
+_PUBLIC_ void mapidump_note(struct mapi_SPropValue_array *properties, const char *id)
+{
+	const char		*subject = NULL;
+	const char		*body = NULL;
+
+	subject = (const char *)find_mapi_SPropValue_data(properties, PR_CONVERSATION_TOPIC);
+	body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY);
+
+	printf("|== %s ==| %s\n", subject?subject:"", id?id:"");
+	fflush(0);
+	
+	mapidump_date(properties, PR_CLIENT_SUBMIT_TIME, "Submit Time");
+
+	if (body) {
+		printf("Content:\n");
+		printf("%s\n", body);
+		fflush(0);
+	} else {
+		body = (const char *)find_mapi_SPropValue_data(properties, PR_BODY_HTML);
+		if (body) {
+			printf("Content HTML:\n");
+			printf("%s\n", body);
+			fflush(0);
+		}
+	}
+}
+
+_PUBLIC_ void mapidump_msgflags(uint32_t MsgFlags, const char *sep)
+{
+	uint32_t	i;
+	
+	for (i = 0; mdump_msgflags[i].flag; i++) {
+		if (MsgFlags & mdump_msgflags[i].flag) {
+			printf("%s\t%s (0x%x)\n", sep?sep:"", 
+			       mdump_msgflags[i].value, mdump_msgflags[i].flag);
+			fflush(0);
+		}
+	}
+
+}
+
+
+_PUBLIC_ void mapidump_newmail(struct NewMailNotification *newmail, const char *sep)
+{
+	printf("%sParent Entry ID: 0x%"PRIx64"\n", sep?sep:"", newmail->FID);
+	fflush(0);
+	printf("%sMessage Entry ID: 0x%"PRIx64"\n", sep?sep:"", newmail->MID);
+	fflush(0);
+	printf("%sMessage flags:\n", sep?sep:"");
+	fflush(0);
+	mapidump_msgflags(newmail->MessageFlags, sep);
+	if (newmail->UnicodeFlag == 0x0) {
+		printf("%sMessage Class: %s\n", sep?sep:"", newmail->MessageClass.lpszA);
+	} else {
+		printf("%sMessage Class: %s\n", sep?sep:"", newmail->MessageClass.lpszW);
+	}
+	fflush(0);
+}
+
+
+_PUBLIC_ const char *mapidump_freebusy_month(uint32_t month, uint32_t year)
+{
+	uint32_t	realmonth;
+
+	realmonth = month - (year * 16);
+
+	switch (realmonth) {
+	case 0x1:
+		return "January";
+	case 0x2:
+		return "February";
+	case 0x3:
+		return "March";
+	case 0x4:
+		return "April";
+	case 0x5:
+		return "May";
+	case 0x6:
+		return "June";
+	case 0x7:
+		return "July";
+	case 0x8:
+		return "August";
+	case 0x9:
+		return "September";
+	case 0xa:
+		return "October";
+	case 0xb:
+		return "November";
+	case 0xc:
+		return "December";
+	}
+	return NULL;
+}
+
+
+_PUBLIC_ uint32_t mapidump_freebusy_year(uint32_t month, uint32_t year)
+{
+	uint32_t	realmonth;
+
+	realmonth = month - (year * 16);
+	while (realmonth > 0xc) {
+		year++;
+		realmonth = month - (year * 16);
+	}
+
+	return year;
+}
+
+
+_PUBLIC_ void mapidump_freebusy_date(uint32_t t, const char *sep)
+{
+	TALLOC_CTX	*mem_ctx;
+	NTTIME		time;
+	const char	*date;
+
+	mem_ctx = talloc_named(NULL, 0, "mapidump_freebusy_date");
+
+	time = t;
+	time *= 60;
+	time *= 10000000;
+
+	date = nt_time_string(mem_ctx, time);
+	DEBUG(0, ("%s %-30s\n", sep, date));
+	talloc_free((char *)date);
+	talloc_free(mem_ctx);
+}
+
+
+_PUBLIC_ void mapidump_freebusy_event(struct Binary_r *bin, uint32_t month, uint32_t year, const char *sep)
+{
+	uint16_t	event_start;
+	uint16_t	event_end;
+	uint32_t	i;
+	uint32_t       	hour;
+	uint32_t       	hours;
+	uint32_t	day;
+	const char	*month_name;
+	uint32_t	last;
+	uint32_t	minutes;
+
+	if (!bin) return;
+	/* bin.cb must be a multiple of 4 */
+	if (bin->cb % 4) return;
+
+	year = mapidump_freebusy_year(month, year);
+	month_name = mapidump_freebusy_month(month, year);
+	if (!month_name) return;
+
+	for (i = 0; i < bin->cb; i+= 4) {
+		event_start = (bin->lpb[i + 1] << 8) | bin->lpb[i];
+		event_end = (bin->lpb[i + 3] << 8) | bin->lpb[i + 2];
+
+		for (hour = 0; hour < 24; hour++) {
+			if (!((event_start - (60 * hour)) % 1440)) {
+				day = ((event_start - (60 * hour)) / 1440) + 1;
+				last = event_end - event_start;
+#if defined (__FreeBSD__)
+				DEBUG(0, ("%s %u %s %u at %u hours and lasts ", sep ? sep : "", day, month_name, year, hour));
+#else
+				DEBUG(0, ("%s %u %s %u at %u hours and lasts ", sep ? sep : "", day, month_name, year, hour + daylight));
+#endif
+				if (last < 60) {
+					DEBUG(0, ("%u minutes\n", last));
+				} else {
+					hours = last / 60;
+					minutes = last - hours * 60;
+					if (minutes > 0) {
+						DEBUG(0, ("%u hours and %u minutes\n", hours, minutes));
+					} else {
+						DEBUG(0, ("%u hours\n", hours));
+					}
+				}
+			}
+		}
+		
+	}	
+}

Added: trunk/openchange/libmapi/mapidump.h
===================================================================
--- trunk/openchange/libmapi/mapidump.h	                        (rev 0)
+++ trunk/openchange/libmapi/mapidump.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,42 @@
+/*
+   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/>.
+ */
+
+#ifndef __MAPIDUMP_H__
+#define	__MAPIDUMP_H__
+
+struct mdump_msgflags {
+	uint16_t	flag;
+	const char	*value;
+};
+
+struct mdump_msgflags mdump_msgflags[] = {
+	{0x1,	"MSGFLAG_READ"},
+	{0x2,	"MSGFLAG_UNMODIFIED"},
+	{0x4,	"MSGFLAG_SUBMIT"},
+	{0x8,	"MSGFLAG_UNSENT"},
+	{0x10,	"MSGFLAG_HASATTACH"},
+	{0x20,	"MSGFLAG_FROMME"},
+	{0x40,	"MSGFLAG_ASSOCIATED"},
+	{0x80,	"MSGFLAG_RESEND"},
+	{0x100,	"MSGFLAG_RN_PENDING"},
+	{0x200,	"MSGFLAG_NRN_PENDING"},
+	{0, NULL}
+};
+
+#endif	/* __MAPIDUMP_H__ */

Added: trunk/openchange/libmapi/nspi.c
===================================================================
--- trunk/openchange/libmapi/nspi.c	                        (rev 0)
+++ trunk/openchange/libmapi/nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1152 @@
+/*
+   OpenChange NSPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005 - 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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange_c.h>
+#include <param.h>
+#include <credentials.h>
+
+
+/**
+   \file nspi.c
+
+   \brief Name Service Provider (NSPI) stack functions
+ */
+
+
+/**
+   \details Initialize the STAT structure and set common STAT parameters
+
+   \param mem_ctx pointer to the memory context
+   \param CodePage the CodePage value to set in the STAT structure
+   \param TemplateLocale the Locale for the STAT TemplateLocale parameter
+   \param SortLocale the Locale for the STAT SortLocal parameter
+ */
+static struct STAT *nspi_set_STAT(TALLOC_CTX *mem_ctx, 
+				  uint32_t CodePage,
+				  uint32_t TemplateLocale, 
+				  uint32_t SortLocale)
+{
+	struct STAT		*pStat;
+
+	/* Sanity Checks */
+	if (!CodePage || !TemplateLocale || !SortLocale) {
+		return NULL;
+	}
+
+	pStat = talloc_zero(mem_ctx, struct STAT);
+	pStat->SortType = SortTypeDisplayName;
+	pStat->CodePage = CodePage;
+	pStat->TemplateLocale = TemplateLocale;
+	pStat->SortLocale = SortLocale;
+
+	return pStat;
+}
+
+
+/**
+   \details Initiates a session between a client and the NSPI server.
+
+   \param mem_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
+   \param language the language to set in the STAT structure
+   \param method the method to set in the STAT structure
+
+   \return Allocated pointer to a nspi_context structure on success,
+   otherwise NULL
+ */
+_PUBLIC_ struct nspi_context *nspi_bind(TALLOC_CTX *mem_ctx, 
+					struct dcerpc_pipe *p,
+					struct cli_credentials *cred, 
+					uint32_t codepage,
+					uint32_t language, 
+					uint32_t method)
+{
+	struct NspiBind		r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	struct nspi_context	*ret;
+	struct GUID		guid;
+
+	/* Sanity checks */
+	if (!p) return NULL;
+	if (!cred) return NULL;
+
+	ret = talloc(mem_ctx, struct nspi_context);
+	ret->rpc_connection = p;
+	ret->mem_ctx = mem_ctx;
+	ret->cred = cred;
+	ret->version = 0;
+
+	/* Sanity Checks */
+	if (!(ret->pStat = nspi_set_STAT(mem_ctx, codepage, language, method))) {
+		talloc_free(ret);
+		return NULL;
+	}
+
+	r.in.dwFlags = 0;
+
+	r.in.pStat = ret->pStat;
+	r.in.pStat->ContainerID = 0x0;
+
+	r.in.mapiuid = talloc(mem_ctx, struct GUID);
+	memset(r.in.mapiuid, 0, sizeof(struct GUID));
+	
+	r.out.mapiuid = &guid;
+
+	r.in.mapiuid = talloc(mem_ctx, struct GUID);
+	memset(r.in.mapiuid, 0, sizeof(struct GUID));
+
+	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);
+		return NULL;
+	}
+	
+	return ret;
+}
+
+
+/**
+   \details Destructor for the NSPI context. Call the NspiUnbind
+   function.
+   
+   \param data generic pointer to data with mapi_provider information
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+
+int nspi_disconnect_dtor(void *data)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_provider	*provider = (struct mapi_provider *) data;
+
+	retval = nspi_unbind(provider->ctx);
+	return retval;
+}
+
+
+/**
+   \details Destroys the context handle
+
+   \param nspi_ctx pointer to the NSPI connection context
+
+   \return return 1 on success or 2 if the input context is NULL
+ */
+_PUBLIC_ enum MAPISTATUS nspi_unbind(struct nspi_context *nspi_ctx)
+{
+	struct NspiUnbind	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	r.in.handle = r.out.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0;
+
+	status = dcerpc_NspiUnbind(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF((retval != 1) && !MAPI_STATUS_IS_OK(NT_STATUS_V(status)), retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Updates the STAT block representing position in a table to
+   reflect positioning changes requested by the client.
+
+   \param nspi_ctx pointer to the NSPI connection context
+   \param plDelta pointer to an unsigned long indicating movement
+   within the address book container specified by the input parameter
+   pStat.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_UpdateStat(struct nspi_context *nspi_ctx, 
+					 uint32_t *plDelta)
+{
+	struct NspiUpdateStat		r;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!plDelta, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.plDelta = plDelta;
+
+	r.out.pStat = nspi_ctx->pStat;
+	r.out.plDelta = r.in.plDelta;
+
+	status = dcerpc_NspiUpdateStat(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a number of Rows from a specified table.
+
+   \param nspi_ctx pointer to the NSPI connection 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
+   table
+   \param count the number of rows requested
+   \param ppRows pointer on pointer to the the rows returned by the
+   server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_QueryRows(struct nspi_context *nspi_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;
+	struct STAT			*pStat;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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;
+		/* We set CurrentRec to the first entry */
+		r.in.pStat->CurrentRec = MIds->aulPropTag[0];
+	} else {
+		r.in.dwETableCount = 0;
+		r.in.lpETable = NULL;
+	}
+
+	r.in.Count = count;	
+ 	r.in.pPropTags = pPropTags;
+
+	pStat = talloc(mem_ctx, struct STAT);
+	r.out.pStat = pStat;
+
+	r.out.ppRows = ppRows;
+
+	status = dcerpc_NspiQueryRows(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	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;
+
+}
+
+
+/**
+   \details Searches for and sets the logical position in a specific
+   table to the first entry greater than or equal to a specified
+   value. Optionally, it might also return information about rows in
+   the table.
+
+   \param nspi_ctx pointer to the NSPI connection 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
+   that the client wants to be returned for each row returned.
+   \param pMIds pointer to a list of Mid that comprise a restricted
+   address book container
+   \param pRows pointer to pointer to a SRowSet structure holding the
+   rows returned by the server
+
+   SortType can take the following values:
+   -# SortTypeDisplayName
+   -# SortTypePhoneticDisplayName
+
+   If pTarget property tag is not set accordingly to SortType, the
+   function returns MAPI_E_INVALID_PARAMETER. Possible values are:
+   -# SortType set to SortTypeDisplayName and pTarget property tag set
+      to PR_DISPLAY_NAME or PR_DISPLAY_UNICODE
+   -# SortType set to SortTypePhoneticDisplayName and pTarget property
+      tag set to PR_EMS_AB_PHONETIC_DISPLAY_NAME or
+      PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_SeekEntries(struct nspi_context *nspi_ctx,
+					  enum TableSortOrders SortType,
+					  struct SPropValue *pTarget,
+					  struct SPropTagArray *pPropTags,
+					  struct SPropTagArray *pMIds,
+					  struct SRowSet **pRows)
+{
+	struct NspiSeekEntries		r;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	struct STAT			*pStat;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!pTarget, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!pRows, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(((SortType != SortTypeDisplayName) 
+			&& (SortType != SortTypePhoneticDisplayName)), 
+		       MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Sanity Checks on SortType and pTarget combination */
+	OPENCHANGE_RETVAL_IF(((SortType == SortTypeDisplayName) && 
+			(pTarget->ulPropTag != PR_DISPLAY_NAME) && 
+			(pTarget->ulPropTag != PR_DISPLAY_NAME_UNICODE)),
+		       MAPI_E_INVALID_PARAMETER, NULL);
+
+	OPENCHANGE_RETVAL_IF(((SortType == SortTypePhoneticDisplayName) && 
+			(pTarget->ulPropTag != PR_EMS_AB_PHONETIC_DISPLAY_NAME) &&
+			(pTarget->ulPropTag != PR_EMS_AB_PHONETIC_DISPLAY_NAME_UNICODE)),
+		       MAPI_E_INVALID_PARAMETER, NULL);
+
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.pStat->SortType = SortType;
+	r.in.pTarget = pTarget;
+
+	if (pMIds && pMIds->cValues) {
+		r.in.lpETable = pMIds;
+	} else {
+		r.in.lpETable = NULL;
+	}
+
+	r.in.pPropTags = pPropTags;
+
+	r.out.pRows = pRows;
+
+	pStat = talloc(nspi_ctx->mem_ctx, struct STAT);
+	r.out.pStat = pStat;
+
+	status = dcerpc_NspiSeekEntries(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, pStat);
+	OPENCHANGE_RETVAL_IF(retval, retval, pStat);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns an explicit table.
+
+   \param nspi_ctx pointer to the NSPI connection 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
+   rows returned by the server
+   \param ppOutMIds pointer to pointer to a list of MId that comprise
+   a restricted address book container
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetMatches(struct nspi_context *nspi_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;
+	struct STAT			*pStat;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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;
+	
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.pStat->ContainerID = 0x0;
+	r.in.pStat->CurrentRec = 0x0;
+	r.in.pStat->Delta = 0x0;
+	r.in.pStat->NumPos = 0x0;
+	r.in.pStat->TotalRecs = 0x0;
+
+	r.in.pReserved = NULL;
+	r.in.Reserved2 = 0;
+	r.in.Filter = Filter;
+	r.in.lpPropName = NULL;
+	r.in.ulRequested = 5000;
+	r.in.pPropTags = pPropTags;
+
+	pStat = talloc(mem_ctx, struct STAT);
+	r.out.pStat = pStat;
+	r.out.ppOutMIds = ppOutMIds;
+	r.out.ppRows = ppRows;
+
+	status = dcerpc_NspiGetMatches(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Applies a sort order to the objects in a restricted
+   address book container
+
+   \param nspi_ctx pointer to the NSPI connection context
+   \param SortType the table sort order to use
+   \param pInMIds pointer on a list of MIds that comprise a
+   restricted addess book container
+   \param ppMIds pointer on pointer to the returned list of MIds that
+   comprise a restricted addess book container.
+
+   SortType can take the following values:
+   -# SortTypeDisplayName
+   -# SortTypePhoneticDisplayName
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_ResortRestriction(struct nspi_context *nspi_ctx,
+						enum TableSortOrders SortType,
+						struct SPropTagArray *pInMIds,
+						struct SPropTagArray **ppMIds)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct NspiResortRestriction	r;
+	enum MAPISTATUS			retval;
+	NTSTATUS			status;
+	struct SPropTagArray		*ppInMIds = NULL;
+	struct STAT			*pStat = NULL;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!pInMIds, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ppMIds, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Sanity check on SortType */
+	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;
+	r.in.pStat->SortType = SortType;
+	r.in.pInMIds = pInMIds;
+	r.in.ppMIds = &ppInMIds;
+
+	pStat = talloc_zero(mem_ctx, struct STAT);
+	r.out.pStat = pStat;
+	r.out.ppMIds = ppMIds;
+
+	status = dcerpc_NspiResortRestriction(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Maps a set of DN to a set of MId
+
+   \param nspi_ctx pointer to the NSPI connection 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
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_DNToMId(struct nspi_context *nspi_ctx, 
+				      struct StringsArray_r *pNames,
+				      struct SPropTagArray **ppMIds)
+{
+	struct NspiDNToMId	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0;
+	r.in.pNames = pNames;
+
+	r.out.ppMIds = ppMIds;
+
+	status = dcerpc_NspiDNToMId(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL)
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a list of all the properties that have values on
+   the specified object
+
+   \param nspi_ctx pointer to the NSPI connection 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
+   \param ppPropTags pointer on pointer to the list of property tags
+   associated to the object.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetPropList(struct nspi_context *nspi_ctx,
+					  bool WantObject,
+					  uint32_t dwMId,
+					  struct SPropTagArray **ppPropTags)
+{
+	struct NspiGetPropList	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!ppPropTags, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	r.in.handle = &nspi_ctx->handle;
+	r.in.dwFlags = (WantObject == true) ? 0x0 : fSkipObjects;
+	r.in.dwMId = dwMId;
+	r.in.CodePage = nspi_ctx->pStat->CodePage;
+	
+	r.out.ppPropTags = ppPropTags;
+
+	status = dcerpc_NspiGetPropList(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+
+/**
+   \details Returns an address book row containing a set of the
+   properties and values that exists on an object
+
+   \param nspi_ctx pointer to the NSPI connection 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
+   \param SRowSet pointer on pointer to the row returned by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetProps(struct nspi_context *nspi_ctx, 
+				       struct SPropTagArray *pPropTags, 
+				       struct SPropTagArray *MId,
+				       struct SRowSet **SRowSet)
+
+{
+	struct NspiGetProps	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	struct SRow		*ppRows;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!MId, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!MId->cValues, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.dwFlags = 0;
+
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.pStat->CurrentRec = MId->aulPropTag[0];
+	r.in.pStat->Delta = 0x0;
+	r.in.pStat->NumPos = 0x0;
+	r.in.pStat->TotalRecs = 0x0;
+
+ 	r.in.pPropTags = pPropTags;
+
+	ppRows = talloc(nspi_ctx->mem_ctx, struct SRow);
+	r.out.ppRows = &ppRows;
+
+	status = dcerpc_NspiGetProps(nspi_ctx->rpc_connection, nspi_ctx->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->ulAdrEntryPad = ppRows->ulAdrEntryPad;
+	SRowSet[0]->aRow->cValues = ppRows->cValues;
+	SRowSet[0]->aRow->lpProps = ppRows->lpProps;
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Compares the position in an address book container of two
+   objects identified by MId and returns the value of the comparison
+
+   \param nspi_ctx pointer to the NSPI connection context
+   \param MId1 the first MId to compare
+   \param MId2 the second MId to compare
+   \param plResult pointer to the value of the comparison
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS nspi_CompareMIds(struct nspi_context *nspi_ctx,
+					  uint32_t MId1, uint32_t MId2,
+					  uint32_t *plResult)
+{
+	struct NspiCompareMIds	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!plResult, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.MId1 = MId1;
+	r.in.MId2 = MId2;
+
+	r.out.plResult = plResult;
+
+	status = dcerpc_NspiCompareMIds(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Modify the properties of an object in the address book
+   
+   \param nspi_ctx pointer to the NSPI connection context
+   \param MId the MId of the address book object
+   \param pPropTags pointer to the list of properties to be modified
+   on the object
+   \param pRow Contains an address book row
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_ModProps(struct nspi_context *nspi_ctx,
+				       uint32_t MId,
+				       struct SPropTagArray *pPropTags,
+				       struct SRow *pRow)
+{
+	struct NspiModProps	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!pPropTags, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!pRow, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+	r.in.pStat = nspi_ctx->pStat;
+
+	if (MId) {
+		r.in.pStat->CurrentRec = MId;
+	}
+
+	r.in.pPropTags = pPropTags;
+	r.in.pRow = pRow;
+
+	status = dcerpc_NspiModProps(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+
+/**
+   \details Returns the rows of a special table to the client. The
+   special table can be a Hierarchy Table or an Address Creation Table
+
+   \param nspi_ctx pointer to the NSPI connection 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
+
+   Possible values for Type:
+   -# NspiAddressCreationTemplates to access an Address Creation Table
+   -# NspiUnicodeStrings for strings to be returned in Unicode
+
+   If NspiAddressCreationTemplates is not set, then
+   NspiGetSpecialTable will automatically fetch the Hierarchy Table.
+
+   If NspiAddressCreationTemplates is set, then NspiUnicodeStrings is
+   ignored.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetSpecialTable(struct nspi_context *nspi_ctx, 
+					      uint32_t Type,
+					      struct SRowSet **ppRows)
+{
+	struct NspiGetSpecialTable	r;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(((Type != 0x0) && (Type != 0x2) && (Type != 0x4)),
+		       MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ppRows, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.dwFlags = Type;
+
+	r.in.pStat = nspi_ctx->pStat;
+	r.in.lpVersion = &nspi_ctx->version;
+
+	r.out.lpVersion = &nspi_ctx->version;
+	r.out.ppRows = ppRows;
+
+	status = dcerpc_NspiGetSpecialTable(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns information about template objects in the address
+   book.
+
+   \param nspi_ctx pointer to the NSPI 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
+   \param ppData pointer on pointer to the data requested
+
+   Possible values for dwFlags:
+   -# TI_TEMPLATE to return the template
+   -# TI_SCRIPT to return the script associated to the template
+   -# TI_EMT to return the e-mail type associated to the template
+   -# TI_HELPFILE_NAME to return the help file associated to the
+      template
+   -# TI_HELPFILE_CONTENTS to return the contents of the help file
+      associated to the template
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetTemplateInfo(struct nspi_context *nspi_ctx,
+					      uint32_t dwFlags,
+					      uint32_t ulType,
+					      char *pDN,
+					      struct SRow **ppData)
+{
+	struct NspiGetTemplateInfo	r;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!ppData, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.dwFlags = dwFlags;
+	r.in.ulType = ulType;
+	r.in.pDN = pDN;
+	r.in.dwCodePage = nspi_ctx->pStat->CodePage;
+	r.in.dwLocaleID = nspi_ctx->pStat->TemplateLocale;
+	
+	r.out.ppData = ppData;
+
+	status = dcerpc_NspiGetTemplateInfo(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+	
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Modifies the values of a specific property of a specific
+   row in the address book. This function only applies only to rows
+   that support the PT_OBJECT Property Type.
+
+   \param nspi_ctx pointer to the NSPI connection context
+   \param Delete boolean value defining whether the server must remove
+   all values specified by the input parameter lpEntryIDs from the
+   property specified by ulPropTag
+   \param ulPropTag property tag of the property the client wishes to
+   modify
+   \param MId the MId of the address book object
+   \param lpEntryIds array of BinaryArray_r structures intended to be
+   modified or deleted
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_ModLinkAtt(struct nspi_context *nspi_ctx,
+					 bool Delete,
+					 uint32_t ulPropTag,
+					 uint32_t MId,
+					 struct BinaryArray_r *lpEntryIds)
+{
+	struct NspiModLinkAtt	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(((ulPropTag & 0xFFFF) != PT_OBJECT), MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpEntryIds, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!lpEntryIds->cValues, MAPI_E_INVALID_PARAMETER, NULL)
+
+	r.in.handle = &nspi_ctx->handle;
+	/* FIXME: need to find fDelete value first */
+	r.in.dwFlags = (Delete == true) ? 0x1 : 0x0; 
+	r.in.ulPropTag = ulPropTag;
+	r.in.MId = MId;
+	r.in.lpEntryIds = lpEntryIds;
+
+	status = dcerpc_NspiModLinkAtt(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a list of all the properties the NSPI server is
+   aware off.
+
+   \param nspi_ctx pointer to the NSPI connection 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,
+					   bool WantUnicode,
+					   struct SPropTagArray **ppColumns)
+{
+	struct NspiQueryColumns	r;
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!ppColumns, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+	r.in.dwFlags = (WantUnicode == true) ? NspiUnicodeProptypes : 0x0;
+	
+	r.out.ppColumns = ppColumns;
+
+	status = dcerpc_NspiQueryColumns(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Returns a list of property names for a set of proptags
+
+   \param nspi_ctx pointer on the NSPI connection text
+   \param lpGuid the property set about which the client is requesting
+   information
+   \param pPropTags pointer to the proptags list
+   \param ppReturnedPropTags pointer on pointer to the list of
+   all the proptags in the property set specified in lpGuid
+   \param ppNames pointer on pointer to the list of property names
+   returned by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetNamesFromIDs(struct nspi_context *nspi_ctx,
+					      struct FlatUID_r *lpGuid,
+					      struct SPropTagArray *pPropTags,
+					      struct SPropTagArray **ppReturnedPropTags,
+					      struct PropertyNameSet_r **ppNames)
+{
+	struct NspiGetNamesFromIDs	r;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!ppReturnedPropTags, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ppNames, MAPI_E_INVALID_PARAMETER, NULL);
+
+	r.in.handle = &nspi_ctx->handle;
+	r.in.Reserved = 0x0;
+	r.in.lpGuid = lpGuid;
+	r.in.pPropTags = pPropTags;
+
+	r.out.ppReturnedPropTags = ppReturnedPropTags;
+	r.out.ppNames = ppNames;
+
+	status = dcerpc_NspiGetNamesFromIDs(nspi_ctx->rpc_connection, nspi_ctx->mem_ctx, &r);
+	retval = r.out.result;
+	OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), retval, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the Property IDs associated with property names
+   from the NSPI server.
+
+   \param nspi_ctx pointer on the NSPI connection context
+   \param VerifyNames boolean value defining whether the NSPI server
+   must verify that all client specified names are recognized by the
+   server
+   \param cNames count of PropertyName_r entries
+   \param ppNames pointer to a PropertyName_r structure with the list of
+   property tags supplied by the client
+   \param ppPropTags pointer on pointer to the list of proptags
+   returned by the server
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_GetIDsFromNames(struct nspi_context *nspi_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;
+	uint32_t			i;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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;
+	r.in.cPropNames = cNames;
+
+	r.in.ppNames = talloc_array(mem_ctx, struct PropertyName_r *, cNames);
+	for (i = 0; i < cNames; i++) {
+		r.in.ppNames[i] = &ppNames[i];
+	}
+
+	r.out.ppPropTags = ppPropTags;
+	
+	status = dcerpc_NspiGetIDsFromNames(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Takes a set of string values in an 8-bit character set and
+   performs ANR on those strings
+
+   \param nspi_ctx pointer on the NSPI connection 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
+   row returned
+   \param pppRows pointer on pointer on pointer to the rows returned
+   by the server
+   \param pppMIds pointer on pointer on pointer to the MIds matching
+   the array of strings
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_ResolveNames(struct nspi_context *nspi_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;
+	enum MAPISTATUS		retval;
+	uint32_t		count;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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);
+
+	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;
+	r.in.Reserved = 0;
+	r.in.pPropTags = pPropTags;
+	
+	paStr = talloc(mem_ctx, struct StringsArray_r);
+	paStr->Count = count;
+	paStr->Strings = usernames;
+	r.in.paStr = paStr;
+
+	r.out.ppMIds = *pppMIds;
+	r.out.ppRows = *pppRows;
+
+	status = dcerpc_NspiResolveNames(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Takes a set of string values in the Unicode character set
+   and performs ANR on those strings
+
+   \param nspi_ctx pointer on the NSPI connection 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
+   row returned
+   \param pppRows pointer on pointer on pointer to the rows returned
+   by the server
+   \param pppMIds pointer on pointer on pointer to the MIds matching
+   the array of strings
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS nspi_ResolveNamesW(struct nspi_context *nspi_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;
+	enum MAPISTATUS			retval;
+	uint32_t			count;
+
+	OPENCHANGE_RETVAL_IF(!nspi_ctx, MAPI_E_NOT_INITIALIZED, 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);
+
+	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;
+	r.in.Reserved = 0;
+	r.in.pPropTags = pPropTags;
+
+	paWStr = talloc(mem_ctx, struct WStringsArray_r);
+	paWStr->Count = count;
+	paWStr->Strings = usernames;
+	r.in.paWStr = paWStr;
+
+	r.out.ppMIds = *pppMIds;
+	r.out.ppRows = *pppRows;
+
+	status = dcerpc_NspiResolveNamesW(nspi_ctx->rpc_connection, nspi_ctx->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);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/nspi.h
===================================================================
--- trunk/openchange/libmapi/nspi.h	                        (rev 0)
+++ trunk/openchange/libmapi/nspi.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,43 @@
+/*
+   OpenChange NSPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005.
+
+   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 __NSPI_H__
+#define	__NSPI_H__
+
+struct nspi_context {
+	struct dcerpc_pipe	*rpc_connection;
+	struct policy_handle	handle;
+	TALLOC_CTX		*mem_ctx;
+	struct cli_credentials	*cred;
+	struct STAT		*pStat;
+	struct mapi_profile	*profile;
+	struct SRowSet		*rowSet;
+	char			*org;
+	char			*org_unit;
+	char			*servername;
+	uint32_t		version;
+};
+
+#define	ORG		"/o="
+#define	ORG_UNIT	"/ou="
+#define	SERVER_DN	"/o=%s/ou=%s/cn=Configuration/cn=Servers/cn=%s"
+#define	SERVERNAME	"/cn=Servers/cn="
+#define	RECIPIENT_DN	"/o=%s/ou=%s/cn=Recipients/cn=%s"
+
+#endif /* __NSPI_H__ */

Added: trunk/openchange/libmapi/property.c
===================================================================
--- trunk/openchange/libmapi/property.c	                        (rev 0)
+++ trunk/openchange/libmapi/property.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,847 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005 - 2008.
+   Copyright (C) Gregory Schiro 2006
+
+   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 <libmapi/proto_private.h>
+#include <libmapi/mapitags.h>
+#include <gen_ndr/ndr_property.h>
+#include <param.h>
+
+/**
+   \file property.c
+
+   \brief Functions for manipulating MAPI properties
+ */
+
+_PUBLIC_ struct SPropTagArray *set_SPropTagArray(TALLOC_CTX *mem_ctx, 
+						 uint32_t PropCount, ...)
+{
+	struct SPropTagArray	*SPropTagArray;
+	va_list			ap;
+	uint32_t		i;
+	uint32_t		*aulPropTag;
+
+	aulPropTag = talloc_array(mem_ctx, uint32_t, PropCount);
+
+	va_start(ap, PropCount);
+	for (i = 0; i < PropCount; i++) {
+		aulPropTag[i] = va_arg(ap, int);
+	}
+	va_end(ap);
+
+	SPropTagArray = talloc(mem_ctx, struct SPropTagArray);
+	SPropTagArray->aulPropTag = aulPropTag;
+	SPropTagArray->cValues = PropCount;
+	return SPropTagArray;
+}
+
+/**
+   \details Add a property tag to an existing properties array
+
+   \param mem_ctx talloc memory context to use for allocation
+   \param SPropTagArray existing properties array to add to
+   \param aulPropTag the property tag to add
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+   \note Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+   - MAPI_E_INVALID_PARAMETER: SPropTagArray parameter is not correctly set
+*/
+_PUBLIC_ enum MAPISTATUS SPropTagArray_add(TALLOC_CTX *mem_ctx, 
+					   struct SPropTagArray *SPropTagArray, 
+					   uint32_t aulPropTag)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!SPropTagArray, MAPI_E_INVALID_PARAMETER, NULL);
+	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[SPropTagArray->cValues - 1] = aulPropTag;
+	SPropTagArray->aulPropTag[SPropTagArray->cValues] = 0;
+
+	return MAPI_E_SUCCESS;
+}
+
+_PUBLIC_ const void *get_SPropValue(struct SPropValue *lpProps, 
+				    uint32_t ulPropTag)
+{
+	uint32_t	i;
+
+	for (i = 0; lpProps[i].ulPropTag; i++) {
+		if (ulPropTag == lpProps[i].ulPropTag) {
+			return get_SPropValue_data(&lpProps[i]);
+		}
+	}
+	return NULL;
+}
+
+_PUBLIC_ struct SPropValue *get_SPropValue_SRowSet(struct SRowSet *RowSet, 
+						   uint32_t ulPropTag)
+{
+	uint32_t	i;
+	uint32_t	j;
+
+	/* Sanity Checks */
+	if (!RowSet) return NULL;
+
+	for (i = 0; i != RowSet->cRows; i++) {
+		for (j = 0; j < RowSet->aRow[i].cValues; j++) {
+			if (ulPropTag == RowSet->aRow[i].lpProps[j].ulPropTag) {
+				return (&RowSet->aRow[i].lpProps[j]);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+_PUBLIC_ const void *get_SPropValue_SRowSet_data(struct SRowSet *RowSet,
+						 uint32_t ulPropTag)
+{
+	struct SPropValue *lpProp;
+
+	lpProp = get_SPropValue_SRowSet(RowSet, ulPropTag);
+	return get_SPropValue(lpProp, ulPropTag);
+}
+
+_PUBLIC_ enum MAPISTATUS set_default_error_SPropValue_SRow(struct SRow *aRow, uint32_t ulPropTag, void *data)
+{
+	uint32_t	i;
+
+	for (i = 0; i < aRow->cValues; i++) {
+		if ((ulPropTag & 0xFFFF0000) == (aRow->lpProps[i].ulPropTag & 0xFFFF0000) &&
+		    (aRow->lpProps[i].ulPropTag & 0xFFFF) == 0xA) {
+			set_SPropValue_proptag(&(aRow->lpProps[i]), ulPropTag, data);
+			return MAPI_E_SUCCESS;
+		}
+	}
+	return MAPI_E_NOT_FOUND;
+}
+
+_PUBLIC_ struct SPropValue *get_SPropValue_SRow(struct SRow *aRow,
+						uint32_t ulPropTag)
+{
+	uint32_t	i;
+
+	for (i = 0; i < aRow->cValues; i++) {
+		if (ulPropTag == aRow->lpProps[i].ulPropTag) {
+			return (&aRow->lpProps[i]);
+		}
+	}
+
+	return NULL;
+}
+
+_PUBLIC_ const void *get_SPropValue_SRow_data(struct SRow *aRow,
+					      uint32_t ulPropTag)
+{
+	struct SPropValue *lpProp;
+
+	lpProp = get_SPropValue_SRow(aRow, ulPropTag);
+	return get_SPropValue(lpProp, ulPropTag);
+}
+
+/*
+  Create a MAPITAGS array from a SRow entry
+ */
+
+enum MAPITAGS *get_MAPITAGS_SRow(TALLOC_CTX *mem_ctx, struct SRow *aRow)
+{
+	enum MAPITAGS	*mapitags;
+	uint32_t	count, idx;
+
+	mapitags = talloc_array(mem_ctx, enum MAPITAGS, aRow->cValues + 1);
+
+	for (count = 0, idx=0; count < aRow->cValues; count++) {
+		if ((aRow->lpProps[count].ulPropTag & 0xFFFF) != PT_ERROR) {
+			mapitags[idx] = aRow->lpProps[count].ulPropTag;
+			idx++;
+		}
+	}
+	mapitags[idx] = 0;
+	return mapitags;
+}
+
+/*
+  Remove MAPITAGS entries from a MAPITAGS array
+*/
+
+uint32_t MAPITAGS_delete_entries(enum MAPITAGS *mapitags, uint32_t final_count, uint32_t PropCount, ...)
+{
+	va_list			ap;
+	uint32_t		i,j;
+	uint32_t		aulPropTag;
+	uint32_t		count = 0;
+	
+	va_start(ap, PropCount);
+	for (i = 0; i != PropCount; i++) {
+		aulPropTag = va_arg(ap, uint32_t);
+		for (count = 0; mapitags[count]; count++) {
+			if (aulPropTag == (uint32_t)mapitags[count]) {
+				final_count -= 1;
+				for (j = count; mapitags[j]; j++) {
+					mapitags[j] = (mapitags[j+1]) ? mapitags[j+1] : 0;
+				}
+			}
+		}
+	}
+	va_end(ap);
+
+	return final_count;
+}
+
+_PUBLIC_ const void *find_SPropValue_data(struct SRow *aRow, uint32_t mapitag)
+{
+	uint32_t i;
+
+	for (i = 0; i < aRow->cValues; i++) {
+		if (aRow->lpProps[i].ulPropTag == mapitag) {
+			return get_SPropValue_data(&(aRow->lpProps[i]));
+		}
+	}
+	return NULL;
+}
+
+_PUBLIC_ const void *find_mapi_SPropValue_data(
+					struct mapi_SPropValue_array *properties, uint32_t mapitag)
+{
+	uint32_t i;
+
+	for (i = 0; i < properties->cValues; i++) {
+		if (properties->lpProps[i].ulPropTag == mapitag) {
+			return get_mapi_SPropValue_data(&properties->lpProps[i]);
+		}
+	}
+	return NULL;
+}
+
+_PUBLIC_ const void *get_mapi_SPropValue_data(struct mapi_SPropValue *lpProp)
+{
+	if (lpProp->ulPropTag == 0) {
+		return NULL;
+	}
+	switch(lpProp->ulPropTag & 0xFFFF) {
+	case PT_BOOLEAN:
+		return (const void *)(uint8_t *)&lpProp->value.b;
+	case PT_I2: /* Equivalent to PT_SHORT */
+		return (const void *)(uint16_t *)&lpProp->value.i;
+	case PT_LONG: /* Equivalent to PT_I4 */
+		return (const void *)&lpProp->value.l;
+	case PT_DOUBLE:
+		return (const void *)&lpProp->value.dbl;
+	case PT_I8:
+		return (const void *)&lpProp->value.d;
+	case PT_SYSTIME:
+		return (const void *)(struct FILETIME *)&lpProp->value.ft;
+	case PT_ERROR:
+		return (const void *)&lpProp->value.err;
+	case PT_STRING8:
+		return (const void *)lpProp->value.lpszA;
+	case PT_UNICODE:
+		return (const void *)lpProp->value.lpszW;
+	case PT_BINARY:
+		return (const void *)(struct SBinary_short *)&lpProp->value.bin;
+	case PT_MV_LONG:
+		return (const void *)(struct mapi_MV_LONG_STRUCT *)&lpProp->value.MVl;
+	case PT_MV_STRING8:
+		return (const void *)(struct mapi_SLPSTRArray *)&lpProp->value.MVszA;
+	case PT_MV_BINARY:
+		return (const void *)(struct mapi_SBinaryArray *)&lpProp->value.MVbin;
+	default:
+		return NULL;
+	}
+}
+
+_PUBLIC_ const void *get_SPropValue_data(struct SPropValue *lpProps)
+{
+	if (lpProps->ulPropTag == 0) {
+		return NULL;
+	}
+
+	switch(lpProps->ulPropTag & 0xFFFF) {
+	case PT_SHORT:
+		return (const void *)&lpProps->value.i;
+	case PT_BOOLEAN:
+		return (const void *)&lpProps->value.b;
+	case PT_I8:
+		return (const void *)&lpProps->value.d;
+	case PT_STRING8:
+		return (const void *)lpProps->value.lpszA;
+	case PT_UNICODE:
+		return (const void *)lpProps->value.lpszW;
+	case PT_SYSTIME:
+		return (const void *)(struct FILETIME *)&lpProps->value.ft;
+	case PT_ERROR:
+		return (const void *)&lpProps->value.err;
+	case PT_LONG:
+		return (const void *)&lpProps->value.l;
+	case PT_DOUBLE:
+		return (const void *)&lpProps->value.dbl;
+	case PT_CLSID:
+		return (const void *)lpProps->value.lpguid;
+	case PT_BINARY:
+		return (const void *)&lpProps->value.bin;
+	case PT_MV_SHORT:
+		return (const void *)(struct ShortArray_r *)&lpProps->value.MVi;
+	case PT_MV_LONG:
+		return (const void *)(struct LongArray_r *)&lpProps->value.MVl;
+	case PT_MV_STRING8:
+		return (const void *)(struct StringArray_r *)&lpProps->value.MVszA;
+	case PT_MV_UNICODE:
+		return (const void *)(struct WStringArray_r *)&lpProps->value.MVszW;
+	case PT_MV_BINARY:
+		return (const void *)(struct BinaryArray_r *)&lpProps->value.MVbin;
+	case PT_MV_SYSTIME:
+		return (const void *)(struct DateTimeArray_r *)&lpProps->value.MVft;
+	case PT_NULL:
+		return (const void *)&lpProps->value.null;
+	default:
+		return NULL;
+	}
+}
+
+_PUBLIC_ bool set_SPropValue_proptag(struct SPropValue *lpProps, uint32_t aulPropTag, const void *data)
+{
+	lpProps->ulPropTag = aulPropTag;
+	lpProps->dwAlignPad = 0x0;
+
+	return (set_SPropValue(lpProps, data));
+}
+
+_PUBLIC_ struct SPropValue *add_SPropValue(TALLOC_CTX *mem_ctx, struct SPropValue *lpProps, uint32_t *cValues, uint32_t aulPropTag, const void * data)
+{
+	lpProps = talloc_realloc(mem_ctx, lpProps, struct SPropValue, *cValues + 2);
+
+	set_SPropValue_proptag(&lpProps[*cValues], aulPropTag, data);
+	*cValues = *cValues + 1;
+
+	return lpProps;
+}
+/*
+  TODO: should this be public?
+*/
+_PUBLIC_ bool set_SPropValue(struct SPropValue *lpProps, const void *data)
+{
+	if (data == NULL) {
+		lpProps->value.err = MAPI_E_NOT_FOUND;
+		return false;
+	}
+	switch (lpProps->ulPropTag & 0xFFFF) {
+	case PT_SHORT:
+		lpProps->value.i = *((const uint16_t *)data);
+		break;
+	case PT_LONG:
+		lpProps->value.l = *((const uint32_t *)data);
+		break;
+	case PT_I8:
+		lpProps->value.d = *((const uint64_t *)data);
+		break;
+	case PT_BOOLEAN:
+		lpProps->value.b = *((const uint8_t *)data);
+		break;
+	case PT_STRING8:
+		lpProps->value.lpszA = (const char *) data;
+		break;
+	case PT_BINARY:
+		lpProps->value.bin = *((const struct Binary_r *)data);
+		break;
+	case PT_UNICODE:
+		lpProps->value.lpszW = (const char *) data;
+		break;
+	case PT_CLSID:
+		lpProps->value.lpguid = (struct FlatUID_r *) data;
+		break;
+	case PT_SYSTIME:
+		lpProps->value.ft = *((const struct FILETIME *) data);
+		break;
+	case PT_ERROR:
+		lpProps->value.err = *((const uint32_t *)data);
+		break;
+	case PT_MV_SHORT:
+		lpProps->value.MVi = *((const struct ShortArray_r *)data);
+		break;
+	case PT_MV_LONG:
+		lpProps->value.MVl = *((const struct LongArray_r *)data);
+		break;
+	case PT_MV_STRING8:
+		lpProps->value.MVszA = *((const struct StringArray_r *)data);
+		break;
+	case PT_MV_BINARY:
+		lpProps->value.MVbin = *((const struct BinaryArray_r *)data);
+		break;
+	case PT_MV_CLSID:
+		lpProps->value.MVguid = *((const struct FlatUIDArray_r *)data);
+		break;
+	case PT_MV_UNICODE:
+		lpProps->value.MVszW = *((const struct WStringArray_r *)data);
+		break;
+	case PT_MV_SYSTIME:
+		lpProps->value.MVft = *((const struct DateTimeArray_r *)data);
+		break;
+	case PT_NULL:
+		lpProps->value.null = *((const uint32_t *)data);
+		break;
+	case PT_OBJECT:
+		lpProps->value.object = *((const uint32_t *)data);
+		break;
+	default:
+		lpProps->value.err = MAPI_E_NOT_FOUND;
+
+		return false;
+	}
+
+	return true;
+}
+
+_PUBLIC_ uint32_t get_mapi_property_size(struct mapi_SPropValue *lpProp)
+{
+	switch(lpProp->ulPropTag & 0xFFFF) {
+	case PT_BOOLEAN:
+		return sizeof (uint8_t);
+	case PT_I2:
+		return sizeof (uint16_t);
+	case PT_LONG:
+	case PT_ERROR:
+		return sizeof (uint32_t);
+	case PT_DOUBLE:
+	case PT_I8:
+		return sizeof (uint64_t);
+	case PT_STRING8:
+		return strlen(lpProp->value.lpszA) + 1;
+	case PT_UNICODE:
+		return strlen(lpProp->value.lpszW) * 2 + 2;
+	case PT_SYSTIME:
+		return sizeof (struct FILETIME);
+	case PT_BINARY:
+		return (lpProp->value.bin.cb + sizeof(uint16_t));
+	}
+	return 0;
+}
+
+/*
+  convenient function which cast a SPropValue structure in a mapi_SPropValue one and return the associated size
+*/
+
+_PUBLIC_ uint32_t cast_mapi_SPropValue(struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
+{
+	mapi_sprop->ulPropTag = sprop->ulPropTag;
+
+	switch(sprop->ulPropTag & 0xFFFF) {
+	case PT_BOOLEAN:
+		mapi_sprop->value.b = sprop->value.b;
+		return sizeof(uint8_t);
+	case PT_I2:
+		mapi_sprop->value.i = sprop->value.i;
+		return sizeof(uint16_t);
+	case PT_LONG:
+		mapi_sprop->value.l = sprop->value.l;
+		return sizeof(uint32_t);
+	case PT_DOUBLE:
+		mapi_sprop->value.dbl = sprop->value.dbl;
+		return sizeof(uint64_t);
+	case PT_STRING8:
+		mapi_sprop->value.lpszA = sprop->value.lpszA;
+		if (!mapi_sprop->value.lpszA) return 0;
+		return (strlen(sprop->value.lpszA) + 1);
+	case PT_UNICODE:
+		mapi_sprop->value.lpszW = sprop->value.lpszW;
+		if (!mapi_sprop->value.lpszW) return 0;
+		return (strlen(sprop->value.lpszW) * 2 + 2);
+	case PT_SYSTIME:
+		mapi_sprop->value.ft.dwLowDateTime = sprop->value.ft.dwLowDateTime;
+		mapi_sprop->value.ft.dwHighDateTime = sprop->value.ft.dwHighDateTime;
+		return (sizeof (struct FILETIME));
+	case PT_BINARY:
+		mapi_sprop->value.bin.cb = sprop->value.bin.cb;
+		mapi_sprop->value.bin.lpb = sprop->value.bin.lpb;
+		return (mapi_sprop->value.bin.cb + sizeof(uint16_t));
+	case PT_MV_STRING8:
+		{
+			uint32_t	i;
+			uint32_t	size = 0;
+
+			mapi_sprop->value.MVszA.cValues = sprop->value.MVszA.cValues;
+			size += 4;
+
+			mapi_sprop->value.MVszA.strings = talloc_array(global_mapi_ctx->mem_ctx, struct mapi_LPSTR, mapi_sprop->value.MVszA.cValues);
+			for (i = 0; i < mapi_sprop->value.MVszA.cValues; i++) {
+				mapi_sprop->value.MVszA.strings[i].lppszA = sprop->value.MVszA.lppszA[i];
+				size += strlen(mapi_sprop->value.MVszA.strings[i].lppszA) + 1;
+			}
+			return size;
+		}
+	}
+	return 0;
+
+}
+
+/*
+ *
+ */
+_PUBLIC_ uint32_t cast_SPropValue(struct mapi_SPropValue *mapi_sprop, struct SPropValue *sprop)
+{
+	sprop->ulPropTag = mapi_sprop->ulPropTag;
+
+	switch(sprop->ulPropTag & 0xFFFF) {
+	case PT_BOOLEAN:
+		sprop->value.b = mapi_sprop->value.b;
+		return sizeof(uint8_t);
+	case PT_I2:
+		sprop->value.i = mapi_sprop->value.i;
+		return sizeof(uint16_t);
+	case PT_LONG:
+		sprop->value.l = mapi_sprop->value.l;
+		return sizeof(uint32_t);
+	case PT_DOUBLE:
+		sprop->value.dbl = mapi_sprop->value.dbl;
+		return sizeof(uint64_t);
+	case PT_STRING8:
+		sprop->value.lpszA = mapi_sprop->value.lpszA;
+		if (!mapi_sprop->value.lpszA) return 0;
+		return (strlen(sprop->value.lpszA) + 1);
+	case PT_UNICODE:
+		sprop->value.lpszW = mapi_sprop->value.lpszW;
+		if (!sprop->value.lpszW) return 0;
+		return (strlen(mapi_sprop->value.lpszW) * 2 + 2);
+	case PT_SYSTIME:
+		sprop->value.ft.dwLowDateTime = mapi_sprop->value.ft.dwLowDateTime;
+		sprop->value.ft.dwHighDateTime = mapi_sprop->value.ft.dwHighDateTime;
+		return (sizeof (struct FILETIME));
+	case PT_BINARY:
+		sprop->value.bin.cb = mapi_sprop->value.bin.cb;
+		sprop->value.bin.lpb = mapi_sprop->value.bin.lpb;
+		return (sprop->value.bin.cb + sizeof(uint16_t));
+
+	case PT_MV_STRING8:
+		{
+		uint32_t	i;
+		uint32_t	size = 0;
+
+		sprop->value.MVszA.cValues = mapi_sprop->value.MVszA.cValues;
+		size += 4;
+
+		sprop->value.MVszA.lppszA = talloc_array(global_mapi_ctx->mem_ctx, const char *, sprop->value.MVszA.cValues);
+		for (i = 0; i < sprop->value.MVszA.cValues; i++) {
+			sprop->value.MVszA.lppszA[i] = mapi_sprop->value.MVszA.strings[i].lppszA;
+			size += strlen(sprop->value.MVszA.lppszA[i]) + 1;
+		}
+		return size;
+		}
+	}
+	return 0;
+}
+
+
+/**
+   \details add a SPropValue structure to a SRow array
+
+   \param aRow pointer to the SRow array where SPropBalue should be
+   appended
+   \param SPropValue reference to the SPropValue structure to add to
+   aRow
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_INVALID_PARAMETER.
+ */
+_PUBLIC_ enum MAPISTATUS SRow_addprop(struct SRow *aRow, struct SPropValue SPropValue)
+{
+	TALLOC_CTX		*mem_ctx;
+	uint32_t		cValues;
+	struct SPropValue	lpProp;
+	uint32_t		i;
+	
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!aRow, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = (TALLOC_CTX *) aRow;
+
+	/* If the property tag already exist, overwrite its value */
+	for (i = 0; i < aRow->cValues; i++) {
+		if (aRow->lpProps[i].ulPropTag == SPropValue.ulPropTag) {
+			aRow->lpProps[i] = SPropValue;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	cValues = aRow->cValues + 1;
+	aRow->lpProps = talloc_realloc(mem_ctx, aRow->lpProps, struct SPropValue, cValues);
+	lpProp = aRow->lpProps[cValues-1];
+	lpProp.ulPropTag = SPropValue.ulPropTag;
+	lpProp.dwAlignPad = 0;
+	set_SPropValue(&(lpProp), get_SPropValue_data(&SPropValue));
+	aRow->cValues = cValues;
+	aRow->lpProps[cValues - 1] = lpProp;
+
+	return MAPI_E_SUCCESS;
+}
+
+_PUBLIC_ uint32_t SRowSet_propcpy(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, struct SPropValue SPropValue)
+{
+	uint32_t	rows;
+	uint32_t	cValues;
+	struct SPropValue lpProp;
+
+	for (rows = 0; rows < SRowSet->cRows; rows++) {
+		cValues = SRowSet->aRow[rows].cValues + 1;
+		SRowSet->aRow[rows].lpProps = talloc_realloc(mem_ctx, SRowSet->aRow[rows].lpProps, struct SPropValue, cValues);
+		lpProp = SRowSet->aRow[rows].lpProps[cValues-1];
+		lpProp.ulPropTag = SPropValue.ulPropTag;
+		lpProp.dwAlignPad = 0;
+		set_SPropValue(&(lpProp), (void *)&SPropValue.value);
+		SRowSet->aRow[rows].cValues = cValues;
+		SRowSet->aRow[rows].lpProps[cValues - 1] = lpProp;
+	}
+	return 0;
+}
+
+_PUBLIC_ void mapi_SPropValue_array_named(mapi_object_t *obj, 
+					  struct mapi_SPropValue_array *props)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct MAPINAMEID	*nameid;
+	uint32_t		propID;
+	uint16_t		count;
+	uint32_t		i;
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_SPropValue_array_named");
+
+	for (i = 0; i < props->cValues; i++) {
+		if ((props->lpProps[i].ulPropTag & 0xFFFF0000) > 0x80000000) {
+			propID = props->lpProps[i].ulPropTag;
+			propID = (propID & 0xFFFF0000) | PT_NULL;
+			nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
+			retval = GetNamesFromIDs(obj, propID, &count, &nameid);
+			if (retval != MAPI_E_SUCCESS) goto end;
+
+			if (count) {
+				/* Display property given its propID */
+				switch (nameid->ulKind) {
+				case MNID_ID:
+					props->lpProps[i].ulPropTag = (nameid->kind.lid << 16) | 
+						(props->lpProps[i].ulPropTag & 0x0000FFFF);
+					break;
+				case MNID_STRING:
+					/* MNID_STRING named properties don't have propIDs */
+					break;
+				}
+			}
+			talloc_free(nameid);
+		}
+	}
+end:
+	talloc_free(mem_ctx);
+}
+
+_PUBLIC_ enum MAPISTATUS get_mapi_SPropValue_array_date_timeval(struct timeval *t,
+								struct mapi_SPropValue_array *properties,
+								uint32_t mapitag)
+{
+	const struct FILETIME	*filetime;
+	NTTIME			time;
+	
+	filetime = (const struct FILETIME *) find_mapi_SPropValue_data(properties, mapitag);
+	if (!filetime) {
+		t = NULL;
+		return MAPI_E_NOT_FOUND;
+	}
+
+	time = filetime->dwHighDateTime;
+	time = time << 32;
+	time |= filetime->dwLowDateTime;
+	nttime_to_timeval(t, time);
+	
+	return MAPI_E_SUCCESS;	
+}
+
+_PUBLIC_ enum MAPISTATUS get_mapi_SPropValue_date_timeval(struct timeval *t, 
+							  struct SPropValue lpProp)
+{
+	const struct FILETIME	*filetime;
+	NTTIME			time;
+	
+	filetime = (const struct FILETIME *) get_SPropValue_data(&lpProp);
+	if (!filetime) {
+		t = NULL;
+		return MAPI_E_NOT_FOUND;
+	}
+
+	time = filetime->dwHighDateTime;
+	time = time << 32;
+	time |= filetime->dwLowDateTime;
+	nttime_to_timeval(t, time);
+	
+	return MAPI_E_SUCCESS;
+}
+
+_PUBLIC_ bool set_SPropValue_proptag_date_timeval(struct SPropValue *lpProps, uint32_t aulPropTag, const struct timeval *t) 
+{
+	struct FILETIME	filetime;
+	NTTIME		time;
+	
+	time = timeval_to_nttime(t);
+
+	filetime.dwLowDateTime = (time << 32) >> 32;
+	filetime.dwHighDateTime = time >> 32;
+
+	return set_SPropValue_proptag(lpProps, aulPropTag, &filetime);
+}
+
+
+/**
+   \details Retrieve a RecurrencePattern structure from a binary blob
+
+   \param mem_ctx pointer to the memory context
+   \param bin pointer to the Binary_r structure with non-mapped
+   reccurrence data
+
+   \return Allocated RecurrencePattern structure on success,
+   otherwise NULL
+
+   \note Developers must free the allocated RecurrencePattern when
+   finished.
+ */
+_PUBLIC_ struct RecurrencePattern *get_RecurrencePattern(TALLOC_CTX *mem_ctx, 
+							 struct Binary_r *bin)
+{
+        struct RecurrencePattern	*RecurrencePattern = 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);
+        RecurrencePattern = talloc_zero(mem_ctx, struct RecurrencePattern);
+        ndr_err_code = ndr_pull_RecurrencePattern(ndr, NDR_SCALARS, RecurrencePattern);
+
+        talloc_free(ndr);
+
+        if (ndr_err_code != NDR_ERR_SUCCESS) {
+                talloc_free(RecurrencePattern);
+                return NULL;
+        }
+
+        return RecurrencePattern;
+}
+
+
+/**
+   \details Retrieve a TimeZoneStruct structure from a binary blob
+
+   \param mem_ctx pointer to the memory context
+   \param bin pointer to the Binary_r structure with raw
+   TimeZoneStruct data
+
+   \return Allocated TimeZoneStruct structure on success, otherwise
+   NULL
+
+   \note Developers must free the allocated TimeZoneStruct when
+   finished.
+ */
+_PUBLIC_ struct TimeZoneStruct *get_TimeZoneStruct(TALLOC_CTX *mem_ctx, 
+						   struct Binary_r *bin)
+{
+	struct TimeZoneStruct	*TimeZoneStruct = 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);
+	TimeZoneStruct = talloc_zero(mem_ctx, struct TimeZoneStruct);
+	ndr_err_code = ndr_pull_TimeZoneStruct(ndr, NDR_SCALARS, TimeZoneStruct);
+
+	talloc_free(ndr);
+	
+	if (ndr_err_code != NDR_ERR_SUCCESS) {
+		talloc_free(TimeZoneStruct);
+		return NULL;
+	}
+
+	return TimeZoneStruct;
+}
+
+
+/**
+   \details Retrieve a GlobalObjectId structure from a binary blob
+
+   \param mem_ctx pointer to the memory context
+   \param bin pointer to the Binary_r structure with raw
+   GlobalObjectId data
+
+   \return Allocated GlobalObjectId structure on success, otherwise
+   NULL
+
+   \note Developers must free the allocated GlobalObjectId when
+   finished.
+ */
+_PUBLIC_ struct GlobalObjectId *get_GlobalObjectId(TALLOC_CTX *mem_ctx,
+						   struct Binary_r *bin)
+{
+	struct GlobalObjectId	*GlobalObjectId = 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);
+	GlobalObjectId = talloc_zero(mem_ctx, struct GlobalObjectId);
+	ndr_err_code = ndr_pull_GlobalObjectId(ndr, NDR_SCALARS, GlobalObjectId);
+
+	talloc_free(ndr);
+
+	if (ndr_err_code != NDR_ERR_SUCCESS) {
+		talloc_free(GlobalObjectId);
+		return NULL;
+	}
+
+	return GlobalObjectId;
+}

Added: trunk/openchange/libmapi/simple_mapi.c
===================================================================
--- trunk/openchange/libmapi/simple_mapi.c	                        (rev 0)
+++ trunk/openchange/libmapi/simple_mapi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,862 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+/**
+   \file simple_mapi.c
+
+   \brief Convenience functions.
+*/
+
+
+/**
+   \details Retrieve the folder id for the specified default folder in
+   a public folder store
+
+   \param obj_store the store to search
+   \param id the type of folder to search for
+   \param folder the resulting folder reference
+
+   The following types of folders are supported:
+   - olFolderPublicRoot - the parent (directly or indirectly) for the folders below
+   - olFolderPublicIPMSubtree - Interpersonal Messages (IPM) folders
+   - olFolderPublicNonIPMSubtree - Non-interpersonal message folders
+   - olFolderPublicEFormsRoot - EForms Registry Root Folder
+   - olFolderPublicFreeBusyRoot - Free/busy root folder
+   - olFolderPublicOfflineAB - Offline address book root folder
+   - olFolderPublicEFormsRegistry - EForms Registry for the users locale
+   - olFolderPublicLocalFreeBusy - Site local free/busy folders
+   - olFolderPublicLocalOfflineAB - Site local Offline address book
+   - olFolderPublicNNTPArticle - NNTP article index folder
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: obj_store is undefined
+   - MAPI_E_NOT_FOUND: The specified folder could not be found or is
+     not yet supported.
+
+   \sa MAPIInitialize, OpenPublicFolder, GetLastError
+ */
+_PUBLIC_ enum MAPISTATUS GetDefaultPublicFolder(mapi_object_t *obj_store,
+						uint64_t *folder,
+						const uint32_t id)
+{
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+
+	switch (id) {
+	case olFolderPublicRoot:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_public_root;
+		break;
+	case olFolderPublicIPMSubtree:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_ipm_subtree;
+		break;
+	case olFolderPublicNonIPMSubtree:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_non_ipm_subtree;
+		break;
+	case olFolderPublicEFormsRoot:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_EFormsRegistryRoot;
+		break;
+	case olFolderPublicFreeBusyRoot:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_FreeBusyRoot;
+		break;
+	case olFolderPublicOfflineAB:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_OfflineAB;
+		break;
+	case olFolderPublicEFormsRegistry:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_EFormsRegistry;
+		break;
+	case olFolderPublicLocalFreeBusy:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_LocalSiteFreeBusy;
+		break;
+	case olFolderPublicLocalOfflineAB:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_LocalSiteOfflineAB;
+		break;
+	case olFolderPublicNNTPArticle:
+		*folder = ((mapi_object_store_t *)obj_store->private_data)->fid_pf_NNTPArticle;
+		break;
+	default:
+		OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, NULL);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+static enum MAPISTATUS CacheDefaultFolders(mapi_object_t *obj_store)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_store_t	*store;
+	mapi_object_t		obj_inbox;
+	mapi_id_t		id_inbox;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SRow		aRow;
+	struct SPropValue	*lpProps;
+	uint32_t		count;
+	const struct Binary_r	*entryid;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+
+	store = (mapi_object_store_t *)obj_store->private_data;
+	OPENCHANGE_RETVAL_IF(!store, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetDefaultFolder");
+
+	mapi_object_init(&obj_inbox);
+	retval = GetReceiveFolder(obj_store, &id_inbox, NULL);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	retval = OpenFolder(obj_store, id_inbox, &obj_inbox);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_IPM_APPOINTMENT_ENTRYID,
+					  PR_IPM_CONTACT_ENTRYID,
+					  PR_IPM_JOURNAL_ENTRYID,
+					  PR_IPM_NOTE_ENTRYID,
+					  PR_IPM_TASK_ENTRYID,
+					  PR_IPM_DRAFTS_ENTRYID);
+	
+	retval = GetProps(&obj_inbox, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	aRow.cValues = count;
+	aRow.lpProps = lpProps;
+	
+	/* set cached calendar FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_APPOINTMENT_ENTRYID);
+	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
+	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_calendar);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* set cached contact FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_CONTACT_ENTRYID);
+	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
+	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_contact);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* set cached journal FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_JOURNAL_ENTRYID);
+	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
+	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_journal);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* set cached note FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_NOTE_ENTRYID);
+	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
+	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_note);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* set cached task FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_TASK_ENTRYID);
+	OPENCHANGE_RETVAL_IF(!entryid, MAPI_E_NOT_FOUND, mem_ctx);
+	retval = GetFIDFromEntryID(entryid->cb, entryid->lpb, id_inbox, &store->fid_task);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+	
+	/* set cached drafts FID */
+	entryid = (const struct Binary_r *)find_SPropValue_data(&aRow, PR_IPM_DRAFTS_ENTRYID);
+	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->cached_mailbox_fid = true;
+	
+	mapi_object_release(&obj_inbox);
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieves the folder id for the specified default folder
+   in a mailbox store
+
+   \param obj_store the store to search
+   \param id the type of folder to search for
+   \param folder the resulting folder reference
+
+   The following types of folders are supported:
+   - olFolderTopInformationStore
+   - olFolderDeletedItems
+   - olFolderOutbox
+   - olFolderSentMail
+   - olFolderInbox
+   - olFolderCommonView
+   - olFolderCalendar
+   - olFolderContacts
+   - olFolderJournal
+   - olFolderNotes
+   - olFolderTasks
+   - olFolderDrafts
+   - olFolderReminders
+   - olFolderFinder
+
+   Note that this function will cache FID values for common accessed
+   folders such as calendar, contact, journal, note, task and drafts
+   until the store object got released.
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: obj_store is undefined
+   - MAPI_E_NOT_FOUND: The specified folder could not be found or is
+     not yet supported.
+
+   \sa MAPIInitialize, OpenMsgStore, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetDefaultFolder(mapi_object_t *obj_store, 
+					  uint64_t *folder,
+					  const uint32_t id)
+{
+	enum MAPISTATUS			retval;
+	mapi_object_store_t		*store;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+
+	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)) {
+		retval = CacheDefaultFolders(obj_store);
+		OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+	} 
+
+	switch (id) {
+	case olFolderTopInformationStore:
+		*folder = store->fid_top_information_store;
+		return MAPI_E_SUCCESS;
+	case olFolderDeletedItems:
+		*folder = store->fid_deleted_items;
+		return MAPI_E_SUCCESS;
+	case olFolderOutbox:
+		*folder = store->fid_outbox;
+		return MAPI_E_SUCCESS;
+	case olFolderSentMail:
+		*folder = store->fid_sent_items;
+		return MAPI_E_SUCCESS;
+	case olFolderInbox:
+		*folder = store->fid_inbox;
+		return MAPI_E_SUCCESS;
+	case olFolderCommonView:
+		*folder = store->fid_common_views;
+		return MAPI_E_SUCCESS;
+	case olFolderCalendar:
+		*folder = store->fid_calendar;
+		return MAPI_E_SUCCESS;
+	case olFolderContacts:
+		*folder = store->fid_contact;
+		return MAPI_E_SUCCESS;
+	case olFolderJournal:
+		*folder = store->fid_journal;
+		return MAPI_E_SUCCESS;
+	case olFolderNotes:
+		*folder = store->fid_note;
+		return MAPI_E_SUCCESS;
+	case olFolderTasks:
+		*folder = store->fid_task;
+		return MAPI_E_SUCCESS;
+	case olFolderDrafts:
+		*folder = store->fid_drafts;
+		return MAPI_E_SUCCESS;
+	case olFolderFinder:
+		*folder = store->fid_search;
+		return MAPI_E_SUCCESS;
+	default:
+		*folder = 0;
+		OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0);
+	}
+}
+
+
+/**
+   \details Check if a given folder identifier matches with a
+   system/default one and optionally returns the olFolder type
+
+   \param obj_store pointer to the store object
+   \param fid reference to the folder identifier to check
+   \param olFolder pointer to the returned olFolder
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool IsMailboxFolder(mapi_object_t *obj_store, 
+			      uint64_t fid, 
+			      uint32_t *olFolder)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_store_t	*store;
+	uint32_t		olFolderNum;
+	bool			ret = true;
+
+	if (!obj_store) return false;
+	store = (mapi_object_store_t *) obj_store->private_data;
+	if (!store) return false;
+
+	if (store->cached_mailbox_fid == false) {
+		retval = CacheDefaultFolders(obj_store);
+		if (retval) return false;
+	}
+
+	if(fid == store->fid_top_information_store) {
+		olFolderNum = olFolderTopInformationStore;
+	} else if (fid == store->fid_deleted_items) {
+		olFolderNum = olFolderDeletedItems;
+	} else if (fid == store->fid_outbox) {
+		olFolderNum = olFolderOutbox;
+	} else if (fid == store->fid_sent_items) {
+		olFolderNum = olFolderSentMail;
+	} else if (fid == store->fid_inbox) {
+		olFolderNum = olFolderInbox;
+	} else if (fid == store->fid_common_views) {
+		olFolderNum = olFolderCommonView;
+	} else if (fid == store->fid_calendar) {
+		olFolderNum = olFolderCalendar;
+	} else if (fid == store->fid_contact) {
+		olFolderNum = olFolderContacts;
+	} else if (fid == store->fid_journal) {
+		olFolderNum = olFolderJournal;
+	} else if (fid == store->fid_note) {
+		olFolderNum = olFolderNotes;
+	} else if (fid == store->fid_task) {
+		olFolderNum = olFolderTasks;
+	} else if (fid == store->fid_drafts) {
+		olFolderNum = olFolderDrafts;
+	} else if (fid == store->fid_search) {
+		olFolderNum = olFolderFinder;
+	} else {
+		olFolderNum = -1;
+		ret = false;
+	}
+
+	if (olFolder) *olFolder = olFolderNum;
+	return ret;
+}
+
+/**
+   \details Retrieves the total and unread number of items for a
+    specified folder.
+
+    \param obj_folder the folder to get item counts for
+    \param unread the number of items in the folder (result)
+    \param total the number of items in the folder, including unread
+    items (result)
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: obj_folder is undefined
+   - MAPI_E_NOT_FOUND: The specified folder could not be found or is
+     not yet supported.
+
+   \sa MAPIInitialize, OpenFolder, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS GetFolderItemsCount(mapi_object_t *obj_folder,
+					     uint32_t *unread,
+					     uint32_t *total)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		count;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!unread, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!total, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "GetFolderItemsCount");
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, 
+					  PR_CONTENT_UNREAD,
+					  PR_CONTENT_COUNT);
+
+	retval = GetProps(obj_folder, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	*unread = lpProps[0].value.l;
+	*total = lpProps[1].value.l;
+
+	talloc_free(mem_ctx);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Adds permissions for a user on a given folder
+
+   \param obj_folder the folder we add permission for
+   \param username the Exchange username we add permissions for
+   \param role the permission mask value
+
+   The following permissions and rights are supported:
+   - RightsNone
+   - RightsReadItems
+   - RightsCreateItems
+   - RightsEditOwn
+   - RightsDeleteOwn
+   - RightsEditAll
+   - RightsDeleteAll
+   - RightsCreateSubfolders
+   - RightsFolderOwner
+   - RightsFolderContact
+   - RoleNone
+   - RoleReviewer
+   - RoleContributor
+   - RoleNoneditingAuthor
+   - RoleAuthor
+   - RoleEditor
+   - RolePublishAuthor
+   - RolePublishEditor
+   - RightsAll
+   - RoleOwner
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: username is NULL
+
+   \sa ResolveNames, ModifyTable
+ */
+_PUBLIC_ enum MAPISTATUS AddUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct SPropTagArray	*SPropTagArray;
+	const char		*names[2];
+	struct SRowSet		*rows = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct mapi_SRowList	rowList;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "AddUserPermission");
+
+	/* query Address book */
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
+	names[0] = username;
+	names[1] = NULL;
+	retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, 
+			      SPropTagArray, &rows, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Check if the username was found */
+	OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx);
+
+	rowList.cEntries = 1;
+	rowList.aEntries = talloc_array(mem_ctx, struct mapi_SRow, 1);
+	rowList.aEntries[0].ulRowFlags = ROW_ADD;
+	rowList.aEntries[0].lpProps.cValues = 2;
+	rowList.aEntries[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2);
+	cast_mapi_SPropValue(&rowList.aEntries[0].lpProps.lpProps[0], &rows->aRow[0].lpProps[0]);
+	rowList.aEntries[0].lpProps.lpProps[1].ulPropTag = PR_MEMBER_RIGHTS;
+	rowList.aEntries[0].lpProps.lpProps[1].value.l = role;
+
+	retval = ModifyTable(obj_folder, &rowList);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Modify permissions for a user on a given folder
+   
+   \param obj_folder the folder we add permission for
+   \param username the Exchange username we modify permissions for
+   \param role the permission mask value (see AddUserPermission)
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: username is NULL
+   - MAPI_E_NOT_FOUND: couldn't find or change permissions for the
+     given user
+
+   \sa AddUserPermission, ResolveNames, GetTable, ModifyTable
+ */
+_PUBLIC_ enum MAPISTATUS ModifyUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct SPropTagArray	*SPropTagArray;
+	const char		*names[2];
+	const char		*user = NULL;
+	struct SRowSet		*rows = NULL;
+	struct SRowSet		rowset;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct mapi_SRowList	rowList;
+	struct SPropValue	*lpProp;
+	mapi_object_t		obj_table;
+	uint32_t		Numerator;
+	uint32_t		Denominator;
+	bool			found = false;
+	uint32_t		i = 0;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "ModifyUserPermission");
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
+	names[0] = username;
+	names[1] = NULL;
+	retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, 
+			      SPropTagArray, &rows, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (flaglist->aulPropTag[0] == MAPI_RESOLVED) {
+		user = find_SPropValue_data(&(rows->aRow[0]), PR_DISPLAY_NAME);
+	} else {
+		/* Special case: Not a AD user account but Default or
+		 * Anonymous. Since names are language specific, we
+		 * can't use strcmp 
+		 */
+		user = username;
+	}
+
+	mapi_object_init(&obj_table);
+	retval = GetTable(obj_folder, &obj_table);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 4,
+					  PR_ENTRYID,
+					  PR_MEMBER_RIGHTS,
+					  PR_MEMBER_ID,
+					  PR_MEMBER_NAME);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	for (i = 0; i < rowset.cRows; i++) {
+		lpProp = get_SPropValue_SRow(&rowset.aRow[i], PR_MEMBER_NAME);
+		if (lpProp && lpProp->value.lpszA) {
+			if (!strcmp(lpProp->value.lpszA, user)) {
+				rowList.cEntries = 1;
+				rowList.aEntries = talloc_array(mem_ctx, struct mapi_SRow, 1);
+				rowList.aEntries[0].ulRowFlags = ROW_MODIFY;
+				rowList.aEntries[0].lpProps.cValues = 2;
+				rowList.aEntries[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2);
+				lpProp = get_SPropValue_SRow(&(rowset.aRow[i]), PR_MEMBER_ID);
+				rowList.aEntries[0].lpProps.lpProps[0].ulPropTag = PR_MEMBER_ID;
+				rowList.aEntries[0].lpProps.lpProps[0].value.d = lpProp->value.d;
+				rowList.aEntries[0].lpProps.lpProps[1].ulPropTag = PR_MEMBER_RIGHTS;
+				rowList.aEntries[0].lpProps.lpProps[1].value.l = role;
+				
+				retval = ModifyTable(obj_folder, &rowList);
+				OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+				found = true;
+				break;
+			}
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	talloc_free(mem_ctx);
+	
+	OPENCHANGE_RETVAL_IF((found == true), MAPI_E_NOT_FOUND, 0);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Remove permissions for a user on a given folder
+
+   \param obj_folder the folder we add permission for
+   \param username the Exchange username we remove permissions for
+
+   \return MAPI_E_SUCCESS on success, otherwise a failure code (MAPISTATUS)
+   indicating the error.
+
+   \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: username or obj_folder are NULL
+   - MAPI_E_NOT_FOUND: couldn't find or remove permissions for the
+     given user
+
+   \sa ResolveNames, GetTable, ModifyTable
+ */
+_PUBLIC_ enum MAPISTATUS RemoveUserPermission(mapi_object_t *obj_folder, const char *username)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct SPropTagArray	*SPropTagArray;
+	const char		*names[2];
+	const char		*user = NULL;
+	struct SRowSet		*rows = NULL;
+	struct SRowSet		rowset;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct mapi_SRowList	rowList;
+	struct SPropValue	*lpProp;
+	mapi_object_t		obj_table;
+	uint32_t		Numerator;
+	uint32_t		Denominator;
+	bool			found = false;
+	uint32_t		i = 0;
+
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!username, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "RemoveUserPermission");
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 2, PR_ENTRYID, PR_DISPLAY_NAME);
+	names[0] = username;
+	names[1] = NULL;
+	retval = ResolveNames(mapi_object_get_session(obj_folder), (const char **)names, 
+			      SPropTagArray, &rows, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Check if the username was found */
+	OPENCHANGE_RETVAL_IF((flaglist->aulPropTag[0] != MAPI_RESOLVED), MAPI_E_NOT_FOUND, mem_ctx);
+
+	user = find_SPropValue_data(&(rows->aRow[0]), PR_DISPLAY_NAME);
+
+	mapi_object_init(&obj_table);
+	retval = GetTable(obj_folder, &obj_table);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 4,
+					  PR_ENTRYID,
+					  PR_MEMBER_RIGHTS,
+					  PR_MEMBER_ID,
+					  PR_MEMBER_NAME);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = QueryRows(&obj_table, Denominator, TBL_ADVANCE, &rowset);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	for (i = 0; i < rowset.cRows; i++) {
+		lpProp = get_SPropValue_SRow(&rowset.aRow[i], PR_MEMBER_NAME);
+		if (lpProp && lpProp->value.lpszA) {
+			if (!strcmp(lpProp->value.lpszA, user)) {
+				rowList.cEntries = 1;
+				rowList.aEntries = talloc_array(mem_ctx, struct mapi_SRow, 1);
+				rowList.aEntries[0].ulRowFlags = ROW_REMOVE;
+				rowList.aEntries[0].lpProps.cValues = 1;
+				rowList.aEntries[0].lpProps.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 1);
+				lpProp = get_SPropValue_SRow(&(rowset.aRow[i]), PR_MEMBER_ID);
+				rowList.aEntries[0].lpProps.lpProps[0].ulPropTag = PR_MEMBER_ID;
+				rowList.aEntries[0].lpProps.lpProps[0].value.d = lpProp->value.d;
+				
+				retval = ModifyTable(obj_folder, &rowList);
+				OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+				found = true;
+				break;
+			}
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	talloc_free(mem_ctx);
+
+	OPENCHANGE_RETVAL_IF((found == true), MAPI_E_NOT_FOUND, 0);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Implement the BestBody algorithm and return the best body
+   content type for a given message.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND. If
+   MAPI_E_NOT_FOUND is returned then format is set to 0x0
+   (undefined). If MAPI_E_SUCCESS is returned, then format can have
+   one of the following values:
+   - olEditorText: format is plain text
+   - olEditorHTML: format is HTML
+   - olEditorRTF: format is RTF
+
+   \param obj_message the message we find the best body for
+   \param format the format - see above.
+ */
+_PUBLIC_ enum MAPISTATUS GetBestBody(mapi_object_t *obj_message, uint8_t *format)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	*lpProps;
+	struct SRow		aRow;
+	uint32_t		count;
+	uint8_t			RtfInSync;
+	uint32_t		PlainStatus;
+	uint32_t		RtfStatus;
+	uint32_t		HtmlStatus;
+	const uint32_t		*err_code;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!format, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Step 1. Retrieve properties needed by the BestBody algorithm */
+	SPropTagArray = set_SPropTagArray(global_mapi_ctx->mem_ctx, 0x4,
+					  PR_BODY,
+					  PR_RTF_COMPRESSED,
+					  PR_HTML,
+					  PR_RTF_IN_SYNC);
+	retval = GetProps(obj_message, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) {
+		*format = 0;
+		OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0);
+	}
+
+	aRow.ulAdrEntryPad = 0;
+	aRow.cValues = count;
+	aRow.lpProps = lpProps;
+
+	/* Step 2. Retrieve properties values and map errors */
+	RtfInSync = *(const uint8_t *)find_SPropValue_data(&aRow, PR_RTF_IN_SYNC);
+
+	err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_BODY_ERROR);
+	PlainStatus = (err_code) ? *err_code : 0;
+
+	err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_RTF_COMPRESSED_ERROR);
+	RtfStatus = (err_code) ? *err_code : 0;
+
+	err_code = (const uint32_t *)find_SPropValue_data(&aRow, PR_BODY_HTML_ERROR);
+	HtmlStatus = (err_code) ? *err_code : 0;
+
+	/* Step 3. Determine the body format (9 possible cases) */
+
+	/* case 1 */
+	if ((PlainStatus == MAPI_E_NOT_FOUND) && (RtfStatus == MAPI_E_NOT_FOUND) && 
+	    (HtmlStatus == MAPI_E_NOT_FOUND)) {
+		*format = 0;
+		OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0);
+	}
+	
+	/* case 2 */
+	if (((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) || (PlainStatus == 0)) && 
+	    (RtfStatus == MAPI_E_NOT_FOUND) && (HtmlStatus == MAPI_E_NOT_FOUND)) {
+		*format = olEditorText;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 3 */
+	if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) && 
+	    (HtmlStatus == MAPI_E_NOT_FOUND)) {
+		*format = olEditorRTF;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 4 */
+	if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (RtfInSync == 1)) {
+		*format = olEditorRTF;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 5 */
+	if ((PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY) &&
+	    (RtfInSync == 0)) {
+		*format = olEditorHTML;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 6 */
+	if (((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    ((HtmlStatus == 0) || (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    (RtfInSync == 1)) {
+		*format = olEditorRTF;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 7 */
+	if (((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    ((HtmlStatus == 0) || (HtmlStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    (RtfInSync == 0)) {
+		*format = olEditorHTML;
+		return MAPI_E_SUCCESS;
+	}
+	
+	/* case 8 */
+	if (((PlainStatus == 0) || (PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    ((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    (RtfInSync == 1)) {
+		*format = olEditorRTF;
+		return MAPI_E_SUCCESS;
+	}
+
+	/* case 9 */
+	if (((PlainStatus == 0) || (PlainStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    ((RtfStatus == 0) || (RtfStatus == MAPI_E_NOT_ENOUGH_MEMORY)) &&
+	    (RtfInSync == 0)) {
+		*format = olEditorText;
+		return MAPI_E_SUCCESS;
+	}
+
+	OPENCHANGE_RETVAL_ERR(MAPI_E_NOT_FOUND, 0);
+}

Added: trunk/openchange/libmapi/socket/interface.c
===================================================================
--- trunk/openchange/libmapi/socket/interface.c	                        (rev 0)
+++ trunk/openchange/libmapi/socket/interface.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,323 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   multiple interface handling
+
+   Copyright (C) Andrew Tridgell 1992-2005
+   
+   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 <libmapi/proto_private.h>
+#include <param.h>
+
+#define ALLONES  ((uint32_t)0xFFFFFFFF)
+/*
+  address construction based on a patch from fred at datalync.com
+*/
+#define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
+#define MKNETADDR(_IP, _NM) (_IP & _NM)
+
+/****************************************************************************
+Try and find an interface that matches an ip. If we cannot, return NULL
+  **************************************************************************/
+static struct interface *iface_find(struct interface *interfaces, 
+				    struct in_addr ip, bool CheckMask)
+{
+	struct interface *i;
+	if (is_zero_ip_v4(ip)) return interfaces;
+
+	for (i=interfaces;i;i=i->next)
+		if (CheckMask) {
+			if (same_net_v4(i->ip,ip,i->nmask)) return i;
+		} else if (i->ip.s_addr == ip.s_addr) return i;
+
+	return NULL;
+}
+
+
+/****************************************************************************
+add an interface to the linked list of interfaces
+****************************************************************************/
+static void add_interface(TALLOC_CTX *mem_ctx, struct in_addr ip, struct in_addr nmask, struct interface **interfaces)
+{
+	struct interface *iface;
+	struct in_addr bcast;
+
+	if (iface_find(*interfaces, ip, false)) {
+		DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
+		return;
+	}
+
+	iface = talloc(*interfaces == NULL ? mem_ctx : *interfaces, struct interface);
+	if (iface == NULL) 
+		return;
+	
+	ZERO_STRUCTPN(iface);
+
+	iface->ip = ip;
+	iface->nmask = nmask;
+	bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+
+	/* keep string versions too, to avoid people tripping over the implied
+	   static in inet_ntoa() */
+	iface->ip_s = talloc_strdup(iface, inet_ntoa(iface->ip));
+	iface->nmask_s = talloc_strdup(iface, inet_ntoa(iface->nmask));
+	
+	if (nmask.s_addr != ~0) {
+		iface->bcast_s = talloc_strdup(iface, inet_ntoa(bcast));
+	}
+
+	DLIST_ADD_END(*interfaces, iface, struct interface *);
+
+	DEBUG(2,("added interface ip=%s nmask=%s\n", iface->ip_s, iface->nmask_s));
+}
+
+
+
+/**
+interpret a single element from a interfaces= config line 
+
+This handles the following different forms:
+
+1) wildcard interface name
+2) DNS name
+3) IP/masklen
+4) ip/mask
+5) bcast/mask
+**/
+static void interpret_interface(TALLOC_CTX *mem_ctx, 
+				const char *token, 
+				struct iface_struct *probed_ifaces, 
+				int total_probed,
+				struct interface **local_interfaces)
+{
+	struct in_addr ip, nmask;
+	char *p;
+	char *address;
+	int i, added=0;
+
+	ip.s_addr = 0;
+	nmask.s_addr = 0;
+	
+	/* first check if it is an interface name */
+	for (i=0;i<total_probed;i++) {
+		if (gen_fnmatch(token, probed_ifaces[i].name) == 0) {
+			add_interface(mem_ctx, probed_ifaces[i].ip,
+				      probed_ifaces[i].netmask,
+				      local_interfaces);
+			added = 1;
+		}
+	}
+	if (added) return;
+
+	/* maybe it is a DNS name */
+	p = strchr_m(token,'/');
+	if (!p) {
+		/* don't try to do dns lookups on wildcard names */
+		if (strpbrk(token, "*?") != NULL) {
+			return;
+		}
+		ip.s_addr = interpret_addr2(token).s_addr;
+		for (i=0;i<total_probed;i++) {
+			if (ip.s_addr == probed_ifaces[i].ip.s_addr) {
+				add_interface(mem_ctx, probed_ifaces[i].ip,
+					      probed_ifaces[i].netmask,
+					      local_interfaces);
+				return;
+			}
+		}
+		DEBUG(2,("can't determine netmask for %s\n", token));
+		return;
+	}
+
+	address = talloc_strdup(mem_ctx, token);
+	p = strchr_m(address,'/');
+
+	/* parse it into an IP address/netmasklength pair */
+	*p++ = 0;
+
+	ip.s_addr = interpret_addr2(address).s_addr;
+
+	if (strlen(p) > 2) {
+		nmask.s_addr = interpret_addr2(p).s_addr;
+	} else {
+		nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
+	}
+
+	/* maybe the first component was a broadcast address */
+	if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
+	    ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
+		for (i=0;i<total_probed;i++) {
+			if (same_net_v4(ip, probed_ifaces[i].ip, nmask)) {
+				add_interface(mem_ctx, probed_ifaces[i].ip, nmask,
+					      local_interfaces);
+				talloc_free(address);
+				return;
+			}
+		}
+		DEBUG(2,("Can't determine ip for broadcast address %s\n", address));
+		talloc_free(address);
+		return;
+	}
+
+	add_interface(mem_ctx, ip, nmask, local_interfaces);
+	talloc_free(address);
+}
+
+
+/**
+load the list of network interfaces
+**/
+void load_interfaces(TALLOC_CTX *mem_ctx, const char **interfaces, struct interface **local_interfaces)
+{
+	const char **ptr = interfaces;
+	int i;
+	struct iface_struct ifaces[MAX_INTERFACES];
+	struct in_addr loopback_ip;
+	int total_probed;
+
+	*local_interfaces = NULL;
+
+	loopback_ip = interpret_addr2("127.0.0.1");
+
+	/* probe the kernel for interfaces */
+	total_probed = get_interfaces(ifaces, MAX_INTERFACES);
+
+	/* if we don't have a interfaces line then use all interfaces
+	   except loopback */
+	if (!ptr || !*ptr || !**ptr) {
+		if (total_probed <= 0) {
+			DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
+		}
+		for (i=0;i<total_probed;i++) {
+			if (ifaces[i].ip.s_addr != loopback_ip.s_addr) {
+				add_interface(mem_ctx, ifaces[i].ip, 
+					      ifaces[i].netmask, local_interfaces);
+			}
+		}
+	}
+
+	while (ptr && *ptr) {
+		interpret_interface(mem_ctx, *ptr, ifaces, total_probed, local_interfaces);
+		ptr++;
+	}
+
+	if (!*local_interfaces) {
+		DEBUG(0,("WARNING: no network interfaces found\n"));
+	}
+}
+
+/**
+  how many interfaces do we have
+  **/
+int iface_count(struct interface *ifaces)
+{
+	int ret = 0;
+	struct interface *i;
+
+	for (i=ifaces;i;i=i->next)
+		ret++;
+	return ret;
+}
+
+/**
+  return IP of the Nth interface
+  **/
+const char *iface_n_ip(struct interface *ifaces, int n)
+{
+	struct interface *i;
+  
+	for (i=ifaces;i && n;i=i->next)
+		n--;
+
+	if (i) {
+		return i->ip_s;
+	}
+	return NULL;
+}
+
+/**
+  return bcast of the Nth interface
+  **/
+const char *iface_n_bcast(struct interface *ifaces, int n)
+{
+	struct interface *i;
+  
+	for (i=ifaces;i && n;i=i->next)
+		n--;
+
+	if (i) {
+		return i->bcast_s;
+	}
+	return NULL;
+}
+
+/**
+  return netmask of the Nth interface
+  **/
+const char *iface_n_netmask(struct interface *ifaces, int n)
+{
+	struct interface *i;
+  
+	for (i=ifaces;i && n;i=i->next)
+		n--;
+
+	if (i) {
+		return i->nmask_s;
+	}
+	return NULL;
+}
+
+/**
+  return the local IP address that best matches a destination IP, or
+  our first interface if none match
+*/
+const char *iface_best_ip(struct interface *ifaces, const char *dest)
+{
+	struct interface *iface;
+	struct in_addr ip;
+
+	ip.s_addr = interpret_addr(dest);
+	iface = iface_find(ifaces, ip, true);
+	if (iface) {
+		return iface->ip_s;
+	}
+	return iface_n_ip(ifaces, 0);
+}
+
+/**
+  return true if an IP is one one of our local networks
+*/
+bool iface_is_local(struct interface *ifaces, const char *dest)
+{
+	struct in_addr ip;
+
+	ip.s_addr = interpret_addr(dest);
+	if (iface_find(ifaces, ip, true)) {
+		return true;
+	}
+	return false;
+}
+
+/**
+  return true if a IP matches a IP/netmask pair
+*/
+bool iface_same_net(const char *ip1, const char *ip2, const char *netmask)
+{
+	return same_net_v4(interpret_addr2(ip1),
+			interpret_addr2(ip2),
+			interpret_addr2(netmask));
+}

Added: trunk/openchange/libmapi/socket/netif.c
===================================================================
--- trunk/openchange/libmapi/socket/netif.c	                        (rev 0)
+++ trunk/openchange/libmapi/socket/netif.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,151 @@
+/* 
+   Unix SMB/CIFS implementation.
+   return a list of network interfaces
+   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/>.
+*/
+
+
+/* working out the interfaces for a OS is an incredibly non-portable
+   thing. We have several possible implementations below, and autoconf
+   tries each of them to see what works
+
+   Note that this file does _not_ include includes.h. That is so this code
+   can be called directly from the autoconf tests. That also means
+   this code cannot use any of the normal Samba debug stuff or defines.
+   This is standalone code.
+
+*/
+
+#include <libmapi/libmapi.h>
+
+#ifdef __COMPAR_FN_T
+#define QSORT_CAST (__compar_fn_t)
+#endif
+
+#ifndef QSORT_CAST
+#define QSORT_CAST (int (*)(const void *, const void *))
+#endif
+
+/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1
+   V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2.
+
+   It probably also works on any BSD style system.  */
+
+/****************************************************************************
+  get the netmask address for a local interface
+****************************************************************************/
+static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+{  
+	struct ifconf		ifc;
+	struct ifreq		*ifr=NULL;
+	struct in_addr		ipaddr;
+	struct in_addr		nmask;
+	struct sockaddr		*sockaddr;
+	struct sockaddr_in	*sockaddr_in;
+	char			*iname;
+	char			buff[8192];
+	int			fd, i, n;
+	int			total = 0;
+
+	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+		return -1;
+	}
+  
+	ifc.ifc_len = sizeof(buff);
+	ifc.ifc_buf = buff;
+
+	if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
+		close(fd);
+		return -1;
+	} 
+
+	ifr = ifc.ifc_req;
+  
+	n = ifc.ifc_len / sizeof(struct ifreq);
+
+	/* Loop through interfaces, looking for given IP address */
+	for (i=n-1;i>=0 && total < max_interfaces;i--) {
+		if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
+			continue;
+		}
+
+		iname = ifr[i].ifr_name;
+		sockaddr = (struct sockaddr *) &ifr[i].ifr_addr;
+		sockaddr_in = (struct sockaddr_in *) sockaddr;
+		ipaddr = sockaddr_in->sin_addr;
+
+		if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) {
+			continue;
+		}  
+
+		if (!(ifr[i].ifr_flags & IFF_UP)) {
+			continue;
+		}
+
+		if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) {
+			continue;
+		}  
+
+		nmask = sockaddr_in->sin_addr;
+
+		strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
+		ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
+		ifaces[total].ip = ipaddr;
+		ifaces[total].netmask = nmask;
+		total++;
+	}
+
+	close(fd);
+
+	return total;
+}  
+
+static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
+{
+	int r;
+	r = strcmp(i1->name, i2->name);
+	if (r) return r;
+	r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr);
+	if (r) return r;
+	r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr);
+	return r;
+}
+
+/* this wrapper is used to remove duplicates from the interface list generated
+   above */
+_PUBLIC_ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+{
+	int total, i, j;
+
+	total = _get_interfaces(ifaces, max_interfaces);
+	if (total <= 0) return total;
+
+	/* now we need to remove duplicates */
+	qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp);
+
+	for (i=1;i<total;) {
+		if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) {
+			for (j=i-1;j<total-1;j++) {
+				ifaces[j] = ifaces[j+1];
+			}
+			total--;
+		} else {
+			i++;
+		}
+	}
+
+	return total;
+}

Added: trunk/openchange/libmapi/socket/netif.h
===================================================================
--- trunk/openchange/libmapi/socket/netif.h	                        (rev 0)
+++ trunk/openchange/libmapi/socket/netif.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,38 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   structures for socke/netif.c and socket/interface.c
+
+   Copyright (C) Andrew Tridgell 2004
+   
+   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/>.
+*/
+
+/** used for network interfaces */
+struct interface {
+	struct interface *next, *prev;
+	struct in_addr ip;
+	struct in_addr nmask;
+	const char *ip_s;
+	const char *bcast_s;
+	const char *nmask_s;
+};
+
+struct iface_struct {
+	char name[16];
+	struct in_addr ip;
+	struct in_addr netmask;
+};
+
+#define MAX_INTERFACES 128

Added: trunk/openchange/libmapi/tests/locale.c
===================================================================
--- trunk/openchange/libmapi/tests/locale.c	                        (rev 0)
+++ trunk/openchange/libmapi/tests/locale.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,103 @@
+/*
+   OpenChange MAPI implementation.
+   Codepages handled by Microsoft Exchange Server
+
+   Copyright (C) Julien Kerihuel 2005.
+
+   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 <talloc.h>
+#include <popt.h>
+#include <util.h>
+
+/* command line options */
+static struct {
+	bool locale_id;
+	bool language_group;
+	bool group;
+} options;
+
+/*
+  print locales information given a locale_id
+*/
+
+static void process_one(const char *name)
+{
+	uint32_t value = 0;
+
+	if (options.group) {
+		printf("Language groups:\n");
+		print_group();
+	}
+
+	else if (options.locale_id) {
+		value = (uint32_t)strtol(name, NULL, 16);
+		if (print_locale(value) == False) {
+			DEBUG(0, ("Unknown locale id in the locale database (%s)\n", name));
+		}
+			
+	}
+	else if (options.language_group) {
+		if ((value = strtol(name, NULL, 10)) == 0) {
+			if ((value = lang2nb(name)) == -1) {
+				DEBUG(0, ("Invalid language group provided (%s)\n", name));
+				exit (1);
+			}
+		}
+		DEBUG(3, ("value = %d\n", value));
+		print_groupmember(value);
+	}
+}
+
+int main(int argc, const char *argv[])
+{
+	poptContext pc;
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{ "locale_id", 'L', POPT_ARG_VAL, &options.locale_id, 
+		  'L', "Display locale information for a given locale id", "LOCALE ID" },
+
+		{ "language_group", 'G', POPT_ARG_VAL, &options.language_group,
+		  'G', "Display all languages for the specified language group", "LANGUAGE_GROUP" },
+
+		{"list_groups", 'l', POPT_ARG_NONE, &options.group,
+		 True, "List existing language groups"},
+
+		{ 0, 0, 0, 0 }
+	};
+	
+	pc = poptGetContext("locale", argc, (const char **)argv, long_options,
+			    POPT_CONTEXT_KEEP_FIRST);
+
+	while ((poptGetNextOpt(pc) != -1)) /* noop */;
+
+	/* swallow argv[0] */
+	poptGetArg(pc);
+
+	if (!poptPeekArg(pc)) {
+		poptPrintUsage(pc, stderr, 0);
+		exit (1);
+	}
+
+	while (poptPeekArg(pc)) {
+		const char *name = poptGetArg(pc);
+
+		process_one(name);
+	}
+
+	poptFreeContext(pc);
+
+	return 0;
+}

Added: trunk/openchange/libmapi/tests/locale_codepage.c
===================================================================
--- trunk/openchange/libmapi/tests/locale_codepage.c	                        (rev 0)
+++ trunk/openchange/libmapi/tests/locale_codepage.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,107 @@
+/*
+   OpenChange MAPI implementation.
+   Codepages handled by Microsoft Exchange Server
+
+   Copyright (C) Julien Kerihuel 2005.
+
+   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 <libmapi/proto_private.h>
+#include <samba/popt.h>
+
+/* command line options */
+static struct {
+	uint32_t	 locale_id;
+	char		*language_group;
+	bool		group;
+	uint32_t	codepage;
+	char		*language_info;
+} options;
+
+/*
+  print locales information given a locale_id
+*/
+
+static void process_one(const char *name)
+{
+	if (options.group) {
+		printf("Language groups:\n");
+		lcid_print_group();
+	}
+
+	if (options.locale_id) {
+		if (lcid_print_locale(options.locale_id) == false) {
+			DEBUG(0, ("Unknown locale id in the locale database (%s)\n", name));
+		}
+			
+	}
+	if (options.language_group) {
+		if (lcid_print_groupmember(lcid_lang2nb(options.language_group)) == false) {
+			DEBUG(0, ("(%s)\n", name));
+			exit (1);
+		}
+	}
+
+	if (options.codepage) {
+		if (print_codepage_infos(options.codepage) == false) {
+			DEBUG(0, ("Invalid codepage (%s)\n", name));
+			exit (1);
+		}
+	}
+	if (options.language_info) {
+		printf("######### BEGIN: (copy and paste into smb.conf) #########\n");
+		if (lcid_get_locales(options.language_info) == false) {
+			DEBUG(0, ("Invalid language (%s)\n", name));
+			exit (1);
+		}
+		printf("######### END:   (copy and paste into smb.conf) #########\n");
+	}
+}
+
+int main(int argc, const char *argv[])
+{
+	poptContext pc;
+	int opt;
+	enum{OPT_LOCALID=1,OPT_LANGROUPS,OPT_GROUPS,OPT_CP,OPT_LANGINFO};
+	struct poptOption popt_options[] = {
+		POPT_AUTOHELP
+		{ "locale_id",		'L', POPT_ARG_STRING,	&options.locale_id,	OPT_LOCALID,   	"Display locale information for a given locale id", "LOCALE ID" },
+		{ "language_group",	'G', POPT_ARG_STRING,	&options.language_group,OPT_LANGROUPS,	"Display all languages for the specified language group", "LANGUAGE_GROUP" },
+		{"list_groups",		'l', POPT_ARG_NONE,	&options.group,		OPT_GROUPS,	"List existing language groups", NULL},
+		{"codepage",		'c', POPT_ARG_INT,	&options.codepage,	OPT_CP,		"Check if CODEPAGE exists and display related information\n", "CODEPAGE"},
+		{"language_info",	'i', POPT_ARG_STRING,	&options.language_info,	OPT_LANGINFO,	"Copy and Paste information into your smb.conf file\n", "LANGUAGE"},
+		POPT_TABLEEND
+	};
+	
+	pc = poptGetContext(argv[0], argc, argv, popt_options,
+			    POPT_CONTEXT_KEEP_FIRST);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_GROUPS:
+			process_one(NULL);
+			break;
+		case OPT_LOCALID:
+		case OPT_LANGROUPS:
+		case OPT_CP:
+		case OPT_LANGINFO:
+			process_one(poptGetOptArg(pc));
+			break;
+		}
+	}
+		
+	return 0;
+}

Added: trunk/openchange/libmapi/utf8_convert.l
===================================================================
--- trunk/openchange/libmapi/utf8_convert.l	                        (rev 0)
+++ trunk/openchange/libmapi/utf8_convert.l	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,379 @@
+/*
+   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;
+}

Added: trunk/openchange/libmapi/util/codepage.c
===================================================================
--- trunk/openchange/libmapi/util/codepage.c	                        (rev 0)
+++ trunk/openchange/libmapi/util/codepage.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,228 @@
+/*
+   OpenChange MAPI implementation.
+   Codepages handled by Microsoft Exchange Server
+
+   Copyright (C) Julien Kerihuel 2005.
+
+   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 <libmapi/proto_private.h>
+
+#define	CP_VAL	"codepage"
+#define	CP_NAME	"codepage name"
+#define	CP_DESC	"codepage description"
+
+struct codepages
+{
+	const char     *cp_name;
+	uint32_t	cpid;
+	const char     *cp_desc;
+};
+
+static struct codepages codepages[] = 
+{
+	{ "cpANSI", 0x0, "ANSI code page" },
+	{ "cpOEM", 0x1, "OEM code page" },
+	{ "cpMAC", 0x2, "Macintosh code page." },
+	{ "cpebcdiccpus", 0x25, "IBM EBCDIC - U.S./Canada, IBM EBCDIC (US-Canada), Charset Label:ebcdic-cp-us" },
+	{ "cpIBM437", 0x1B5, "OEM - United States, OEM United States, Charset Label:IBM437, Aliases:437, cp437, csPC8, CodePage437" },
+	{ "cpIBMEBCDICInternational", 0x1F4, "IBM EBCDIC - International" },
+	{ "cpASMO708", 0x2C4, "Arabic - ASMO 708, Arabic (ASMO 708), Charset Label:ASMO-708" },
+	{ "cpArabicASMO449BCONV4", 0x2C5, "Arabic - ASMO 449+, BCON V4" },
+	{ "cpArabicTransparentArabic", 0x2C6, "Arabic - Transparent Arabic" },
+	{ "cpDOS720", 0x2D0, "Arabic - Transparent ASMO, Arabic (DOS), Charset Label:DOS-720" },
+	{ "cpibm737", 0x2E1, "OEM - Greek (formerly 437G), Greek (DOS), Charset Label:ibm737" },
+	{ "cpibm775", 0x307, "OEM - Baltic, Baltic (DOS), Charset Label:ibm775, Aliases:CP500" },
+	{ "cpibm850", 0x352, "OEM - Multilingual Latin I, Western European (DOS), Charset Label:ibm850" },
+	{ "cpibm852", 0x354, "OEM - Latin II, Central European (DOS), Charset Label:ibm852, Aliases:cp852" },
+	{ "cpOEMCyrillicprimarilyRussian", 0x357, "OEM - Cyrillic (primarily Russian)" },
+	{ "cpibm857", 0x359, "OEM - Turkish, Turkish (DOS), Charset Label:ibm857" },
+	{ "cpOEMMultlingualLatinIEurosymbol", 0x35A, "OEM - Multlingual Latin I + Euro symbol" },
+	{ "cpOEMPortuguese", 0x35C, "OEM - Portuguese" },
+	{ "cpibm861", 0x35D, "OEM - Icelandic, Icelandic (DOS), Charset Label:ibm861" },
+	{ "cpDOS862", 0x35E, "OEM - Hebrew, Hebrew (DOS), Charset Label:DOS-862" },
+	{ "cpOEMCanadianFrench", 0x35F, "OEM - Canadian-French, " },
+	{ "cpOEMArabic", 0x360, "OEM - Arabic, " },
+	{ "cpOEMNordic", 0x361, "OEM - Nordic, " },
+	{ "cpcp866", 0x362, "OEM - Russian, Cyrillic (DOS), Charset Label:cp866, Aliases:ibm866" },
+	{ "cpibm869", 0x365, "OEM - Modern Greek, Greek, Modern (DOS), Charset Label:ibm869" },
+	{ "cpCP870", 0x366, "IBM EBCDIC - Multilingual/ROECE (Latin-2), IBM EBCDIC (Multilingual Latin-2), Charset Label:CP870" },
+	{ "cpwindows874", 0x36A, "ANSI/OEM - Thai (same as 28605, ISO 8859-15), Thai (Windows), Charset Label:windows-874, Aliases:DOS-874, iso-8859-11, TIS-620" },
+	{ "cpxEBCDICGreekModern", 0x36B, "IBM EBCDIC - Modern Greek, IBM EBCDIC (Greek Modern), Charset Label:x-EBCDIC-GreekModern" },
+	{ "cpshiftjis", 0x3A4, "ANSI/OEM - Japanese, Shift-JIS, Japanese (Shift-JIS), Charset Label:shift_jis, Aliases:csShiftJIS, csWindows31J, ms_Kanji, shift-jis, x-ms-cp932, x-sjis" },
+	{ "cpgb2312", 0x3A8, "ANSI/OEM - Simplified Chinese (PRC, Singapore), Chinese Simplified (GB2312), Charset Label:gb2312, Aliases:chinese, CN-GB, csGB2312, csGB231280, csISO58GB231280, GB_2312-80, GB231280, GB2312-80, GBK, iso-ir-58" },
+	{ "cpksc56011987", 0x3B5, "ANSI/OEM - Korean (Unified Hangeul Code), Korean, Charset Label:ks_c_5601-1987, Aliases:csKSC56011987, euc-kr, iso-ir-149, korean, ks_c_5601, ks_c_5601_1987, ks_c_5601-1989, KSC_5601, KSC5601" },
+	{ "cpbig5", 0x3B6, "ANSI/OEM - Traditional Chinese (Taiwan; Hong Kong SAR, PRC), Chinese Traditional (Big5), Charset Label:big5, Aliases:cn-big5, csbig5, x-x-big5" },
+	{ "cpCP1026", 0x402, "IBM EBCDIC - Turkish (Latin-5), IBM EBCDIC (Turkish Latin-5), Charset Label:CP1026" },
+	{ "cpIBMEBCDICLatin1OpenSystem", 0x417, "IBM EBCDIC - Latin 1/Open System, " },
+	{ "cpxebcdiccpuseuro", 0x474, "IBM EBCDIC - U.S./Canada (037 + Euro symbol), IBM EBCDIC (US-Canada-Euro), Charset Label:x-ebcdic-cp-us-euro" },
+	{ "cpxebcdicgermanyeuro", 0x475, "IBM EBCDIC - Germany (20273 + Euro symbol), IBM EBCDIC (Germany-Euro), Charset Label:x-ebcdic-germany-euro" },
+	{ "cpxebcdicdenmarknorwayeuro", 0x476, "IBM EBCDIC - Denmark/Norway (20277 + Euro symbol), IBM EBCDIC (Denmark-Norway-Euro), Charset Label:x-ebcdic-denmarknorway-euro" },
+	{ "cpxebcdicfinlandswedeneuro", 0x477, "IBM EBCDIC - Finland/Sweden (20278 + Euro symbol), IBM EBCDIC (Finland-Sweden-Euro), Charset Label:x-ebcdic-finlandsweden-euro, Aliases:X-EBCDIC-France" },
+	{ "cpxebcdicitalyeuro", 0x478, "IBM EBCDIC - Italy (20280 + Euro symbol), IBM EBCDIC (Italy-Euro), Charset Label:x-ebcdic-italy-euro" },
+	{ "cpxebcdicspaineuro", 0x479, "IBM EBCDIC - Latin America/Spain (20284 + Euro symbol), IBM EBCDIC (Spain-Euro), Charset Label:x-ebcdic-spain-euro" },
+	{ "cpxebcdicukeuro", 0x47A, "IBM EBCDIC - United Kingdom (20285 + Euro symbol), IBM EBCDIC (UK-Euro), Charset Label:x-ebcdic-uk-euro" },
+	{ "cpxebcdicfranceeuro", 0x47B, "IBM EBCDIC - France (20297 + Euro symbol), IBM EBCDIC (France-Euro), Charset Label:x-ebcdic-france-euro" },
+	{ "cpxebcdicinternationaleuro", 0x47C, "IBM EBCDIC - International (500 + Euro symbol), IBM EBCDIC (International-Euro), Charset Label:x-ebcdic-international-euro" },
+	{ "cpxebcdicicelandiceuro", 0x47D, "IBM EBCDIC - Icelandic (20871 + Euro symbol), IBM EBCDIC (Icelandic-Euro), Charset Label:x-ebcdic-icelandic-euro" },
+	{ "cpunicode", 0x4B0, "Unicode UCS-2 Little-Endian (BMP of ISO 10646), Unicode, Charset Label:unicode, Aliases:utf-16" },
+	{ "cpunicodeFFFE", 0x4B1, "Unicode UCS-2 Big-Endian, Unicode (Big-Endian), Charset Label:unicodeFFFE" },
+	{ "cpwindows1250", 0x4E2, "ANSI - Central European, Central European (Windows), Charset Label:windows-1250, Aliases:x-cp1250" },
+	{ "cpwindows1251", 0x4E3, "ANSI - Cyrillic, Cyrillic (Windows), Charset Label:windows-1251, Aliases:x-cp1251" },
+	{ "cpWindows1252", 0x4E4, "ANSI - Latin I, Western European (Windows), Charset Label:Windows-1252, Aliases:ANSI_X3.4-1968, ANSI_X3.4-1986, ascii, cp367, cp819, csASCII, IBM367, ibm819, ISO_646.irv:1991, iso_8859-1, iso_8859-1:1987, ISO646-US, iso8859-1, iso-8859-1, iso-ir-100, i..." },
+	{ "cpwindows1253", 0x4E5, "ANSI - Greek, Greek (Windows), Charset Label:windows-1253" },
+	{ "cpwindows1254", 0x4E6, "ANSI - Turkish, Turkish (Windows), Charset Label:windows-1254, Aliases:ISO_8859-9, ISO_8859-9:1989, iso-8859-9, iso-ir-148, latin5" },
+	{ "cpwindows1255", 0x4E7, "ANSI - Hebrew, Hebrew (Windows), Charset Label:windows-1255, Aliases:ISO_8859-8-I, ISO-8859-8, visual" },
+	{ "cpwindows1256", 0x4E8, "ANSI - Arabic, Arabic (Windows), Charset Label:windows-1256, Aliases:cp1256" },
+	{ "cpwindows1257", 0x4E9, "ANSI - Baltic, Baltic (Windows), Charset Label:windows-1257" },
+	{ "cpwindows1258", 0x4EA, "ANSI/OEM - Vietnamese, Vietnamese (Windows), Charset Label:windows-1258" },
+	{ "cpJohab", 0x551, "Korean (Johab), Korean (Johab), Charset Label:Johab" },
+	{ "cpmacintosh", 0x2710, "MAC - Roman, Western European (Mac), Charset Label:macintosh" },
+	{ "cpxmacjapanese", 0x2711, "MAC - Japanese, Japanese (Mac), Charset Label:x-mac-japanese" },
+	{ "cpxmacchinesetrad", 0x2712, "MAC - Traditional Chinese (Big5), Chinese Traditional (Mac), Charset Label:x-mac-chinesetrad" },
+	{ "cpxmackorean", 0x2713, "MAC - Korean, Korean (Mac), Charset Label:x-mac-korean" },
+	{ "cpxmacarabic", 0x2714, "MAC - Arabic, Arabic (Mac), Charset Label:x-mac-arabic" },
+	{ "cpxmachebrew", 0x2715, "MAC - Hebrew, Hebrew (Mac), Charset Label:x-mac-hebrew" },
+	{ "cpxmacgreek", 0x2716, "MAC - Greek I, Greek (Mac), Charset Label:x-mac-greek" },
+	{ "cpxmaccyrillic", 0x2717, "MAC - Cyrillic, Cyrillic (Mac), Charset Label:x-mac-cyrillic" },
+	{ "cpxmacchinesesimp", 0x2718, "MAC - Simplified Chinese (GB 2312), Chinese Simplified (Mac), Charset Label:x-mac-chinesesimp" },
+	{ "cpMACRomania", 0x271A, "MAC - Romania, " },
+	{ "cpMACUkraine", 0x2721, "MAC - Ukraine, " },
+	{ "cpMACThai", 0x2725, "MAC - Thai, " },
+	{ "cpxmacce", 0x272D, "MAC - Latin II, Central European (Mac), Charset Label:x-mac-ce" },
+	{ "cpxmacicelandic", 0x275F, "MAC - Icelandic, Icelandic (Mac), Charset Label:x-mac-icelandic" },
+	{ "cpxmacturkish", 0x2761, "MAC - Turkish, Turkish (Mac), Charset Label:x-mac-turkish" },
+	{ "cpMACCroatia", 0x2762, "MAC - Croatia, " },
+	{ "cpUnicodeUCS4LittleEndian", 0x2EE0, "Unicode UCS-4 Little-Endian, " },
+	{ "cpUnicodeUCS4BigEndian", 0x2EE1, "Unicode UCS-4 Big-Endian, " },
+	{ "cpxChineseCNS", 0x4E20, "CNS - Taiwan, Chinese Traditional (CNS), Charset Label:x-Chinese-CNS" },
+	{ "cpTCATaiwan", 0x4E21, "TCA - Taiwan, " },
+	{ "cpxChineseEten", 0x4E22, "Eten - Taiwan, Chinese Traditional (Eten), Charset Label:x-Chinese-Eten" },
+	{ "cpIBM5550Taiwan", 0x4E23, "IBM5550 - Taiwan, " },
+	{ "cpTeleTextTaiwan", 0x4E24, "TeleText - Taiwan, " },
+	{ "cpWangTaiwan", 0x4E25, "Wang - Taiwan, " },
+	{ "cpxIA5", 0x4E89, "IA5 IRV International Alphabet No. 5 (7-bit), Western European (IA5), Charset Label:x-IA5" },
+	{ "cpxIA5German", 0x4E8A, "IA5 German (7-bit), German (IA5), Charset Label:x-IA5-German" },
+	{ "cpxIA5Swedish", 0x4E8B, "IA5 Swedish (7-bit), Swedish (IA5), Charset Label:x-IA5-Swedish" },
+	{ "cpxIA5Norwegian", 0x4E8C, "IA5 Norwegian (7-bit), Norwegian (IA5), Charset Label:x-IA5-Norwegian" },
+	{ "cpusascii", 0x4E9F, "US-ASCII (7-bit), US-ASCII, Charset Label:us-ascii, Aliases:ANSI_X3.4-1968, ANSI_X3.4-1986, ascii, cp367, csASCII, IBM367, ISO_646.irv:1991, ISO646-US, iso-ir-6us" },
+	{ "cpT61", 0x4F25, "T.61, " },
+	{ "cpISO6937NonSpacingAccent", 0x4F2D, "ISO 6937 Non-Spacing Accent, " },
+	{ "cpxEBCDICGermany", 0x4F31, "IBM EBCDIC - Germany, IBM EBCDIC (Germany), Charset Label:x-EBCDIC-Germany" },
+	{ "cpxEBCDICDenmarkNorway", 0x4F35, "IBM EBCDIC - Denmark/Norway, IBM EBCDIC (Denmark-Norway), Charset Label:x-EBCDIC-DenmarkNorway" },
+	{ "cpxEBCDICFinlandSweden", 0x4F36, "IBM EBCDIC - Finland/Sweden, IBM EBCDIC (Finland-Sweden), Charset Label:x-EBCDIC-FinlandSweden" },
+	{ "cpxEBCDICItaly", 0x4F38, "IBM EBCDIC - Italy, IBM EBCDIC (Italy), Charset Label:x-EBCDIC-Italy" },
+	{ "cpXEBCDICSpain", 0x4F3C, "IBM EBCDIC - Latin America/Spain, IBM EBCDIC (Spain), Charset Label:X-EBCDIC-Spain" },
+	{ "cpxEBCDICUK", 0x4F3D, "IBM EBCDIC - United Kingdom, IBM EBCDIC (UK), Charset Label:x-EBCDIC-UK" },
+	{ "cpxEBCDICJapaneseKatakana", 0x4F42, "IBM EBCDIC - Japanese Katakana Extended, IBM EBCDIC (Japanese katakana), Charset Label:x-EBCDIC-JapaneseKatakana" },
+	{ "cpIBMEBCDICFrance", 0x4F49, "IBM EBCDIC - France, " },
+	{ "cpxEBCDICArabic", 0x4FC4, "IBM EBCDIC - Arabic, IBM EBCDIC (Arabic), Charset Label:x-EBCDIC-Arabic" },
+	{ "cpxEBCDICGreek", 0x4FC7, "IBM EBCDIC - Greek, IBM EBCDIC (Greek), Charset Label:x-EBCDIC-Greek" },
+	{ "cpxEBCDICHebrew", 0x4FC8, "IBM EBCDIC - Hebrew, IBM EBCDIC (Hebrew), Charset Label:x-EBCDIC-Hebrew" },
+	{ "cpxEBCDICKoreanExtended", 0x5161, "IBM EBCDIC - Korean Extended, IBM EBCDIC (Korean Extended), Charset Label:x-EBCDIC-KoreanExtended" },
+	{ "cpxEBCDICThai", 0x5166, "IBM EBCDIC - Thai, IBM EBCDIC (Thai), Charset Label:x-EBCDIC-Thai" },
+	{ "cpkoi8r", 0x5182, "Russian - KOI8-R, Cyrillic (KOI8-R), Charset Label:koi8-r, Aliases:csKOI8R, koi, koi8, koi8r" },
+	{ "cpxEBCDICIcelandic", 0x5187, "IBM EBCDIC - Icelandic, IBM EBCDIC (Icelandic), Charset Label:x-EBCDIC-Icelandic" },
+	{ "cpxEBCDICCyrillicRussian", 0x5190, "IBM EBCDIC - Cyrillic (Russian), IBM EBCDIC (Cyrillic Russian), Charset Label:x-EBCDIC-CyrillicRussian" },
+	{ "cpxEBCDICTurkish", 0x51A9, "IBM EBCDIC - Turkish, IBM EBCDIC (Turkish), Charset Label:x-EBCDIC-Turkish" },
+	{ "cpIBMEBCDICLatin1OpenSystem1047Eurosymbol", 0x51BC, "IBM EBCDIC - Latin-1/Open System (1047 + Euro symbol), " },
+	{ "cpJISX0208199001211990", 0x51C4, "JIS X 0208-1990 & 0121-1990, " },
+	{ "cpSimplifiedChineseGB2312", 0x51C8, "Simplified Chinese (GB2312), " },
+	{ "cpxEBCDICCyrillicSerbianBulgarian", 0x5221, "IBM EBCDIC - Cyrillic (Serbian, Bulgarian), IBM EBCDIC (Cyrillic Serbian-Bulgarian), Charset Label:x-EBCDIC-CyrillicSerbianBulgarian" },
+	{ "cpExtendedAlphaLowercase", 0x5223, "Extended Alpha Lowercase, " },
+	{ "cpkoi8u", 0x556A, "Ukrainian (KOI8-U), Cyrillic (KOI8-U), Charset Label:koi8-u, Aliases:koi8-ru" },
+	{ "cpiso88591", 0x6FAF, "ISO 8859-1 Latin I, Western European (ISO), Charset Label:iso-8859-1, Aliases:cp819, csISO, Latin1, ibm819, iso_8859-1, iso_8859-1:1987, iso8859-1, iso-ir-100, l1, latin1" },
+	{ "cpiso88592", 0x6FB0, "ISO 8859-2 Central Europe, Central European (ISO), Charset Label:iso-8859-2, Aliases:csISOLatin2, iso_8859-2, iso_8859-2:1987, iso8859-2, iso-ir-101, l2, latin2" },
+	{ "cpiso88593", 0x6FB1, "ISO 8859-3 Latin 3, Latin 3 (ISO), Charset Label:iso-8859-3, Aliases:csISO, Latin3, ISO_8859-3, ISO_8859-3:1988, iso-ir-109, l3, latin3" },
+	{ "cpiso88594", 0x6FB2, "ISO 8859-4 Baltic, Baltic (ISO), Charset Label:iso-8859-4, Aliases:csISOLatin4, ISO_8859-4, ISO_8859-4:1988, iso-ir-110, l4, latin4" },
+	{ "cpiso88595", 0x6FB3, "ISO 8859-5 Cyrillic, Cyrillic (ISO), Charset Label:iso-8859-5, Aliases:csISOLatin5, csISOLatinCyrillic, cyrillic, ISO_8859-5, ISO_8859-5:1988, iso-ir-144, l5" },
+	{ "cpiso88596", 0x6FB4, "ISO 8859-6 Arabic, Arabic (ISO), Charset Label:iso-8859-6, Aliases:arabic, csISOLatinArabic, ECMA-114, ISO_8859-6, ISO_8859-6:1987, iso-ir-127" },
+	{ "cpiso88597", 0x6FB5, "ISO 8859-7 Greek, Greek (ISO), Charset Label:iso-8859-7, Aliases:csISOLatinGreek, ECMA-118, ELOT_928, greek, greek8, ISO_8859-7, ISO_8859-7:1987, iso-ir-126" },
+	{ "cpiso88598", 0x6FB6, "ISO 8859-8 Hebrew, Hebrew (ISO-Visual), Charset Label:iso-8859-8, Aliases:csISOLatinHebrew, hebrew, ISO_8859-8, ISO_8859-8:1988, ISO-8859-8, iso-ir-138, visual" },
+	{ "cpiso88599", 0x6FB7, "ISO 8859-9 Latin 5, Turkish (ISO), Charset Label:iso-8859-9, Aliases:csISO, Latin5, ISO_8859-9, ISO_8859-9:1989, iso-ir-148, l5, latin5" },
+	{ "cpiso885915", 0x6FBD, "ISO 8859-15 Latin 9, Latin 9 (ISO), Charset Label:iso-8859-15, Aliases:csISO, Latin9, ISO_8859-15, l9, latin9" },
+	{ "cpxEuropa", 0x7149, "Europa 3, Europa, Charset Label:x-Europa" },
+	{ "cpiso88598i", 0x96C6, "ISO 8859-8 Hebrew, Hebrew (ISO-Logical), Charset Label:iso-8859-8-i, Aliases:logical" },
+	{ "cpiso2022jp", 0xC42C, "ISO 2022 Japanese with no halfwidth Katakana, Japanese (JIS), Charset Label:iso-2022-jp" },
+	{ "cpcsISO2022JP", 0xC42D, "ISO 2022 Japanese with halfwidth Katakana, Japanese (JIS-Allow 1 byte Kana), Charset Label:csISO2022JP, Aliases:_iso-2022-jp" },
+	{ "cpiso2022jp1", 0xC42E, "ISO 2022 Japanese JIS X 0201-1989, Japanese (JIS-Allow 1 byte Kana - SO/SI), Charset Label:iso-2022-jp-1, Aliases:_iso-2022-jp$SIO" },
+	{ "cpiso2022kr", 0xC431, "ISO 2022 Korean, Korean (ISO), Charset Label:iso-2022-kr, Aliases:csISO2022KR" },
+	{ "cpISO2022SimplifiedChinese", 0xC433, "ISO 2022 Simplified Chinese, " },
+	{ "cpISO2022TraditionalChinese", 0xC435, "ISO 2022 Traditional Chinese, " },
+	{ "cpxEBCDICJapaneseAndKana", 0xC6F2, "Japanese (Katakana) Extended, IBM EBCDIC (Japanese and Japanese Katakana), Charset Label:x-EBCDIC-JapaneseAndKana" },
+	{ "cpxEBCDICJapaneseAndUSCanada", 0xC6F3, "US/Canada and Japanese, IBM EBCDIC (Japanese and US-Canada), Charset Label:x-EBCDIC-JapaneseAndUSCanada" },
+	{ "cpxEBCDICKoreanAndKoreanExtended", 0xC6F5, "Korean Extended and Korean, IBM EBCDIC (Korean and Korean Extended), Charset Label:x-EBCDIC-KoreanAndKoreanExtended" },
+	{ "cpxEBCDICSimplifiedChinese", 0xC6F7, "Simplified Chinese Extended and Simplified Chinese, IBM EBCDIC (Simplified Chinese), Charset Label:x-EBCDIC-SimplifiedChinese" },
+	{ "cpSimplifiedChinese", 0xC6F8, "Simplified Chinese, " },
+	{ "cpxEBCDICTraditionalChinese", 0xC6F9, "US/Canada and Traditional Chinese, IBM EBCDIC (Traditional Chinese), Charset Label:x-EBCDIC-TraditionalChinese" },
+	{ "cpxEBCDICJapaneseAndJapaneseLatin", 0xC6FB, "Japanese (Latin) Extended and Japanese, IBM EBCDIC (Japanese and Japanese-Latin), Charset Label:x-EBCDIC-JapaneseAndJapaneseLatin" },
+	{ "cpeucjp", 0xCADC, "EUC - Japanese, Japanese (EUC), Charset Label:euc-jp, Aliases:csEUCPkdFmtJapanese, Extended_UNIX_Code_Packed_Format_for_Japanese, x-euc, x-euc-jp" },
+	{ "cpEUCCN", 0xCAE0, "EUC - Simplified Chinese, Chinese Simplified (EUC), Charset Label:EUC-CN, Aliases:x-euc-cn" },
+	{ "cpeuckr", 0xCAED, "EUC - Korean, Korean (EUC), Charset Label:euc-kr, Aliases:csEUCKR" },
+	{ "cpEUCTraditionalChinese", 0xCAEE, "EUC - Traditional Chinese, " },
+	{ "cphzgb2312", 0xCEC8, "HZ-GB2312 Simplified Chinese, Chinese Simplified (HZ), Charset Label:hz-gb-2312" },
+	{ "cpWindowsXPGB18030SimplifiedChinese4Byte", 0xD698, "Windows XP: GB18030 Simplified Chinese (4 Byte), " },
+	{ "cpxisciide", 0xDEAA, "ISCII Devanagari, ISCII Devanagari, Charset Label:x-iscii-de" },
+	{ "cpxisciibe", 0xDEAB, "ISCII Bengali, ISCII Bengali, Charset Label:x-iscii-be" },
+	{ "cpxisciita", 0xDEAC, "ISCII Tamil, ISCII Tamil, Charset Label:x-iscii-ta" },
+	{ "cpxisciite", 0xDEAD, "ISCII Telugu, ISCII Telugu, Charset Label:x-iscii-te" },
+	{ "cpxisciias", 0xDEAE, "ISCII Assamese, ISCII Assamese, Charset Label:x-iscii-as" },
+	{ "cpxisciior", 0xDEAF, "ISCII Oriya, ISCII Oriya, Charset Label:x-iscii-or" },
+	{ "cpxisciika", 0xDEB0, "ISCII Kannada, ISCII Kannada, Charset Label:x-iscii-ka" },
+	{ "cpxisciima", 0xDEB1, "ISCII Malayalam, ISCII Malayalam, Charset Label:x-iscii-ma" },
+	{ "cpxisciigu", 0xDEB2, "ISCII Gujarati, ISCII Gujarathi, Charset Label:x-iscii-gu" },
+	{ "cpxisciipa", 0xDEB3, "ISCII Punjabi, ISCII Panjabi, Charset Label:x-iscii-pa" },
+	{ "cputf7", 0xFDE8, "Unicode UTF-7, Unicode (UTF-7), Charset Label:utf-7, Aliases:csUnicode11UTF7, unicode-1-1-utf-7, x-unicode-2-0-utf-7" },
+	{ "cputf8", 0xFDE9, "Unicode UTF-8, Unicode (UTF-8), Charset Label:utf-8, Aliases:unicode-1-1-utf-8, unicode-2-0-utf-8, x-unicode-2-0-utf-8" },
+	{NULL, 0, NULL}
+};
+
+/*
+ Check for a valid codepage
+*/
+
+_PUBLIC_ bool valid_codepage(uint32_t cpid)
+{
+	uint32_t idx = 0;
+
+	while (codepages[idx].cp_name) {
+		if (codepages[idx].cpid == cpid) {
+			return true;
+		}
+		idx++;
+	}
+	return false;
+}
+
+bool print_codepage_infos(uint32_t cpid)
+{
+	uint32_t idx = 0;
+
+	if (valid_codepage(cpid) == false) {
+		return false;
+	}
+	
+	while (codepages[idx].cp_name) {
+		if (codepages[idx].cpid == cpid) {
+			printf("\t%-25s: 0x%x\n", CP_VAL, cpid);
+			printf("\t%-25s: %s\n", CP_NAME, codepages[idx].cp_name);
+			printf("\t%-25s: %s\n", CP_DESC, codepages[idx].cp_desc);
+			return true;
+		}
+		idx++;
+	}
+	return false;
+}

Added: trunk/openchange/libmapi/util/lcid.c
===================================================================
--- trunk/openchange/libmapi/util/lcid.c	                        (rev 0)
+++ trunk/openchange/libmapi/util/lcid.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,460 @@
+/*
+   OpenChange MAPI implementation.
+   Codepages handled by Microsoft Exchange Server
+
+   Copyright (C) Julien Kerihuel 2005.
+
+   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 <libmapi/proto_private.h>
+
+#define	CP_WESTERN_EUROPE_AND_US	1	/* 1  (Western Europe & US) */
+#define	CP_CENTRAL_EUROPE		2	/* 2  (Central Europe) */
+#define	CP_BALTIC			3   	/* 3  (Baltic) */
+#define	CP_GREEK			4	/* 4  (Greek) */
+#define	CP_CYRILLIC			5	/* 5  (Cyrillic) */
+#define	CP_TURKIC			6	/* 6  (Turkic) */
+#define	CP_JAPENESE			7   	/* 7  (Japanese) */
+#define	CP_KOREAN			8   	/* 8  (Korean) */
+#define	CP_TRADITIONAL_CHINESE		9   	/* 9  (Traditional Chinese) */
+#define	CP_SIMPLIFIED_CHINESE		10	/* 10 (Simplified Chinese) */
+#define	CP_THAI				11  	/* 11 (Thai) */
+#define	CP_HEBREW			12  	/* 12 (Hebrew) */
+#define	CP_ARABIC			13  	/* 13 (Arabic) */
+#define	CP_VIETNAMESE			14  	/* 14 (Vietnamese) */
+#define	CP_INDIC			15  	/* 15 (Indic) */
+#define	CP_GEORGIAN			16  	/* 16 (Georgian) */
+#define	CP_ARMENIAN			17   	/* 17 (Armenian) */
+
+#define	LANG_GROUP		"language group"
+#define	LOCALE_ID		"locale id"
+#define	INPUT_COMBINATIONS	"input combinations"
+
+static const char *language_group[] = 
+{
+	"CP_NONEXISTENT",
+	"CP_WESTERN_EUROPE_AND_US",
+	"CP_CENTRAL_EUROPE",
+	"CP_BALTIC",
+	"CP_GREEK",
+	"CP_CYRILLIC",
+	"CP_TURKIC",
+	"CP_JAPANESE",
+	"CP_KOREAN",
+	"CP_TRADITIONAL_CHINESE",
+	"CP_SIMPLIFIED_CHINESE",
+	"CP_THAI",
+	"CP_HEBREW",
+	"CP_ARABIC",
+	"CP_VIETNAMESE",
+	"CP_INDIC",
+	"CP_GEORGIAN",
+	"CP_ARMENIAN",
+	NULL
+};
+
+struct combination {
+	uint32_t	lcid;
+	uint32_t	input_locale;
+};
+
+struct locale_struct {
+	const char		*locale_str;
+	uint32_t		lcid;
+	const char		*lang_tag; /* RFC4646 language tag */
+	int			language_group;
+	struct combination	combination[6];
+};
+
+/*
+Missing entries from this table (compared to MS-LCID v20081024:
+ - everything from 0x0001 to 0x0091
+ - 0x0417 =-> rm-CH
+ - 0x0428 =-> tg-Cyrl-TJ
+ - 0x042E =-> wen-DE
+ - 0x0430 to 0x0435 (*-ZA)
+ - 0x043A =-> mt-MT
+ - 0x043B =-> se-NO
+ - 0x0440 =-> ky-KG
+ - 0x0442 =-> tk-TM
+ - 0x0445 =-> bn-IN
+ - 0x0446 =-> pa-IN
+ - 0x0447 =-> gu-IN
+ - 0x0448 =-> or-IN
+ - 0x044A =-> te-IN
+ - 0x044B =-> kn-IN
+ - 0x044C =-> ml-IN
+ - 0x044D =-> as-IN
+ - 0x0450 =-> mn-MN
+ - 0x0451 =-> bo-CN
+ - 0x0452 =-> cy-GB
+ - 0x0453 =-> km-KH
+ - 0x0454 =-> lo-LA
+ - 0x0455 =-> my-MM
+ - 0x0456 =-> gl-ES
+ - everything between 0x0458 and 0x048D
+ - 0x0818 =-> ro-MO
+ - 0x0819 =-> ru-MO
+ - 0x0820 =-> ur-IN
+ - 0x082E =-> dsb-DE
+ - 0x083B =-> se-SE
+ - 0x083C =-> ga-IE
+ - 0x0845 =-> bn-BD
+ - 0x0846 =-> pa-PK
+ - 0x0850 =-> mn-Mong-CN
+ - 0x0851 =-> bo-BT
+ - 0x0859 =-> sd-PK
+ - 0x085D =-> iu-Latn-CA
+ - 0x085F =-> tzm-Latn-DZ
+ - 0x0861 =-> ne-IN
+ - 0x086B =-> quz-EC
+ - 0x0873 =-> ti-ET
+ - 0x0C3B =-> se-FI
+ - 0x0C5F =-> tmz-MA
+ - 0x0C6B =-> quz-PE
+ - 0x101A =-> hr-BA
+ - 0x103B =-> smj-NO
+ - 0x141A =-> bs-Latn-BA
+ - 0x143B =-> smj-SE
+ - 0x181A =-> sr-Latn-BA
+ - 0x183B =-> sma-NO
+ - 0x1C0C =-> fr-West Indies
+ - 0x1C1A =-> sr-Cyrl-BA
+ - 0x1C3B =-> sma-SE
+ - 0x200C =-> fr-RE
+ - 0x201A =-> bs-Cyrl->BA
+ - 0x203b =-> sms-FI
+ - 0x240c =-> fr-CG
+ - 0x243B =-> smn-FI
+ - 0x280C =-> fr-SN
+ - 0x2C0C =-> fr-CM
+ - 0x300C =-> fr-CI
+ - 0x340C =-> fr-ML
+ - 0x3809 =-> en-ID
+ - 0x380C =-> fr-MA
+ - 0x3C09 =-> en-HK
+ - 0x3C0C =-> fr-HT
+ - 0x4009 =-> en-IN
+ - 0x4409 =-> en-MY
+ - 0x4809 =-> en-SG
+ - everything from 0x540a to 0x7c68 (and after)
+*/
+static const struct locale_struct locales[] =
+{
+	{ "Afrikaans", 0x436, "af-ZA", CP_WESTERN_EUROPE_AND_US, { {0x436, 0x409}, {0x409, 0x409}, {0, 0} } },
+	{ "Albanian", 0x41c, "sq-AL", CP_CENTRAL_EUROPE, { {0x41c, 0x41c}, {0x409, 0x409}, {0, 0} } },
+	{ "Arabic_Saudi_Arabia", 0x401, "ar-SA", CP_ARABIC, { {0x409, 0x409},  {0x401, 0x401}, {0, 0} } },
+	{ "Arabic_Iraq", 0x801, "ar-IQ", CP_ARABIC, { {0x409, 0x409}, {0x801, 0x401}, {0, 0} } },
+	{ "Arabic_Egypt", 0xc01, "ar-EG", CP_ARABIC, { {0x409, 0x409}, {0xc01, 0x401}, {0, 0} } },
+	{ "Arabic_Libya ", 0x1001, "ar-LY", CP_ARABIC, { {0x40c, 0x40c}, {0x1001, 0x20401}, {0, 0} } },
+	{ "Arabic_Algeria", 0x1401, "ar-DZ", CP_ARABIC, { {0x40c, 0x40c}, {0x1401, 0x20401}, {0, 0} } },
+	{ "Arabic_Morocco", 0x1801, "ar-MA", CP_ARABIC, { {0x40c, 0x40c}, {0x1801, 0x20401}, {0, 0} } },
+	{ "Arabic_Tunisia", 0x1c01, "ar-TN", CP_ARABIC, { {0x40c, 0x40c}, {0x1c01, 0x20401}, {0, 0} } },
+	{ "Arabic_Oman", 0x2001, "ar-OM", CP_ARABIC, { {0x409, 0x409}, {0x2001, 0x401}, {0, 0} } },
+	{ "Arabic_Yemen", 0x2401, "ar-YE", CP_ARABIC, { {0x409, 0x409}, {0x2401, 0x401}, {0, 0} } },
+	{ "Arabic_Syria", 0x2801, "ar-SY", CP_ARABIC, { {0x409,0x409}, {0x2801, 0x401}, {0, 0} } },
+	{ "Arabic_Jordan", 0x2c01, "ar-JO", CP_ARABIC, { {0x409, 0x409}, {0x2c01, 0x401}, {0, 0} } },
+	{ "Arabic_Lebanon", 0x3001, "ar-LB", CP_ARABIC, { {0x409, 0x409}, {0x3001, 0x401}, {0, 0} } },
+	{ "Arabic_Kuwait", 0x3401, "ar-KW", CP_ARABIC, { {0x409, 0x409}, {0x3401, 0x401}, {0, 0} } },
+	{ "Arabic_UAE", 0x3801, "ar-AE", CP_ARABIC, { {0x409, 0x409}, {0x3801, 0x401}, {0, 0} } },
+	{ "Arabic_Bahrain", 0x3c01, "ar-BH", CP_ARABIC, { {0x409, 0x409}, {0x3c01, 0x401}, {0, 0} } },
+	{ "Arabic_Qatar", 0x4001, "ar-QA", CP_ARABIC, { {0x409, 0x409}, {0x4001, 0x401}, {0, 0} } },
+	{ "Armenian", 0x42b, "hy-AM", CP_ARMENIAN, { {0x42b, 0x42b}, {0x409, 0x409}, {0x419,0x419}, {0, 0} } },
+	{ "Azeri_Latin", 0x42c, "az-Latn-AZ", CP_TURKIC, { {0x42c, 0x42c}, {0x82c, 0x82c}, {0x419, 0x419}, {0, 0} } },
+	{ "Azeri_Cyrillic", 0x82c, "az-Cyrl-AZ", CP_CYRILLIC, { {0x82c, 0x82c}, {0x42c, 0x42c}, {0x419, 0x419}, {0, 0} } },
+	{ "Basque", 0x42d, "eu-ES", CP_WESTERN_EUROPE_AND_US, { {0x42d, 0x40a}, {0x409, 0x409}, {0, 0} } },
+	{ "Belarusian", 0x423, "be-BY", CP_CYRILLIC, { {0x423, 0x423}, {0x409, 0x409}, {0x419, 0x419}, {0, 0} } },
+	{ "Bulgarian", 0x402, "bg-BG", CP_CYRILLIC, { {0x402, 0x402}, {0x409, 0x409}, {0, 0} } },
+	{ "Catalan", 0x403, "ca-ES", CP_WESTERN_EUROPE_AND_US, { {0x403, 0x40a}, {0x409, 0x409}, {0, 0} } },
+	{ "Chinese_Taiwan", 0x404, "zh-TW", CP_TRADITIONAL_CHINESE, { {0x404, 0x404}, {0x404, 0xe0080404}, {0x404, 0xe0010404}, {0, 0} } },
+	{ "Chinese_PRC", 0x804, "zh-CN", CP_SIMPLIFIED_CHINESE, { {0x804, 0x804}, {0x804, 0xe00e0804}, {0x804, 0xe0010804}, {0x804, 0xe0030804}, {0x804, 0xe0040804}, {0, 0} } },
+	{ "Chinese_Hong_Kong", 0xc04, "zh-HK", CP_TRADITIONAL_CHINESE, { {0x409, 0x409}, {0xc04, 0xe0080404}, {0, 0} } },
+	{ "Chinese_Singapore", 0x1004, "zh-SG", CP_SIMPLIFIED_CHINESE, { {0x409, 0x409}, {0x804, 0xe00e0804}, {0x804, 0xe0010804}, {0x804, 0xe0030804}, {0x804, 0xe0040804}, {0, 0} } },
+	{ "Chinese_Macau", 0x1404, "zh-MO", CP_TRADITIONAL_CHINESE, { {0x409, 0x409}, {0x804, 0xe00e0804}, {0x404, 0xe0020404}, {0x404, 0xe0080404}, {0, 0} } },
+	{ "Croatian", 0x41a, "hr-HR", CP_CENTRAL_EUROPE, { {0x41a, 0x41a}, {0x409, 0x409}, {0, 0} } },
+	{ "Czech", 0x405, "cz-CZ", CP_CENTRAL_EUROPE, { {0x405, 0x405}, {0x409, 0x409}, {0, 0} } },
+	{ "Danish", 0x406, "da-DK", CP_WESTERN_EUROPE_AND_US, { {0x406, 0x406}, {0x409, 0x409}, {0, 0} } },
+	{ "Dutch_Standard", 0x413, "nl-NL", CP_WESTERN_EUROPE_AND_US, { {0x409, 0x20409}, {0x413, 0x413}, {0x409, 0x409}, {0, 0} } },
+	{ "Dutch_Belgian", 0x813, "nl-BE", CP_WESTERN_EUROPE_AND_US, { {0x813, 0x813}, {0x409, 0x409}, {0, 0} } },
+	{ "English_United_States", 0x409, "en-US", CP_WESTERN_EUROPE_AND_US, { {0x409, 0x409}, {0, 0} } },
+	{ "English_United_Kingdom", 0x809, "en-GB", CP_WESTERN_EUROPE_AND_US, { {0x809, 0x809}, {0, 0} } },
+	{ "English_Australia", 0xc09, "en-AU", CP_WESTERN_EUROPE_AND_US, { {0xc09, 0x409}, {0, 0} } },
+	{ "English_Canada", 0x1009, "en-CA", CP_WESTERN_EUROPE_AND_US, { {0x1009, 0x409}, {0x1009, 0x11009}, {0x1009, 0x1009}, {0, 0} } },
+	{ "English_New_Zealand", 0x1409, "en-NZ", CP_WESTERN_EUROPE_AND_US, { {0x1409, 0x409}, {0, 0} } },
+	{ "English_Ireland", 0x1809, "en-IE", CP_WESTERN_EUROPE_AND_US, { {0x1809, 0x1809}, {0x1809, 0x11809}, {0, 0} } },
+	{ "English_South_Africa", 0x1c09, "en-ZA", CP_WESTERN_EUROPE_AND_US, { {0x1c09, 0x409}, {0, 0} } },
+	{ "English_Jamaica", 0x2009, "en-JM", CP_WESTERN_EUROPE_AND_US, { {0x2009, 0x409}, {0, 0} } },
+	{ "English_Caribbean", 0x2409, "en-CB", CP_WESTERN_EUROPE_AND_US, { {0x2409, 0x409}, {0, 0} } },
+	{ "English_Belize", 0x2809, "en-BZ", CP_WESTERN_EUROPE_AND_US, { {0x2809, 0x409}, {0, 0} } },
+	{ "English_Trinidad", 0x2c09, "en-TT", CP_WESTERN_EUROPE_AND_US, { {0x2c09, 0x409}, {0, 0} } },
+	{ "English_Zimbabwe", 0x3009, "en-ZW", CP_WESTERN_EUROPE_AND_US, { {0x3009, 0x409}, {0, 0} } },
+	{ "English_Philippines", 0x3409, "en-PH", CP_WESTERN_EUROPE_AND_US, { {0x3409, 0x409}, {0, 0} } },
+	{ "Estonian", 0x425, "et-EE", CP_BALTIC, { {0x425, 0x425}, {0, 0} } },
+	{ "Faeroese", 0x438, "fo-FO", CP_WESTERN_EUROPE_AND_US, { {0x438, 0x406}, {0x409, 0x409}, {0, 0} } },
+	{ "Farsi", 0x429, "fa-IR", CP_ARABIC, { {0x409, 0x409}, {0x429, 0x429}, {0x429, 0x401}, {0, 0} } },
+	{ "Finnish", 0x40b, "fi-FI", CP_WESTERN_EUROPE_AND_US, { {0x40b, 0x40b}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Standard", 0x40c, "fr-FR", CP_WESTERN_EUROPE_AND_US, { {0x40c, 0x40c}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Belgian", 0x80c, "fr-BE", CP_WESTERN_EUROPE_AND_US, { {0x80c, 0x80c}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Canadian", 0xc0c, "fr-CA", CP_WESTERN_EUROPE_AND_US, { {0xc0c, 0x11009}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Swiss", 0x100c, "fr-CH", CP_WESTERN_EUROPE_AND_US, { {0x100c, 0x100c}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Luxembourg", 0x140c, "fr-LU", CP_WESTERN_EUROPE_AND_US, { {0x140c, 0x40c}, {0x409, 0x409}, {0, 0} } },
+	{ "French_Monaco", 0x180c, "fr-MC", CP_WESTERN_EUROPE_AND_US, { {0x180c, 0x40c}, {0x409, 0x409}, {0, 0} } },
+	{ "Georgian", 0x437, "ka-GE", CP_GEORGIAN, { {0x437, 0x437}, {0x409, 0x409}, {0x419, 0x419}, {0, 0} } },
+	{ "German_Standard", 0x407, "de-DE", CP_WESTERN_EUROPE_AND_US, { {0x407, 0x407}, {0x409, 0x409}, {0, 0} } },
+	{ "German_Swiss", 0x807, "de-CH", CP_WESTERN_EUROPE_AND_US, { {0x807, 0x807}, {0x409, 0x409}, {0, 0} } },
+	{ "German_Austria", 0xc07, "de-AT", CP_WESTERN_EUROPE_AND_US, { {0xc07, 0x407}, {0x409, 0x409}, {0, 0} } },
+	{ "German_Luxembourg", 0x1007, "de-LU", CP_WESTERN_EUROPE_AND_US, { {0x1007, 0x407}, {0x409, 0x409}, {0, 0} } },
+	{ "German_Liechtenstein", 0x1407, "de-LI", CP_WESTERN_EUROPE_AND_US, { {0x1407, 0x407}, {0x409, 0x409}, {0, 0} } },
+	{ "Greek", 0x408, "el-GR", CP_GREEK, { {0x409, 0x409}, {0x408, 0x408}, {0, 0} } },
+	{ "Hebrew", 0x40d, "he-IL", CP_HEBREW, { {0x409, 0x409}, {0x40d, 0x40d}, {0, 0} } },
+	{ "Hindi", 0x439, "hi-IN", CP_INDIC, { {0x409, 0x409}, {0x439, 0x10439}, {0x439, 0x439}, {0, 0} } },
+	{ "Hungarian", 0x40e, "hu-HU", CP_CENTRAL_EUROPE, { {0x40e, 0x40e}, {0x409, 0x409}, {0, 0} } },
+	{ "Icelandic", 0x40f, "is-IS", CP_WESTERN_EUROPE_AND_US, { {0x40f, 0x40f}, {0x409, 0x409}, {0, 0} } },
+	{ "Indonesian", 0x421, "id-ID", CP_WESTERN_EUROPE_AND_US, { {0x421, 0x409}, {0x409, 0x409}, {0, 0} } },
+	{ "Italian_Standard", 0x410, "it-IT", CP_WESTERN_EUROPE_AND_US, { {0x410, 0x410}, {0x409, 0x409}, {0, 0} } },
+	{ "Italian_Swiss", 0x810, "it-CH", CP_WESTERN_EUROPE_AND_US, { {0x810, 0x410}, {0x409, 0x409}, {0, 0} } },
+	{ "Japanese", 0x411, "ja-JP", CP_JAPENESE, { {0x411, 0xe0010411}, {0, 0} } },
+	{ "Kazakh", 0x43f, "kk-KZ", CP_CYRILLIC, { {0x43f, 0x43f}, {0x409, 0x409}, {0x419, 0x419}, {0, 0} } },
+	{ "Konkani", 0x457, "kok-IN", CP_INDIC, { {0x409, 0x409}, {0x457, 0x439}, {0, 0} } },
+	{ "Korean", 0x412, "ko-KR", CP_KOREAN, { {0x412, 0xe0010412}, {0, 0} } },
+	{ "Latvian", 0x426, "lv-LV", CP_BALTIC, { {0x426, 0x10426}, {0, 0} } },
+	{ "Lithuanian", 0x427, "lt-LT", CP_BALTIC, { {0x427, 0x10427}, {0, 0} } },
+	{ "Macedonian", 0x42f, "mk-MK", CP_CYRILLIC, { {0x42f, 0x42f}, {0x409, 0x409}, {0, 0} } },
+	{ "Malay_Malaysia", 0x43e, "ms-MY", CP_WESTERN_EUROPE_AND_US, { {0x409, 0x409}, {0, 0} } },
+	{ "Malay_Brunei_Darussalam", 0x83e, "ms-BN", CP_WESTERN_EUROPE_AND_US, { {0x409, 0x409}, {0, 0} } },
+	{ "Marathi", 0x44e, "mr-IN", CP_INDIC, { {0x409, 0x409}, {0x44e, 0x44e}, {0x44e, 0x439}, {0, 0} } },
+	{ "Norwegian_Bokmal", 0x414, "nb-NO", CP_WESTERN_EUROPE_AND_US, { {0x414, 0x414}, {0x409, 0x409}, {0, 0} } },
+	{ "Norwegian_Nynorsk", 0x814, "nn-NO", CP_WESTERN_EUROPE_AND_US, { {0x814, 0x414}, {0x409, 0x409}, {0, 0} } },
+	{ "Polish", 0x415, "pl-PL", CP_CENTRAL_EUROPE, { {0x415, 0x10415}, {0x415, 0x415}, {0x409, 0x409}, {0, 0} } },
+	{ "Portuguese_Brazilian", 0x416, "pt-BR", CP_WESTERN_EUROPE_AND_US, { {0x416, 0x416}, {0x409, 0x409}, {0, 0} } },
+	{ "Portuguese_Standard", 0x816, "pt-PT", CP_WESTERN_EUROPE_AND_US, { {0x816, 0x816}, {0x409, 0x409}, {0, 0} } },
+	{ "Romanian", 0x418, "ro-RM", CP_CENTRAL_EUROPE, { {0x418, 0x418}, {0x409, 0x409}, {0, 0} } },
+	{ "Russian", 0x419, "ru-RU", CP_CYRILLIC, { {0x419, 0x419}, {0x409, 0x409}, {0, 0} } },
+	{ "Sanskrit", 0x44f, "sa-IN", CP_INDIC, { {0x409, 0x409}, {0x44f, 0x439}, {0, 0} } },
+	{ "Serbian_Latin", 0x81a, "sr-Latn-CS", CP_CENTRAL_EUROPE, { {0x81a, 0x81a}, {0x409, 0x409}, {0, 0} } },
+	{ "Serbian_Cyrillic", 0xc1a, "sr-Cyrl-CS", CP_CYRILLIC, { {0xc1a, 0xc1a}, {0x409, 0x409}, {0, 0} } },
+	{ "Slovak", 0x41b, "sk-SK", CP_CENTRAL_EUROPE, { {0x41b, 0x41b}, {0x409, 0x409}, {0, 0}, {0, 0} } },
+	{ "Slovenian", 0x424, "sl-SI", CP_CENTRAL_EUROPE, { {0x424, 0x424}, {0x409, 0x409}, {0, 0}, {0, 0} } },
+	{ "Spanish_Traditional_Sort", 0x40a, "es-ES_tradnl", CP_WESTERN_EUROPE_AND_US, { {0x40a, 0x40a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Mexican", 0x80a, "es-MX", CP_WESTERN_EUROPE_AND_US, { {0x80a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Modern_Sort", 0xc0a, "es-ES", CP_WESTERN_EUROPE_AND_US, { {0xc0a, 0x40a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Guatemala", 0x100a, "es-GT", CP_WESTERN_EUROPE_AND_US, { {0x100a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Costa_Rica", 0x140a, "es-CR", CP_WESTERN_EUROPE_AND_US, { {0x140a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Panama", 0x180a, "es-PA", CP_WESTERN_EUROPE_AND_US, { {0x180a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Dominican_Republic", 0x1c0a, "es-DO", CP_WESTERN_EUROPE_AND_US, { {0x1c0a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Venezuela", 0x200a, "es-VE", CP_WESTERN_EUROPE_AND_US, { {0x200a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Colombia", 0x240a, "es-CO", CP_WESTERN_EUROPE_AND_US, { {0x240a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Peru", 0x280a, "es-PE", CP_WESTERN_EUROPE_AND_US, { {0x280a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Argentina", 0x2c0a, "es-AR", CP_WESTERN_EUROPE_AND_US, { {0x2c0a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Ecuador", 0x300a, "es-EC", CP_WESTERN_EUROPE_AND_US, { {0x300a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Chile", 0x340a, "es-CL", CP_WESTERN_EUROPE_AND_US, { {0x340a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Uruguay", 0x380a, "es-UY",CP_WESTERN_EUROPE_AND_US, { {0x380a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Paraguay", 0x3c0a, "es-PY", CP_WESTERN_EUROPE_AND_US, { {0x3c0a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Bolivia", 0x400a, "es-BO", CP_WESTERN_EUROPE_AND_US, { {0x400a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_El_Salvador", 0x440a, "es-SV", CP_WESTERN_EUROPE_AND_US, { {0x440a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Honduras", 0x480a, "es-HN", CP_WESTERN_EUROPE_AND_US, { {0x480a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Nicaragua", 0x4c0a, "es-NI", CP_WESTERN_EUROPE_AND_US, { {0x4c0a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Spanish_Puerto_Rico", 0x500a, "es-PR", CP_WESTERN_EUROPE_AND_US, { {0x500a, 0x80a}, {0x409, 0x409}, {0, 0} } },
+	{ "Swahili", 0x441, "sw-KE", CP_WESTERN_EUROPE_AND_US, { {0x409, 0x409}, {0, 0} } },
+	{ "Swedish", 0x41d, "sv-SE", CP_WESTERN_EUROPE_AND_US, { {0x41d, 0x41d}, {0x409, 0x409}, {0, 0} } },
+	{ "Swedish_Finland", 0x81d, "sv-FI", CP_WESTERN_EUROPE_AND_US, { {0x81d, 0x41d}, {0x409, 0x409}, {0, 0} } },
+	{ "Tamil", 0x449, "ta-IN", CP_INDIC, { {0x409, 0x409}, {0x449, 0x449}, {0, 0} } },
+	{ "Tatar", 0x444, "tt-RU", CP_CYRILLIC, { {0x444, 0x444}, {0x409, 0x409}, {0x419, 0x419}, {0, 0} } },
+	{ "Thai", 0x41e, "th-TH", CP_THAI, { {0x409, 0x409}, {0x41e, 0x41e}, {0, 0} } },
+	{ "Turkish", 0x41f, "tr-TR", CP_TURKIC, { {0x41f, 0x41f}, {0x409, 0x41f}, {0, 0} } },
+	{ "Ukrainian", 0x422, "uk-UA", CP_CYRILLIC, { {0x422, 0x422}, {0x409, 0x409}, {0, 0} } },
+	{ "Urdu", 0x420, "ur-PK", CP_ARABIC, { {0x420, 0x401}, {0x409, 0x409}, {0, 0} } },
+	{ "Uzbek_Latin", 0x443, "uz-Latn-UZ", CP_TURKIC, { {0x443, 0x409}, {0x843, 0x843}, {0x419, 0x419}, {0, 0} } },
+	{ "Uzbek_Cyrillic", 0x843, "uz-Cyrl-UZ", CP_CYRILLIC, { {0x843, 0x843}, {0x443, 0x409}, {0x419, 0x419}, {0, 0} } },
+	{ "Vietnamese", 0x42a, "vi-VN", CP_VIETNAMESE, { {0x409, 0x409}, {0x42a, 0x42a}, {0, 0} } },
+	{ NULL, 0, NULL, 0, { { 0, 0 } } }
+};
+
+/*
+  Print locale_id information for a given Language
+*/
+
+_PUBLIC_ bool lcid_get_locales(const char *lang)
+{
+	int idx = 0;
+	
+	if (!lang) {
+		return false;
+	}
+		
+	while (locales[idx].locale_str != NULL) {
+		if (!strcmp(lang, locales[idx].locale_str)) {
+			DEBUG(0, ("locale:language = 0x%x\n", locales[idx].lcid));
+			/* Fix me */
+			DEBUG(0, ("locale:method = 0x%x\n", locales[idx].combination[1].lcid));
+			return true;
+		}
+		idx++;
+	}
+	return false;
+}
+
+/*
+  Check if the locale provided exists
+*/
+
+_PUBLIC_ bool lcid_valid_locale(uint32_t locale)
+{
+	int idx = 0;
+
+	while (locales[idx].locale_str != NULL) {
+		if (locales[idx].lcid == locale)
+			return true;
+		idx++;
+	}
+	return false;
+}
+
+/*
+  Find the short language code for a given language code
+*/
+
+_PUBLIC_ const char *lcid_langcode2langtag(uint32_t langcode)
+{
+	int idx = 0;
+
+	while (locales[idx].locale_str != NULL) {
+		if (locales[idx].lcid == langcode)
+			return locales[idx].lang_tag;
+		idx++;
+	}
+	return NULL;
+}
+
+/*
+  Print locale information for a given locale id
+ */
+
+_PUBLIC_ bool lcid_print_locale(uint32_t locale)
+{
+	int idx = 0;
+	int i = 0;
+
+	while (locales[idx].locale_str != NULL) {
+		if (locales[idx].lcid == locale) {
+			printf("%s:\n", locales[idx].locale_str);
+			printf("\t%-25s:    %s\n", LANG_GROUP, language_group[locales[idx].language_group]);
+			printf("\t%-25s:    0x%x\n", LOCALE_ID, locales[idx].lcid);
+			printf("\t%-25s:\n", INPUT_COMBINATIONS);
+			for (i = 0; locales[idx].combination[i].lcid != 0; i++) {
+				printf("\t\t\t\t      0x%x:0x%x\n", 
+				       locales[idx].combination[i].lcid,
+				       locales[idx].combination[i].input_locale);
+			}
+			return true;
+		}
+		idx++;
+	}
+	return false;
+}
+
+/*
+  Print all languages
+*/
+_PUBLIC_ void lcid_print_languages(void)
+{
+	int idx = 0;
+
+	while (locales[idx].locale_str != NULL) {
+		printf("\t%s\n", locales[idx].locale_str);
+		idx++;
+	}
+}
+
+/*
+  Convert language name (as a string) to an integer language code
+ */
+
+_PUBLIC_ uint32_t lcid_lang2lcid(const char *name)
+{
+	int idx = 0;
+
+	if (!name) {
+		return 0xFFFFFFFF;
+	}
+		
+	while (locales[idx].locale_str != NULL) {
+		if (strncasecmp(locales[idx].locale_str, name, strlen(name)) == 0) {
+			// we found a match
+			return locales[idx].lcid;
+		}
+		idx++;
+	}
+	return 0xFFFFFFFF;
+}
+
+/*
+  Print language groups
+ */
+
+_PUBLIC_ void lcid_print_group(void)
+{
+	int idx = 1;
+
+	while (language_group[idx]) {
+		printf("\t\t%s\n", language_group[idx]);
+		idx++;
+	}
+}
+
+/*
+  Print languages associated to a single language group
+ */
+
+_PUBLIC_ bool lcid_print_groupmember(int group)
+{
+	uint32_t idx = 0;
+
+	if (group == -1) {
+	  DEBUG(0, ("Invalid language group "));
+	  return false;
+	}
+
+	DEBUG(0, ("%s:\n", language_group[group]));
+
+	for (idx = 0; locales[idx].locale_str != NULL; idx++) {
+		if (locales[idx].language_group == group) {
+			printf("\t\t\t%s\n", locales[idx].locale_str);
+		}
+	}
+	return true;
+}
+
+/*
+  Convert language group from string to integer
+ */
+
+_PUBLIC_ int lcid_lang2nb(const char *name)
+{
+	int		idx = 0;
+
+	if (!name) {
+		return -1;
+	}
+		
+	while (language_group[idx]) {
+		if (!strcmp(language_group[idx], name)) {
+			return idx++;
+		}
+		idx++;
+	}
+	return -1;
+}

Added: trunk/openchange/libmapi/utils.c
===================================================================
--- trunk/openchange/libmapi/utils.c	                        (rev 0)
+++ trunk/openchange/libmapi/utils.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,156 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005 - 2006.
+
+   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 <libmapi/proto_private.h>
+#include <gen_ndr/ndr_exchange.h>
+
+/*
+  Constructs a PR_ENTRYID value for recipients.
+ */
+
+/* 
+   FIXME: 
+   nor     0x00 0x00 0x00 0x00 at the beginning 
+   neither 0x2f at the end should be listed 
+*/
+static const uint8_t MAPI_LOCAL_UID[] = {
+	0xdc, 0xa7, 0x40, 0xc8, 0xc0, 0x42, 0x10, 0x1a,
+	0xb4, 0xb9, 0x08, 0x00, 0x2b, 0x2f, 0xe1, 0x82
+};
+
+static const uint8_t MAPI_LOCAL_UID_END[] = {
+	0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 
+	0x00, 0x2f
+};
+
+_PUBLIC_ char *guid_delete_dash(TALLOC_CTX *mem_ctx, const char *recipient_id)
+{
+	char		*guid;
+	uint32_t	count,i;
+
+	if (!recipient_id) {
+		return NULL;
+	}
+
+	for (count=0,i=0;i!=strlen(recipient_id);i++) {
+		if (recipient_id[i] != '-') count++;
+	}
+
+	guid = talloc_zero_size(mem_ctx, count+1);
+	for (count=0,i = 0;i!=strlen(recipient_id);i++) {
+		if (recipient_id[i] != '-') {
+			guid[count] = recipient_id[i];
+			count++;
+		}
+	}
+
+	return guid;
+}
+
+_PUBLIC_ struct Binary_r *generate_recipient_entryid(TALLOC_CTX *mem_ctx, const char *recipient_id)
+{
+	struct Binary_r	*entryid;
+	uint32_t	off;
+	char		*guid = (char *) NULL;
+
+	entryid = talloc(mem_ctx, struct Binary_r);
+	entryid->cb = sizeof (uint32_t) + sizeof (MAPI_LOCAL_UID) + sizeof (MAPI_LOCAL_UID_END) + 1;
+
+	if (recipient_id) {
+		guid = guid_delete_dash(mem_ctx, recipient_id);
+		entryid->cb += strlen(guid);
+	}
+
+	entryid->lpb = talloc_zero_size(mem_ctx, entryid->cb);
+	off = 4;
+	memcpy(entryid->lpb + off, MAPI_LOCAL_UID, sizeof (MAPI_LOCAL_UID));
+	off += sizeof (MAPI_LOCAL_UID);
+	
+	memcpy(entryid->lpb + off, MAPI_LOCAL_UID_END, sizeof (MAPI_LOCAL_UID_END));
+	off += sizeof (MAPI_LOCAL_UID_END);
+
+	if (recipient_id) {
+		strcpy((char *)entryid->lpb + off, guid);
+		off += strlen(recipient_id);
+	}
+	
+	return entryid;
+}
+
+/**
+ * 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
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS GetFIDFromEntryID(uint16_t cb, 
+					   uint8_t *lpb, 
+					   uint64_t parent_fid, 
+					   uint64_t *fid)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!lpb, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!fid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(cb < 8, MAPI_E_INVALID_PARAMETER, NULL);
+
+	*fid = 0;
+	*fid += ((uint64_t)lpb[cb - 3] << 56);
+	*fid += ((uint64_t)lpb[cb - 4] << 48);
+	*fid += ((uint64_t)lpb[cb - 5] << 40);
+	*fid += ((uint64_t)lpb[cb - 6] << 32);
+	*fid += ((uint64_t)lpb[cb - 7] << 24);
+	*fid += ((uint64_t)lpb[cb - 8] << 16);
+	/* WARNING: for some unknown reason the latest byte of folder
+	   ID may change (0x1 or 0x4 values identified so far).
+	   However this byte sounds the same than the parent folder
+	   one */
+	*fid += (parent_fid & 0xFF);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapi/x500.c
===================================================================
--- trunk/openchange/libmapi/x500.c	                        (rev 0)
+++ trunk/openchange/libmapi/x500.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,80 @@
+/*
+   OpenChange NSPI implementation.
+
+   Copyright (C) Julien Kerihuel 2005 - 2006.
+
+   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>
+
+
+/**
+   \details Extract a DN element from a given DN
+
+   \param mem_ctx pointer to the memory context
+   \param dn pointer to a valid DN
+   \param element pointer to the substring where extraction should start
+
+   \return pointer to an allocated substring on success, otherwise NULL
+ */
+_PUBLIC_ char *x500_get_dn_element(TALLOC_CTX *mem_ctx, const char *dn, const char *element)
+{
+	char	*pdn, *p, *str;
+	char	*tmp_dn;
+
+	if ((dn == NULL) || (dn[0] == '\0') || !element) return NULL;
+
+	tmp_dn = talloc_strdup(mem_ctx, dn);
+	pdn = strcasestr((const char *)tmp_dn, element);
+	if (pdn == NULL) {
+		talloc_free(tmp_dn);
+		return NULL;
+	}
+
+	pdn += strlen(element);
+	p = pdn;
+
+	if ((p = strchr(pdn, '/')) != NULL) {
+		p[0] = '\0';
+	}
+
+	str = talloc_strdup(mem_ctx, pdn);
+
+	talloc_free(tmp_dn);
+	return str;
+}
+
+/**
+ * Retrieve the servername from a string
+ * We should definitively find a better way to handle this
+ */
+
+_PUBLIC_ char *x500_get_servername(const char *dn)
+{
+	char *pdn;
+	char *servername;
+
+	if (!dn) {
+		return NULL;
+	}
+
+	pdn = strcasestr(dn, SERVERNAME);
+	if (pdn == NULL) return NULL;
+
+	pdn += strlen(SERVERNAME);
+	servername = strsep(&pdn, "/");
+
+	return (servername);
+}

Added: trunk/openchange/libmapi++/Doxyfile.in
===================================================================
--- trunk/openchange/libmapi++/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/libmapi++/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1257 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MAPI C++ Client Library Bindings
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = libmapi++
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.h *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = libmapi++/tests libmapi++/examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/libmapi++
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/libmapi++/attachment.h
===================================================================
--- trunk/openchange/libmapi++/attachment.h	                        (rev 0)
+++ trunk/openchange/libmapi++/attachment.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,157 @@
+/*
+   libmapi C++ Wrapper
+   Attachment Class
+
+   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/>.
+*/
+
+
+#ifndef LIBMAPIPP__ATTACHMENT_H__
+#define LIBMAPIPP__ATTACHMENT_H__
+
+#include <iostream> //for debugging
+#include <string>
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/message.h>
+
+namespace libmapipp
+{
+class object;
+
+/**
+ * \brief This class represents a message %attachment
+ *
+ * A message can contain both text content, and also have attached
+ * (embedded) files and messages. This class represents the attachments
+ * for one messaage.
+ * 
+ * You may not need to create the attachments yourself, since you can 
+ * create a container with all the attachments using message::fetch_attachments().
+ */
+class attachment : public object {
+	public:
+		/** \brief Constructor
+		 *
+		 *  \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");
+
+			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, 0, &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
+		 */
+		uint32_t get_num() const { return m_attach_num; }
+
+		/**
+		 * \brief the contents of the %attachment
+		 *
+		 * \note the length of the array is given by get_data_size()
+		 */
+		const uint8_t* get_data() const  { return m_bin_data; }
+
+		/**
+		 * \brief the size of the %attachment
+		 *
+		 * \return the size of the %attachment in bytes
+		 */
+		uint32_t get_data_size() const { return m_data_size; }
+
+		/**
+		 * \brief the filename of the %attachment
+		 *
+		 * \note not all attachments have file names
+		 *
+		 * \return string containing the file name of the %attachment, if any
+		 */
+		std::string get_filename() const { return m_filename; }
+
+		/**
+		 * Destructor
+		 */
+		virtual ~attachment() throw()
+		{
+			if (m_bin_data) delete m_bin_data;
+		}
+
+	private:
+		uint32_t	m_attach_num;
+		uint8_t*	m_bin_data; 	// (same as unsigned char* ?)
+		uint32_t	m_data_size;
+		std::string	m_filename;
+};
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__ATTACHMENT_H__

Added: trunk/openchange/libmapi++/clibmapi.h
===================================================================
--- trunk/openchange/libmapi++/clibmapi.h	                        (rev 0)
+++ trunk/openchange/libmapi++/clibmapi.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,27 @@
+/*
+   libmapi C++ Wrapper
+
+   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/>.
+*/
+
+#ifndef	__CLIBMAPI_H
+#define	__CLIBMAPI_H
+
+extern "C" {
+#include <libmapi/libmapi.h>
+}
+
+#endif /* ! __CLIBMAPI_H */

Added: trunk/openchange/libmapi++/examples/foldertree.cpp
===================================================================
--- trunk/openchange/libmapi++/examples/foldertree.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/examples/foldertree.cpp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,80 @@
+/*
+   libmapi C++ Wrapper
+
+   Sample folder tree list application
+
+   Copyright (C) Brad Hards <bradh at frogmouth.net> 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 <exception>
+#include <string>
+
+#include <libmapi++/libmapi++.h>
+
+int main ()
+{
+        try {
+                // Initialize MAPI Session
+                libmapipp::session mapi_session;
+		// You could log in with a non-default profile here
+                mapi_session.login();
+
+		// Get the private (user) folders message store
+		libmapipp::message_store &msg_store = mapi_session.get_message_store();
+
+		// Get a property of the top level message store
+		libmapipp::property_container msg_store_props = msg_store.get_property_container();
+		msg_store_props << PR_DISPLAY_NAME; // you could use other properties here
+		msg_store_props.fetch();
+
+		// Display the property. You can also use a property_container_iterator 
+		// to work through the properties, but in this case there is only one.
+		std::cout << "Message store display name: "
+			  << (const char*)msg_store_props[PR_DISPLAY_NAME]
+			  << std::endl;
+
+		// Fetch the folder list.
+		// We start off by fetching the top level folder
+		mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore);
+		libmapipp::folder top_folder(msg_store, top_folder_id);
+		// Now get the child folders of the top level folder. These are returned as
+		// a std::vector of pointers to folders
+		libmapipp::folder::hierarchy_container_type child_folders = top_folder.fetch_hierarchy();
+		// Display the name, total item count and unread item count for each folder
+        	for (unsigned int i = 0; i < child_folders.size(); ++i) {
+			libmapipp::property_container child_props = child_folders[i]->get_property_container();
+			child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD;
+			child_props.fetch();
+			std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME]
+				  << " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, "
+				  << (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)"
+				  << std::endl;
+        	}
+
+        }
+        catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions
+        {
+                std::cout << "MAPI Exception in main: " <<  e.what()
+			  << std::endl;
+        }
+        catch (std::runtime_error e) // Catch any other runtime exceptions
+        {
+                std::cout << "std::runtime_error exception in main: "
+			  << e.what() << std::endl;
+        }
+
+        return 0;
+}

Added: trunk/openchange/libmapi++/examples/messages.cpp
===================================================================
--- trunk/openchange/libmapi++/examples/messages.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/examples/messages.cpp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,72 @@
+/*
+   libmapi C++ Wrapper
+
+   Sample folder message application
+
+   Copyright (C) Brad Hards <bradh at frogmouth.net> 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 <exception>
+#include <string>
+
+#include <libmapi++/libmapi++.h>
+
+int main ()
+{
+        try {
+                // Initialize MAPI Session
+                libmapipp::session mapi_session;
+		// You could log in with a non-default profile here
+                mapi_session.login();
+
+		// Get the private (user) folders message store
+		libmapipp::message_store &msg_store = mapi_session.get_message_store();
+
+		// We start off by fetching the inbox
+		mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox);
+		libmapipp::folder inbox_folder(msg_store, inbox_id);
+		// Now get the messages in this folder These are returned as
+		// a std::vector of pointers to messages
+		libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages();
+		std::cout << "Inbox contains " << messages.size() << " messages" << std::endl;
+
+		// Work through each message
+        	for (unsigned int i = 0; i < messages.size(); ++i) {
+			// Get the properties we are interested in
+			libmapipp::property_container msg_props = messages[i]->get_property_container();
+			// We get the "to" addressee, and the subject
+			// You can get a lot of other properties here (e.g. sender, body, etc).
+			msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
+			msg_props.fetch();
+			// Display those properties
+			std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO]
+				  << "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC]
+				  << std::endl;
+        	}
+        }
+        catch (libmapipp::mapi_exception e) // Catch any MAPI exceptions
+        {
+                std::cout << "MAPI Exception in main: " <<  e.what()
+			  << std::endl;
+        }
+        catch (std::runtime_error e) // Catch any other runtime exceptions
+        {
+                std::cout << "std::runtime_error exception in main: "
+			  << e.what() << std::endl;
+        }
+
+        return 0;
+}

Added: trunk/openchange/libmapi++/folder.h
===================================================================
--- trunk/openchange/libmapi++/folder.h	                        (rev 0)
+++ trunk/openchange/libmapi++/folder.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,208 @@
+/*
+   libmapi C++ Wrapper
+   Folder Class
+
+   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/>.
+*/
+
+#ifndef LIBMAPIPP__FOLDER_H__
+#define LIBMAPIPP__FOLDER_H__
+
+#include <iostream> //for debugging
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/mapi_exception.h>
+#include <libmapi++/object.h>
+#include <libmapi++/message.h>
+
+namespace libmapipp
+{
+
+/**
+ *  This class represents a %folder or container within Exchange
+ */
+class folder : public object {
+	public:
+		/**
+		 * Pointer to a message
+		*/
+		typedef boost::shared_ptr<message>		message_shared_ptr;
+
+		typedef std::vector<message_shared_ptr >	message_container_type;
+
+		/**
+		 * Pointer to a %folder
+		*/
+		typedef boost::shared_ptr<folder>		folder_shared_ptr;
+
+		/**
+		 * Hierarchy folders
+		 *
+		 * This is a vector (list) of child folders for a given %folder
+		*/
+		typedef std::vector<folder_shared_ptr>		hierarchy_container_type;
+
+		/** 
+		 * \brief Constructor
+		 *
+		 * \param parent_folder The parent of this %folder.
+		 * \param folder_id     This folder's id.
+		*/
+		folder(object& parent_folder, const mapi_id_t folder_id) throw(mapi_exception) 
+		: object(parent_folder.get_session(), "folder"), m_id(folder_id)
+		{
+			if (OpenFolder(&parent_folder.data(), folder_id, &m_object) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "folder::folder : OpenFolder");
+		}
+
+		/**
+		 * \brief Obtain %folder id
+		 *
+		 * \return This folder's id.
+		 */
+		mapi_id_t get_id() const { return m_id; }
+
+		/** 
+		 * \brief Delete a message that belongs to this %folder
+		 *
+		 * \param message_id The id of the message to delete.
+		 */
+		void delete_message(mapi_id_t message_id) throw (mapi_exception)
+		{
+			if (DeleteMessage(&m_object, &message_id, 1) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "folder::delete_message : DeleteMessage");
+		}
+
+		/**
+		 * \brief Fetch all messages in this %folder
+		 *
+		 * \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;
+
+			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;
+
+			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
+		 */
+		virtual ~folder() throw()
+		{
+		}
+
+	private:
+		mapi_id_t	m_id;
+};
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__FOLDER_H__

Added: trunk/openchange/libmapi++/impl/message.ipp
===================================================================
--- trunk/openchange/libmapi++/impl/message.ipp	                        (rev 0)
+++ trunk/openchange/libmapi++/impl/message.ipp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -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++/impl/object.ipp
===================================================================
--- trunk/openchange/libmapi++/impl/object.ipp	                        (rev 0)
+++ trunk/openchange/libmapi++/impl/object.ipp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,32 @@
+/*
+   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++/session.h>
+#include <libmapi++/property_container.h>
+
+namespace libmapipp {
+
+inline property_container object::get_property_container() 
+{ 
+	return property_container(m_session.get_memory_ctx(), m_object); 
+}
+
+} // namespace libmapipp
+

Added: trunk/openchange/libmapi++/impl/session.ipp
===================================================================
--- trunk/openchange/libmapi++/impl/session.ipp	                        (rev 0)
+++ trunk/openchange/libmapi++/impl/session.ipp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,98 @@
+/*
+   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>
+
+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;
+	}
+}
+
+inline void session::uninitialize() throw()
+{
+	talloc_free(m_memory_ctx);
+	MAPIUninitialize();
+	delete m_message_store;
+}
+
+} // namespace libmapipp

Added: trunk/openchange/libmapi++/libmapi++-example.doxy
===================================================================
--- trunk/openchange/libmapi++/libmapi++-example.doxy	                        (rev 0)
+++ trunk/openchange/libmapi++/libmapi++-example.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,51 @@
+/** \example test.cpp
+
+An example that shows reading mail.
+
+*/
+
+/** \example attach_test.cpp
+
+An example that shows reading of attachments.
+
+*/
+
+/** \example foldertree.cpp
+
+This example lists the top level folders in the message store,
+with output like:
+\code
+Message store display name: Mailbox - Test User1
+|-----> Calendar (0 items, 0 unread)
+|-----> Contacts (0 items, 0 unread)
+|-----> Deleted Items (0 items, 0 unread)
+|-----> Drafts (0 items, 0 unread)
+|-----> Inbox (26 items, 24 unread)
+|-----> Journal (0 items, 0 unread)
+|-----> Notes (0 items, 0 unread)
+|-----> Outbox (9 items, 0 unread)
+|-----> Sent Items (0 items, 0 unread)
+|-----> Tasks (0 items, 0 unread)
+\endcode
+
+The example shows how to create a session, get the message_store, get
+properties of the message store, and then gets the list of child folders and
+some associated folder properties.
+
+*/
+
+/** \example messages.cpp
+
+This example displays information about the messages in the inbox, with
+output like:
+\code
+Inbox contains 2 messages
+|-----> Test User1              | Working Remotely with Windows Small Business Server
+|-----> Test User1              | Welcome to Windows Small Business Server 2003
+\endcode
+
+The example shows how to create a session, get the message_store, and open 
+the inbox folder. It then determines how many messages are in the inbox folder,
+and retrieves and prints the intended addressee and the message subject.
+
+*/

Added: trunk/openchange/libmapi++/libmapi++-mainpage.doxy
===================================================================
--- trunk/openchange/libmapi++/libmapi++-mainpage.doxy	                        (rev 0)
+++ trunk/openchange/libmapi++/libmapi++-mainpage.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,116 @@
+/**
+\mainpage libmapi++
+
+<h2>libmapi++ - C++ Bindings for OpenChange Clients</h2>
+
+libmapi++ provides C++ bindings for OpenChange client libraries (<a href="../libmapi/index.html">libmapi</a>).
+It is intended to provide a higher level abstraction of the OpenChange client libraries for C++ users who
+would prefer to work with an object-oriented API.
+
+<h2>Using libmapi++</h2>
+
+\note libmapi++ classes live in the libmapipp namespace.
+
+When using libmapi++, you start by creating a session, and logging in to the server.
+\code
+// Initialize MAPI Session
+libmapipp::session mapi_session;
+
+// login() can use an optional profile_name, and an optional password
+mapi_session.login();
+\endcode
+
+The session can then access the message store, which is the tree of private folders associated
+with a single user (containing various folders, such as the Inbox, Sent Mail, Calendar, Journal
+and so on).
+
+The message store is associated with the session, so you don't create it yourself. Instead,
+you obtain it using the session object's get_message_store() method.
+\code
+// Take a reference to the message store
+libmapipp::message_store &msg_store = mapi_session.get_message_store();
+\endcode
+\note It has to be a reference, not a copy / assignment.
+
+Most objects in libmapi++ (and any kind of MAPI library) can be considered to have properties
+that belong to them, and subordinate (child) objects. For example, the name of the message
+store is a property of the message store, but the various folders in the message store (or equally,
+the messages in a folder, or the attachments to a message) are part of a hierachy. 
+
+To get access to the properties of an object, you obtain the property_container associated
+with the object, set the properties you want to access, call fetch(), and then read off the
+various properties.
+\code
+// Get a property of the top level message store
+libmapipp::property_container msg_store_props = msg_store.get_property_container();
+msg_store_props << PR_DISPLAY_NAME; // you could use other properties here
+msg_store_props.fetch();
+std::cout << "Message store display name: "
+	  << (const char*)msg_store_props[PR_DISPLAY_NAME]
+	  << std::endl;
+\endcode
+
+Note that the operator[] is essentially a lookup operator. If you'd prefer to use an
+iterator, look at libmapipp::property_container_iterator.
+
+As noted above, the objects in libmapi++ can be considered as a hierachy. To get the
+child elements for an object, you use the hierachy table for that element. For example,
+to get the various folders in the private information store, you could use code like this:
+\code
+// We start off by fetching the top level folder
+mapi_id_t top_folder_id = msg_store.get_default_folder(olFolderTopInformationStore);
+libmapipp::folder top_folder(msg_store, top_folder_id);
+// Now get the child folders of the top level folder. These are returned as
+// a std::vector of pointers to folders
+libmapipp::folder::hierarchy_container_type child_folders = top_folder.fetch_hierarchy();
+
+// Display the name, total item count and unread item count for each folder
+for (unsigned int i = 0; i < child_folders.size(); ++i) {
+    libmapipp::property_container child_props = child_folders[i]->get_property_container();
+    child_props << PR_DISPLAY_NAME << PR_CONTENT_COUNT << PR_CONTENT_UNREAD;
+    child_props.fetch();
+    std::cout << "|-----> " << (const char*)child_props[PR_DISPLAY_NAME]
+              << " (" << (*(int*)child_props[PR_CONTENT_COUNT]) << " items, "
+              << (*(int*)child_props[PR_CONTENT_UNREAD]) << " unread)"
+              << std::endl;
+}
+\endcode
+
+As an alternative to working through the folder tree hierachy, you can also open 
+folders directly. In the example below, we open the Inbox. The API documentation
+for message_store::get_default_folder() provides a list of other folder IDs that
+you may find useful.
+\code
+mapi_id_t inbox_id = msg_store.get_default_folder(olFolderInbox);
+libmapipp::folder inbox_folder(msg_store, inbox_id);
+\endcode
+
+You can then get each message in the folder:
+\code
+// These are returned as a std::vector of pointers to messages
+libmapipp::folder::message_container_type messages = inbox_folder.fetch_messages();
+std::cout << "Inbox contains " << messages.size() << " messages" << std::endl;
+\endcode
+
+You can then get the various properties of each message in the same way as was
+used for the folder properties - you get the associated property_container, set
+the required properties, and call fetch() before reading off the required
+properties:
+\code
+// Work through each message
+for (unsigned int i = 0; i < messages.size(); ++i) {
+	// Get the properties we are interested in
+	libmapipp::property_container msg_props = messages[i]->get_property_container();
+	// We get the "to" addressee, and the subject
+	msg_props << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
+	msg_props.fetch();
+	// Display those properties
+	std::cout << "|-----> " << (const char*)msg_props[PR_DISPLAY_TO]
+		  << "\t\t| " << (const char*)msg_props[PR_CONVERSATION_TOPIC]
+		  << std::endl;
+}
+\endcode
+
+\todo Explain attachments.
+
+*/

Added: trunk/openchange/libmapi++/libmapi++.h
===================================================================
--- trunk/openchange/libmapi++/libmapi++.h	                        (rev 0)
+++ trunk/openchange/libmapi++/libmapi++.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,34 @@
+/*
+   libmapi C++ Wrapper
+   MAPI Exception Class
+
+   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/>.
+*/
+
+#ifndef	__LIBMAPIPP_H
+#define	__LIBMAPIPP_H
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/session.h>
+#include <libmapi++/message_store.h>
+#include <libmapi++/mapi_exception.h>
+#include <libmapi++/folder.h>
+#include <libmapi++/message.h>
+#include <libmapi++/attachment.h>
+#include <libmapi++/property_container.h>
+#include <libmapi++/profile.h>
+
+#endif /* ! __LIBMAPIPP_H */

Added: trunk/openchange/libmapi++/mapi_exception.h
===================================================================
--- trunk/openchange/libmapi++/mapi_exception.h	                        (rev 0)
+++ trunk/openchange/libmapi++/mapi_exception.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,148 @@
+/*
+   libmapi C++ Wrapper
+   MAPI Exception Class
+
+   Copyright (C) Alan Alvarez 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/>.
+*/
+
+#ifndef LIBMAPIPP__MAPI_EXCEPTION_H__
+#define LIBMAPIPP__MAPI_EXCEPTION_H__
+
+#include <exception>
+#include <map>
+#include <iostream>
+#include <string>
+
+#include <libmapi++/clibmapi.h>
+
+#define STATUS_TABLE_INSERT(status) sm_status_map.insert(status_map::value_type(status, #status));
+
+namespace libmapipp {
+
+class mapi_exception : public std::exception
+{
+	public:
+	
+		mapi_exception(enum MAPISTATUS status, const std::string& origin = "") : std::exception(), m_status(status), m_origin(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 ret_string.c_str();
+		}
+		enum MAPISTATUS get_status() const { return m_status; }
+
+		virtual ~mapi_exception() throw() {}
+
+	private:
+		enum MAPISTATUS	m_status;
+		std::string	m_origin;
+		friend class session;
+
+		typedef std::map<enum MAPISTATUS, const char*> status_map;
+		static status_map	sm_status_map;
+
+		static void fill_status_map()
+		{
+			static bool filled = false;
+
+			if (!filled) {
+				STATUS_TABLE_INSERT(MAPI_E_SUCCESS);
+				STATUS_TABLE_INSERT(MAPI_E_CALL_FAILED);
+				STATUS_TABLE_INSERT(MAPI_E_NO_SUPPORT);
+				STATUS_TABLE_INSERT(MAPI_E_BAD_CHARWIDTH);
+				STATUS_TABLE_INSERT(MAPI_E_STRING_TOO_LONG);
+				STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_FLAGS);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_ENTRYID);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_OBJECT);
+				STATUS_TABLE_INSERT(MAPI_E_OBJECT_CHANGED);
+				STATUS_TABLE_INSERT(MAPI_E_OBJECT_DELETED);
+				STATUS_TABLE_INSERT(MAPI_E_BUSY);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_ENOUGH_DISK);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_ENOUGH_RESOURCES);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_FOUND);
+				STATUS_TABLE_INSERT(MAPI_E_VERSION);
+				STATUS_TABLE_INSERT(MAPI_E_LOGON_FAILED);
+				STATUS_TABLE_INSERT(MAPI_E_SESSION_LIMIT);
+				STATUS_TABLE_INSERT(MAPI_E_USER_CANCEL);
+				STATUS_TABLE_INSERT(MAPI_E_UNABLE_TO_ABORT);
+				STATUS_TABLE_INSERT(MAPI_E_NETWORK_ERROR);
+				STATUS_TABLE_INSERT(MAPI_E_DISK_ERROR);
+				STATUS_TABLE_INSERT(MAPI_E_TOO_COMPLEX);
+				STATUS_TABLE_INSERT(MAPI_E_BAD_COLUMN);
+				STATUS_TABLE_INSERT(MAPI_E_EXTENDED_ERROR);
+				STATUS_TABLE_INSERT(MAPI_E_COMPUTED);
+				STATUS_TABLE_INSERT(MAPI_E_CORRUPT_DATA);
+				STATUS_TABLE_INSERT(MAPI_E_UNCONFIGURED);
+				STATUS_TABLE_INSERT(MAPI_E_FAILONEPROVIDER);
+				STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_CPID);
+				STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_LCID);
+				STATUS_TABLE_INSERT(MAPI_E_PASSWORD_CHANGE_REQUIRED);
+				STATUS_TABLE_INSERT(MAPI_E_PASSWORD_EXPIRED);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_WORKSTATION_ACCOUNT);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_ACCESS_TIME);
+				STATUS_TABLE_INSERT(MAPI_E_ACCOUNT_DISABLED);
+				STATUS_TABLE_INSERT(MAPI_E_END_OF_SESSION);
+				STATUS_TABLE_INSERT(MAPI_E_UNKNOWN_ENTRYID);
+				STATUS_TABLE_INSERT(MAPI_E_MISSING_REQUIRED_COLUMN);
+				STATUS_TABLE_INSERT(MAPI_E_BAD_VALUE);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_TYPE);
+				STATUS_TABLE_INSERT(MAPI_E_TYPE_NO_SUPPORT);
+				STATUS_TABLE_INSERT(MAPI_E_UNEXPECTED_TYPE);
+				STATUS_TABLE_INSERT(MAPI_E_TOO_BIG);
+				STATUS_TABLE_INSERT(MAPI_E_DECLINE_COPY);
+				STATUS_TABLE_INSERT(MAPI_E_UNEXPECTED_ID);
+				STATUS_TABLE_INSERT(MAPI_E_UNABLE_TO_COMPLETE);
+				STATUS_TABLE_INSERT(MAPI_E_TIMEOUT);
+				STATUS_TABLE_INSERT(MAPI_E_TABLE_EMPTY);
+				STATUS_TABLE_INSERT(MAPI_E_TABLE_TOO_BIG);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_BOOKMARK);
+				STATUS_TABLE_INSERT(MAPI_E_WAIT);
+				STATUS_TABLE_INSERT(MAPI_E_CANCEL);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_ME);
+				STATUS_TABLE_INSERT(MAPI_E_CORRUPT_STORE);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_IN_QUEUE);
+				STATUS_TABLE_INSERT(MAPI_E_NO_SUPPRESS);
+				STATUS_TABLE_INSERT(MAPI_E_COLLISION);
+				STATUS_TABLE_INSERT(MAPI_E_NOT_INITIALIZED);
+				STATUS_TABLE_INSERT(MAPI_E_NON_STANDARD);
+				STATUS_TABLE_INSERT(MAPI_E_NO_RECIPIENTS);
+				STATUS_TABLE_INSERT(MAPI_E_SUBMITTED);
+				STATUS_TABLE_INSERT(MAPI_E_HAS_FOLDERS);
+				STATUS_TABLE_INSERT(MAPI_E_HAS_MESAGES);
+				STATUS_TABLE_INSERT(MAPI_E_FOLDER_CYCLE);
+				STATUS_TABLE_INSERT(MAPI_E_AMBIGUOUS_RECIP);
+				STATUS_TABLE_INSERT(MAPI_E_NO_ACCESS);
+				STATUS_TABLE_INSERT(MAPI_E_INVALID_PARAMETER);
+				STATUS_TABLE_INSERT(MAPI_E_RESERVED);
+
+				filled = true;
+			}
+		}	
+};
+
+mapi_exception::status_map mapi_exception::sm_status_map = status_map();
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__EXCEPTION_H__

Added: trunk/openchange/libmapi++/message.h
===================================================================
--- trunk/openchange/libmapi++/message.h	                        (rev 0)
+++ trunk/openchange/libmapi++/message.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,96 @@
+/*
+   libmapi C++ Wrapper
+   Message Class
+
+   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/>.
+*/
+
+
+#ifndef LIBMAPIPP__MESSAGE_H__
+#define LIBMAPIPP__MESSAGE_H__
+
+#include <iostream> //for debugging
+#include <vector>
+
+#include <libmapi++/mapi_exception.h>
+#include <libmapi++/session.h>
+#include <libmapi++/clibmapi.h>
+
+namespace libmapipp
+{
+class object;
+class attachment;
+
+/** 
+ * \brief This class represents a %message in Exchange.
+ *
+ * It is important to note that a %message is not necessarily an email %message.
+ * It could be a contact, journal or anything else that is not a folder.
+ */
+class message : public object {
+	public:
+		typedef boost::shared_ptr<attachment>		attachment_shared_ptr;
+		typedef std::vector<attachment_shared_ptr>	attachment_container_type;
+
+		/**
+		 * \brief Constructor
+		 *
+		 * \param mapi_session The session to use to retrieve this %message.
+		 * \param folder_id The id of the folder this %message belongs to.
+		 * \param message_id The %message id.
+		 */
+		message(session& mapi_session, const mapi_id_t folder_id, const mapi_id_t message_id) throw(mapi_exception) 
+		: object(mapi_session, "message"), m_folder_id(folder_id), m_id(message_id)
+		{
+			if (OpenMessage(&mapi_session.get_message_store().data(), folder_id, message_id, &m_object, 0) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "message::message : OpenMessage");
+		}
+
+		/**
+		 * \brief Fetches all attachments in this %message.
+		 *
+		 * \return A container of attachment shared pointers.
+		 */
+		attachment_container_type fetch_attachments();
+
+		/**
+		 * \brief Get this %message's ID.
+		 */
+		mapi_id_t get_id() const { return m_id; }
+
+		/**
+		 * \brief Get this message's parent folder ID.
+		 */
+		mapi_id_t get_folder_id() const { return m_folder_id; } 
+
+		/**
+		 * Destructor
+		 */
+		virtual ~message() throw()
+		{
+		}
+
+	private:
+		mapi_id_t	m_folder_id;
+		mapi_id_t	m_id;
+
+};
+
+} // namespace libmapipp
+
+#include <libmapi++/impl/message.ipp>
+
+#endif //!LIBMAPIPP__MESSAGE_H__

Added: trunk/openchange/libmapi++/message_store.h
===================================================================
--- trunk/openchange/libmapi++/message_store.h	                        (rev 0)
+++ trunk/openchange/libmapi++/message_store.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,101 @@
+/*
+   libmapi C++ Wrapper
+   Message Store Class
+
+   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/>.
+*/
+
+
+#ifndef LIBMAPIPP__MESSAGE_STORE_H__
+#define LIBMAPIPP__MESSAGE_STORE_H__
+
+#include <stdint.h>
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/mapi_exception.h>
+#include <libmapi++/object.h>
+
+namespace libmapipp
+{
+class session;
+
+/**
+ * \brief This class represents the Message Store in Exchange.
+ *
+ * The message_store is the grouping of message folders (which could be the 
+ * users private store including mail, calendar, todo list, journal, contacts
+ * and so on) or could be the public store (e.g. shared public folders).
+ *
+ * It is not possible for you, the user, to create a message_store object.
+ * Instead, you should retrieve the message_store associated with a session
+ * using session::get_message_store()
+ */
+class message_store : public object {
+	public:
+		/**
+		 * \brief Retrieves the folder id for the specified default folder in the Message Store.
+		 *
+		 * \param id The type of folder to search for.
+		 *
+		 * The following types of folders are supported:
+		 * - olFolderTopInformationStore
+		 * - olFolderDeletedItems
+		 * - olFolderOutbox
+		 * - olFolderSentMail
+		 * - olFolderInbox
+		 * - olFolderCalendar
+		 * - olFolderContacts
+		 * - olFolderJournal
+		 * - olFolderNotes
+		 * - olFolderTasks
+		 * - olFolderDrafts
+		 *
+		 * If you are trying to enumerate all folders, you should open the 
+		 * olFolderTopInformationStore, and then get the hierachy container for
+		 * that top level folder.
+		 *
+		 * \return The resulting folder id.
+		 */
+		mapi_id_t get_default_folder(const uint32_t id) const throw(mapi_exception)
+		{
+			mapi_id_t folder;
+
+			if (GetDefaultFolder(const_cast<mapi_object_t*>(&m_object), &folder, id) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "message_store::get_default_folder() : GetDefaultFolder");
+
+			return folder;
+		}
+
+
+	private:
+		friend class session;
+		message_store(session& mapi_session) throw() : object(mapi_session, "message_store")
+		{}
+
+		void open(mapi_session *mapi_session) throw(mapi_exception)
+		{
+			if (OpenMsgStore(mapi_session, &m_object) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "message_store::open() : OpenMsgStore");
+		}
+
+		~message_store() throw()
+		{
+		}
+};
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__MESSAGE_STORE_H__

Added: trunk/openchange/libmapi++/object.h
===================================================================
--- trunk/openchange/libmapi++/object.h	                        (rev 0)
+++ trunk/openchange/libmapi++/object.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,108 @@
+/*
+   libmapi C++ Wrapper
+   Base Object Class
+
+   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/>.
+*/
+
+#ifndef LIBMAPIPP__OBJECT_H__
+#define LIBMAPIPP__OBJECT_H__
+
+#include <iostream> //for debugging
+
+#include <stdexcept>
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/session.h>
+
+/**
+ *  The libmapi++ classes and other definitions are all enclosed in
+ *  the libmapipp namespace.
+ */
+namespace libmapipp
+{
+// #define INVALID_HANDLE_VALUE 0xffffffff
+class property_container;
+
+/**
+ * Base Object class
+ *
+ * Most classes such as folder, message and message_store derive from this class.
+ * It is important that objects be passed around as references and that no unnecessary
+ * copies are made as this will call the class destructor which will call
+ * mapi_object_release() and release the handle associated with this object.
+ */
+class object {
+	public:
+		/**
+		 * \brief Object Constructor
+		 *
+		 * \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)
+		{
+			mapi_object_init(&m_object);
+		}
+
+		/**
+		 * \brief Obtain a reference to the mapi_object_t associated with this object
+		 * 
+		 * \return A reference to the C struct mapi_object_t associated with this object
+		 */
+		virtual mapi_object_t& data() throw() { return m_object; }
+
+		/**
+		 * \brief Obtain a property_container to be used with this object.
+		 *
+		 * \return A property_container to be used with this object.
+		 */
+		virtual property_container get_property_container();
+
+		/**
+		 * \brief Obtain the session associated with this object.
+		 *
+		 * \return The session associated with this object
+		 */
+		virtual session& get_session() { return m_session; }
+
+		/**
+		 * \brief Destructor
+		 *
+		 * Calls mapi_object_release() which releases the handle associated with this object.
+		 */ 
+		virtual ~object() throw()
+		{
+			// TODO: Check for invalid handle in libmapi 0.7
+			// if (m_object.handle != INVALID_HANDLE_VALUE)
+			mapi_object_release(&m_object);
+
+//			std::cout << "destroying object " << m_object_type << std::endl;
+		}
+
+	protected:
+		mapi_object_t	m_object;
+		session&	m_session;
+
+	private:
+		std::string m_object_type; // for debugging purposes
+};
+
+} // namespace libmapipp
+
+#include <libmapi++/impl/object.ipp>
+
+#endif //!LIBMAPIPP__OBJECT_H__

Added: trunk/openchange/libmapi++/profile.h
===================================================================
--- trunk/openchange/libmapi++/profile.h	                        (rev 0)
+++ trunk/openchange/libmapi++/profile.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,88 @@
+/*
+   libmapi C++ Wrapper
+   Profile Class
+
+   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/>.
+*/
+
+
+#ifndef LIBMAPIPP__PROFILE_H__
+#define LIBMAPIPP__PROFILE_H__
+
+#include <libmapi++/clibmapi.h>
+
+namespace libmapipp {
+
+/**
+ * This class represents a user %profile database
+ *
+ * \todo possibly rename profile class to profile_database?
+ * \todo we should be able to create a profile using libmapi++ classes
+ * \todo we should be able to delete a profile using libmapi++ classes
+ * \todo maybe move some of the session.h documentation on profiles to profile.h?
+ */
+class profile 
+{
+	public:
+
+		/**
+		 * Make the specified profile the default profile
+		 *
+		 * \param profname the name of the profile to make default
+		 */
+		bool static set_default(const char* profname)
+		{
+			return (SetDefaultProfile(profname) == MAPI_E_SUCCESS);
+		}
+
+		/**
+		 * Make the specified profile the default profile
+		 *
+		 * \param profname the name of the profile to make default
+		 */
+		bool static set_default(const std::string& profname)
+		{
+			return set_default(profname.c_str());
+		}
+
+		/**
+		 * Get the default profile name
+		 *
+		 * \return the name of the default profile
+		 */
+		std::string static get_default_profile() throw (mapi_exception)
+		{
+			char* profname = NULL;
+			if (GetDefaultProfile(&profname) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "profile::get_default_profile : GetDefaultProfile()");
+
+			return std::string(profname);
+		}
+
+		~profile()
+		{
+			if (m_profile)
+				::ShutDown(m_profile);
+		}
+
+
+	private:
+		mapi_profile	*m_profile;
+};
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__PROFILE_H__

Added: trunk/openchange/libmapi++/property_container.h
===================================================================
--- trunk/openchange/libmapi++/property_container.h	                        (rev 0)
+++ trunk/openchange/libmapi++/property_container.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,307 @@
+/*
+   libmapi C++ Wrapper
+   Property Tag Container Class
+
+   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/>.
+*/
+
+#ifndef LIBMAPIPP__PROPERTY_CONTAINER_H__
+#define LIBMAPIPP__PROPERTY_CONTAINER_H__
+
+#include <stdint.h>
+#include <iostream> // for debugging only.
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/mapi_exception.h>
+
+// This is not declared in any of libmapi's headers, but it is defined in libmapi/property.c
+extern "C" {
+extern const void *get_mapi_SPropValue_data(struct mapi_SPropValue *lpProp);
+}
+
+namespace libmapipp
+{
+/// Iterator to use with Property Container
+class property_container_iterator {
+	public:
+		/// Default Constructor. Creates an invalid iterator.
+		property_container_iterator() : m_property_values(NULL), m_mapi_property_values(NULL)
+		{}
+
+		property_container_iterator(SPropValue* property_values) : m_property_values(property_values),
+									   m_mapi_property_values(NULL)
+		{}
+
+		property_container_iterator(mapi_SPropValue* mapi_property_values) : m_property_values(NULL),
+										     m_mapi_property_values(mapi_property_values)
+		{}
+
+		/** \brief Get Property Tag Type.
+		 *  \return Type of property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator.
+		 *  Valid Types are: 
+		 *  - PT_BOOLEAN 
+		 *  - PT_I2 
+		 *  - PT_LONG 
+		 *  - PT_DOUBLE 
+		 *  - PT_I8 
+		 *  - PT_SYSTIME 
+		 *  - PT_ERROR 
+		 *  - PT_STRING8 
+		 *  - PT_UNICODE 
+		 *  - PT_BINARY
+		 *  - PT_CLSID
+		 *  - PT_ERROR
+		 *  - PT_MV_SHORT
+		 *  - PT_MV_LONG
+		 *  - PT_MV_STRING8
+		 *  - PT_MV_BINARY
+		 *  - PT_MV_CLSID
+		 *  - PT_MV_UNICODE
+		 *  - PT_MV_SYSTIME
+		 *  - PT_NULL
+		 *  - PT_OBJECT
+		 */
+		int get_type()
+		{
+			if (m_property_values) {
+				return m_property_values->ulPropTag & 0xffff;
+			} else if (m_mapi_property_values) {
+				return m_mapi_property_values->ulPropTag & 0xffff;
+			} else {
+				return MAPI_PROP_RESERVED;
+			}
+		}
+
+		/**
+		 * \brief Get Property Tag of the Property Value this operator points to.
+		 *
+		 * \return Property Tag of Property this iterator points to or MAPI_PROP_RESERVED if this is an invalid iterator.
+		 */
+		int get_tag()
+		{
+			if (m_property_values) {
+				return m_property_values->ulPropTag;
+			} else if (m_mapi_property_values) {
+				return m_mapi_property_values->ulPropTag;
+			} else {
+				return MAPI_PROP_RESERVED;
+			}
+		}
+
+		/// operator++
+		property_container_iterator& operator++() // prefix
+		{
+			if (m_property_values)
+				++m_property_values;
+			else if (m_mapi_property_values)
+				++m_mapi_property_values;
+
+			return *this;
+		}
+
+		/// operator++ postfix
+		property_container_iterator operator++(int postfix) // postfix
+		{
+			property_container_iterator retval = *this;
+			if (m_property_values)
+				 ++m_property_values;
+			else if (m_mapi_property_values)
+				++m_mapi_property_values;
+
+			return retval;
+		}
+		
+		/// operator==
+		bool operator==(const property_container_iterator& rhs) const
+		{
+			return ( (m_property_values == rhs.m_property_values) && (m_mapi_property_values == rhs.m_mapi_property_values) );
+		}
+
+		/// operator!=
+		bool operator!=(const property_container_iterator& rhs) const
+		{
+			return !(*this == rhs);
+		}
+
+		/**
+		 * \brief operator*
+		 *
+		 * \return The property value as a void pointer.
+		 */
+		const void* operator*()
+		{
+			if (m_property_values)
+				return get_SPropValue_data(m_property_values);
+			else
+				return get_mapi_SPropValue_data(m_mapi_property_values);
+		}		
+
+	private:
+		SPropValue*		m_property_values;
+		mapi_SPropValue*	m_mapi_property_values;
+};
+
+
+/// A container of properties to be used with classes derived from object.
+class property_container {
+
+	public:
+		typedef property_container_iterator	iterator;
+		typedef const void*			value_type;
+
+		/// Constructor
+		property_container(TALLOC_CTX* memory_ctx, mapi_object_t& mapi_object) : 
+		m_memory_ctx(memory_ctx), m_mapi_object(mapi_object), m_fetched(false), m_property_tag_array(NULL), m_cn_vals(0), m_property_values()
+		{
+		}
+
+		/**
+		 * \brief Fetches properties with the tags supplied using operator<<
+		 *
+		 * \return The number of objects that were fetched.
+		 */
+		uint32_t fetch()
+		{
+			if (GetProps(&m_mapi_object, m_property_tag_array, &m_property_values, &m_cn_vals) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "property_container::fetch : GetProps");
+
+			MAPIFreeBuffer(m_property_tag_array);
+			m_property_tag_array = NULL;
+
+			m_fetched = true;
+			return m_cn_vals;
+		}
+
+		/// \brief Fetches \b ALL properties of the object associated with this container.
+		void fetch_all()
+		{
+			if (GetPropsAll(&m_mapi_object, &m_property_value_array) != MAPI_E_SUCCESS)
+				throw mapi_exception(GetLastError(), "property_container::fetch_all : GetPropsAll");
+
+			// Free property_tag_array in case user used operator<< by mistake.
+			if (m_property_tag_array) {
+				MAPIFreeBuffer(m_property_tag_array);
+				m_property_tag_array = NULL;
+			}
+
+			m_fetched = true;
+		}
+
+		/// \brief Adds a Property Tag to be fetched by fetch().
+		property_container& operator<<(uint32_t property_tag)
+		{
+			if (!m_property_tag_array) {
+				m_property_tag_array = set_SPropTagArray(m_memory_ctx, 1, property_tag);
+			} else {
+				if (SPropTagArray_add(m_memory_ctx, m_property_tag_array, property_tag) != MAPI_E_SUCCESS)
+					throw mapi_exception(GetLastError(), "property_container::operator<< : SPropTagArray_add");
+			}
+
+			return *this;
+		}
+
+		/**
+		 * \brief Finds the property value associated with a property tag
+		 *
+		 * \param property_tag The Property Tag to be searched for
+		 *
+		 * \return Property Value as a const void pointer
+		 */
+		const void* operator[](uint32_t property_tag)
+		{
+			if (!m_fetched) return NULL;
+
+			if (m_property_values)
+				return find_SPropValue_value(property_tag);
+			else
+				return find_mapi_SPropValue_data(&m_property_value_array, property_tag);
+		}
+
+		enum MAPITAGS get_tag_at(uint32_t pos)
+		{
+			if (m_property_values)
+				return m_property_values[pos].ulPropTag;
+			else
+				return m_property_value_array.lpProps[pos].ulPropTag;
+		}
+
+		iterator begin() const
+		{
+			if (!m_fetched) return iterator();
+		
+			if (m_property_values)
+				return iterator(m_property_values);
+			else
+				return iterator(m_property_value_array.lpProps);
+		}
+
+		iterator end() const
+		{
+			if (!m_fetched) return iterator();
+			
+			if (m_property_values)
+				return iterator(m_property_values + m_cn_vals);
+			else
+				return iterator(m_property_value_array.lpProps + m_property_value_array.cValues);
+		}
+
+		/// \brief Get number of properties in container.
+		size_t size() const
+		{
+			if (!m_fetched) return 0;
+
+			if (m_property_values)
+				return m_cn_vals;
+			else
+				return m_property_value_array.cValues;
+		}
+
+		/// Destructor
+		~property_container()
+		{
+			if (m_property_tag_array) MAPIFreeBuffer(m_property_tag_array);
+		}
+
+	private:
+		TALLOC_CTX*		m_memory_ctx;
+		mapi_object_t&		m_mapi_object;
+
+		bool			m_fetched;
+
+		SPropTagArray*		m_property_tag_array;
+
+		// Used when calling GetProps (fetch)
+		uint32_t		m_cn_vals;
+		SPropValue*		m_property_values;
+
+		// Used when calling GetPropsAll (fetch_all)
+		mapi_SPropValue_array	m_property_value_array;
+
+		const void* find_SPropValue_value(uint32_t property_tag)
+		{
+			for (uint32_t i = 0; i < m_cn_vals; ++i)
+			{
+				if (m_property_values[i].ulPropTag == property_tag)
+					return get_SPropValue_data(&m_property_values[i]);
+			}
+
+			return NULL;
+		}
+};
+
+} // namespace libmapipp
+
+#endif //!LIBMAPIPP__PROPERTY_CONTAINER_H__

Added: trunk/openchange/libmapi++/session.h
===================================================================
--- trunk/openchange/libmapi++/session.h	                        (rev 0)
+++ trunk/openchange/libmapi++/session.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,146 @@
+/*
+   libmapi C++ Wrapper
+   Session Class
+
+   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/>.
+*/
+
+#ifndef LIBMAPIPP__SESSION_H__
+#define LIBMAPIPP__SESSION_H__
+
+#include <cstdlib>
+#include <cstring>
+#include <string>
+#include <stdexcept>
+
+#include <iostream> // for debugging
+
+#include <libmapi++/clibmapi.h>
+#include <libmapi++/mapi_exception.h>
+
+using std::cout;
+using std::endl;
+
+namespace libmapipp
+{
+class message_store;
+/**
+ * This class represents a MAPI %session with the Exchange Server
+ *
+ * The %session is best thought of as the connection by a single user to a
+ * single server. It is possible to have multiple sessions open at the same
+ * time.
+ *
+ * A key concept in the %session is that of a \em profile, and the %profile
+ * database. The %profile is a pre-established data set that specifies the
+ * server information (e.g. server name / IP address, and Exchange domain)
+ * and client information (e.g. the user name, preferred language, and
+ * optionally the users password). The profiles are stored in a local store
+ * (Samba LDB database) known as the %profile store or %profile database. One
+ * of the profiles in the %profile database can be designated as the default
+ * %profile (which is particularly useful given that most users may only have
+ * one). See the profile class documentation for more information.
+ *
+ * The general concept is that you create a %session %object, log in to the
+ * %session using a selected %profile name, and then work with the message_store
+ * associated with that %session. The message_store is only valid so long
+ * as the session is valid.
+ */
+class session {
+	public:
+		/**
+		 * \brief Constructor
+		 *
+		 * \param profiledb An absolute path specifying the location of the
+		 * %profile database. If not specified (or ""  is specified) the default
+		 * location will be used (~/.openchange.profiles.ldb).
+		 *
+		 * \param debug Whether to output debug information to stdout
+		 */
+		session(const std::string& profiledb = "", const bool debug = false) throw(std::runtime_error, mapi_exception);
+
+		/**
+		 * \brief Log-in to the Exchange Server
+		 *
+		 * \param profile_name The name of the profile to use to login with.
+		 * If not specified (or "" is specified), then the default %profile will
+		 * be used.
+		 *
+		 * \param password The password to use to login with. It is possible to
+		 * omit this if the password is stored in the %profile database.
+		 */
+		void login(const std::string& profile_name = "", const std::string& password = "") throw(mapi_exception); 
+
+		/**
+		 * \brief The path to the default %profile database
+		 *
+		 * This method is not normally required to be called by user applications
+		 * but might be useful under some circumstances.
+		 */
+		static std::string get_default_profile_path();
+
+		/**
+		 * \brief The name of the profile that is in use
+		 *
+		 * Calling this method only makes sense if login() has been called with
+		 * this %session object.
+		*/
+		std::string get_profile_name() const { return m_profile_name; }
+
+		/**
+		 * \brief Obtain a reference to the message_store associated with this %session
+		 *
+		 * \return The message_store associated with this %session.
+		 */
+		message_store& get_message_store() throw() { return *m_message_store; }
+
+		/**
+		 * \brief Obtain a talloc memory context for this %session
+		 *
+		 * This pointer can be used for subsequent memory allocations, and
+		 * these will be cleaned up when the %session is terminated.
+		 */
+		TALLOC_CTX* get_memory_ctx() throw() { return m_memory_ctx; }
+
+		/**
+		 * \brief Uninitialize and clean up the MAPI %session.
+		 */
+		~session()
+		{
+			uninitialize();
+		}
+
+		/**
+		 * \brief The underlying mapi_session
+		 * 
+		 * Exposing this is temporary. Maybe be removed when we sort it out
+		 */
+		mapi_session* get_mapi_session() throw() { return m_session; }
+
+	private:
+		mapi_session		*m_session;
+		TALLOC_CTX		*m_memory_ctx;
+		message_store		*m_message_store;
+		std::string		m_profile_name;
+
+		void uninitialize() throw();
+};
+
+} // namespace libmapipp
+
+#include <libmapi++/impl/session.ipp>
+
+#endif //!LIBMAPIPP__SESSION_H__

Added: trunk/openchange/libmapi++/tests/attach_test.cpp
===================================================================
--- trunk/openchange/libmapi++/tests/attach_test.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/tests/attach_test.cpp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,97 @@
+/*
+   libmapi C++ Wrapper
+
+   Sample attachment test application
+
+   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 <iostream>
+
+#include <libmapi++/libmapi++.h>
+
+using namespace std;
+using namespace libmapipp;
+
+uint32_t get_attachment_count(message& mapi_message)
+{
+	message::attachment_container_type attachment_container = mapi_message.fetch_attachments();
+	return attachment_container.size();
+}
+
+void print_messages_with_attachments(folder& up_folder)
+{
+	folder::message_container_type messages = up_folder.fetch_messages();
+	for (folder::message_container_type::iterator Iter = messages.begin(); Iter != messages.end(); ++Iter) {
+		uint32_t attachment_count = get_attachment_count(*(*Iter));
+//		cout << "Attachment Count: " << attachment_count << endl;
+		if (attachment_count) {
+			cout << "Message (" << (*Iter)->get_id() << ") has " << attachment_count << " attachments." << endl; 
+		}
+	}
+}
+
+void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0)
+{
+	property_container up_folder_property_container = up_folder.get_property_container();
+	up_folder_property_container << PR_DISPLAY_NAME << PR_CONTENT_COUNT;
+	up_folder_property_container.fetch();
+
+	string display_name = static_cast<const char*>(up_folder_property_container[PR_DISPLAY_NAME]);
+	const uint32_t message_count = *(static_cast<const uint32_t*>(up_folder_property_container[PR_CONTENT_COUNT]));
+
+	for (unsigned int i = 0; i < deep; ++i) {
+		cout << "|----> ";
+	}
+
+	cout << display_name << " (id: " << up_folder.get_id()  << ") (messages: " << message_count << ")" << endl;
+	
+	print_messages_with_attachments(up_folder);
+
+	// 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) {
+		print_folder_tree(*hierarchy[i], mapi_session, deep+1);
+	}
+}
+
+
+int main()
+{
+	try {
+		session mapi_session;
+
+		mapi_session.login();
+
+		// Get Default Top Information Store folder ID
+		mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore);
+
+		// Open Top Information Folder
+		folder top_folder(mapi_session.get_message_store(), top_folder_id);
+
+		print_folder_tree(top_folder, mapi_session);
+	}
+	catch (mapi_exception e) // Catch any mapi exceptions
+	{
+		cout << "MAPI Exception @ main: " <<  e.what() << endl;
+	}
+	catch (std::runtime_error e) // Catch runtime exceptions
+	{
+		cout << "std::runtime_error exception @ main: " << e.what() << endl;
+	}
+
+        return 0;
+}

Added: trunk/openchange/libmapi++/tests/test.cpp
===================================================================
--- trunk/openchange/libmapi++/tests/test.cpp	                        (rev 0)
+++ trunk/openchange/libmapi++/tests/test.cpp	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,140 @@
+/*
+   libmapi C++ Wrapper
+
+   Sample test application
+
+   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 <exception>
+#include <vector>
+#include <string>
+
+#include <libmapi++/libmapi++.h>
+
+using namespace libmapipp;
+using std::string;
+
+// The best way to get a folder message count is to get property PR_FOLDER_CHILD_COUNT.
+// This is only used to test opening all messages.
+unsigned int get_message_count(folder& the_folder, session& mapi_session)
+{
+	folder::message_container_type messages = the_folder.fetch_messages();
+	return messages.size();
+}
+
+void print_folder_tree(folder& up_folder, session& mapi_session, unsigned int deep = 0)
+{
+	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();
+
+	string display_name = static_cast<const char*>(up_folder_property_container[PR_DISPLAY_NAME]);
+	string container_class;
+	if (up_folder_property_container[PR_CONTAINER_CLASS])
+		container_class = static_cast<const char*>(up_folder_property_container[PR_CONTAINER_CLASS]);
+
+	for (unsigned int i = 0; i < deep; ++i) {
+		cout << "|----> ";
+	}
+
+	cout << display_name << " (id: " << up_folder.get_id()  << ") (messages: " << get_message_count(up_folder, mapi_session) << ")" 
+	     << " container class: " << container_class << endl;
+
+	// 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) {
+		print_folder_tree(*hierarchy[i], mapi_session, deep+1);
+	}
+}
+
+int main ()
+{
+	try {
+		// Initialize MAPI Session
+		session mapi_session;
+
+		mapi_session.login();
+
+		property_container store_properties = mapi_session.get_message_store().get_property_container();
+		store_properties << PR_DISPLAY_NAME;
+		store_properties.fetch();
+		cout << "Mailbox Name: " << static_cast<const char*>(*store_properties.begin()) << endl;
+
+		// Get Default Inbox folder ID.
+		mapi_id_t inbox_id = mapi_session.get_message_store().get_default_folder(olFolderInbox);
+		cout << "inbox_id: " << inbox_id << endl;
+
+		// Open Inbox Folder
+		folder inbox_folder(mapi_session.get_message_store(), inbox_id);
+
+		// Fetch messages in Inbox Folder
+		folder::message_container_type messages = inbox_folder.fetch_messages();
+		cout << "Inbox size: " << messages.size() << endl;
+
+		// Get and Print some information about the first message in the Inbox Folder
+		if (messages.size() > 0) {
+			// Get a property container associated to the first message
+			property_container message_property_container = messages[0]->get_property_container();
+
+			// Add Property Tags to be fetched and then fetch the properties.
+			message_property_container << PR_DISPLAY_TO << PR_CONVERSATION_TOPIC;
+			message_property_container.fetch_all();
+
+			string to;
+			string subject;
+			// Get some property values using property_container::operator[]
+			// to		= static_cast<const char*>(message_property_container[PR_DISPLAY_TO]);
+			// subject	= static_cast<const char*>(message_property_container[PR_CONVERSATION_TOPIC]);
+			// Print property values
+			// cout << "To: " << to << endl;
+			// cout << "Subject: " << subject << endl;
+
+			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;
+			}
+
+			// Print property values
+			cout << "To: " << to << endl;
+			cout << "Subject: " << subject << endl;
+		}
+
+		// Get Default Top Information Store folder ID
+		mapi_id_t top_folder_id = mapi_session.get_message_store().get_default_folder(olFolderTopInformationStore);
+
+		// Open Top Information Folder
+		folder top_folder(mapi_session.get_message_store(), top_folder_id);
+
+		print_folder_tree(top_folder, mapi_session);
+
+		cout << "finished session" << endl;
+	}
+	catch (mapi_exception e) // Catch any mapi exceptions
+	{
+		cout << "MAPI Exception @ main: " <<  e.what() << endl;
+	}
+	catch (std::runtime_error e) // Catch runtime exceptions
+	{
+		cout << "std::runtime_error exception @ main: " << e.what() << endl;
+
+	}
+
+	return 0;
+}

Added: trunk/openchange/libmapi.pc.in
===================================================================
--- trunk/openchange/libmapi.pc.in	                        (rev 0)
+++ trunk/openchange/libmapi.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: MAPI
+Description: MAPI Protocol Implementation
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lmapi
+Libs.private: @LIBS@
+Cflags: -I${includedir}
+Requires: talloc dcerpc ndr ldb
+Requires.private: samba-hostconfig

Added: trunk/openchange/libmapiadmin/Doxyfile.in
===================================================================
--- trunk/openchange/libmapiadmin/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/libmapiadmin/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1272 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = libmapiadmin
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = libmapiadmin
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.h *.c *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =  *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c *_private.h
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed \
+		         -e '20,50s/.*\<libmapiadmin\/proto_private.h\>//'	\
+			 -e '20,50s/.*\<param.h\>//'				\
+			 -e '20,50s/.*\<time.h\>//'				\
+			 -e '20,50s/.*\<credentials.h\>//'			\
+			 -e '20,50s/.*\<samba\/popt.h\>//'			\
+			 -e '20,50s/.*\<ldberrors.h\>//'			\
+			 -e '20,50s/.*\<ldb_wrap.h\>//'				\
+ 			 -e '20,50s/.*\<ldb_errors.h\>//'			\
+			 -e '20,50s/.*\<util_ldb.h\>//'				\
+			 -e '20,50s/.*\<ldap.h\>//'				\
+			 -e '20,50s/.*\<ldap_ndr.h\>//'				\
+			 -e '20,50s/.*\<core\/error.h\>//'			\
+			 -e '20,50s/.*\<gen_ndr\/ndr_samr.h\>//'		\
+			 -e '20,50s/.*\<gen_ndr\/ndr_samr_c.h\>//'		\
+                         -e 's/_PUBLIC_//'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/libmapiadmin
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/libmapiadmin/libmapiadmin-mainpage.doxy
===================================================================
--- trunk/openchange/libmapiadmin/libmapiadmin-mainpage.doxy	                        (rev 0)
+++ trunk/openchange/libmapiadmin/libmapiadmin-mainpage.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,11 @@
+/**
+\mainpage libmapiadmin
+
+<h2>Client library for OpenChange Administration</h2>
+
+libmapiadmin provides administration client capabilities for
+OpenChange and Exchange servers.
+
+\note As of version 0.8, libmapiadmin is considered alpha quality.
+
+*/

Added: trunk/openchange/libmapiadmin/libmapiadmin.h
===================================================================
--- trunk/openchange/libmapiadmin/libmapiadmin.h	                        (rev 0)
+++ trunk/openchange/libmapiadmin/libmapiadmin.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,114 @@
+/*
+   OpenChange Exchange Administration library.
+
+   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/>.
+ */
+
+#ifndef	__LIBMAPIADMIN_H__
+#define	__LIBMAPIADMIN_H__
+
+#define	_GNU_SOURCE	1
+
+struct mapiadmin_ctx;
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+
+/* Samba4 includes */
+#include <stdint.h>
+#include <talloc.h>
+#include <ldb.h>
+#include <tevent.h>
+
+/* OpenChange includes */
+#include <libmapi/libmapi.h>
+#include <libmapiadmin/proto.h>
+
+#undef _PRINTF_ATTRIBUTE
+#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)
+
+#ifndef	__BEGIN_DECLS
+#ifdef	__cplusplus
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+#endif
+
+#ifndef	MAX
+#define	MAX(p,q) (((p) >= (q)) ? (p) : (q))
+#endif
+
+/**
+	\file
+	Structures for MAPI admin functions
+*/
+
+struct test_join {
+	struct dcerpc_pipe		*p;
+	struct policy_handle		user_handle;
+	struct libnet_JoinDomain	*libnet_r;
+	struct dom_sid			*dom_sid;
+	const char			*dom_netbios_name;
+	const char			*dom_dns_name;
+	struct dom_sid			*user_sid;
+	struct GUID			user_guid;
+	const char			*netbios_name;
+};
+
+/**
+	MAPI admin function context
+*/
+struct mapiadmin_ctx
+{
+	struct mapi_session	*session;
+	const char		*username;
+	const char		*password;
+	const char		*fullname;
+	const char		*description;
+	const char		*comment;
+	struct test_join	*user_ctx;
+	const char		*binding;
+	const char		*dc_binding;
+	struct policy_handle	*handle;
+};
+
+/*
+ * prototypes from Samba4
+ */
+
+__BEGIN_DECLS
+struct ldb_dn *samdb_search_dn(struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, const char *, ...) _PRINTF_ATTRIBUTE(4,5);
+int samdb_msg_add_string(struct ldb_context *, TALLOC_CTX *,
+			 struct ldb_message *, const char *, const char *);
+int samdb_replace(struct ldb_context *, TALLOC_CTX *, struct ldb_message *);
+struct dom_sid *dom_sid_add_rid(TALLOC_CTX *, const struct dom_sid *, uint32_t);
+bool encode_pw_buffer(uint8_t buffer[516], const char *, int);
+void arcfour_crypt_blob(uint8_t *, int, const DATA_BLOB *);
+__END_DECLS
+
+#define	DEFAULT_PROFDB_PATH	"%s/.openchange/profiles.ldb"
+#define	MAPIADMIN_DEBUG_STR	"[%s:%d]: %s %s\n", __FUNCTION__, __LINE__
+
+#endif /* __LIBMAPIADMIN_H__ */

Added: trunk/openchange/libmapiadmin/mapiadmin.c
===================================================================
--- trunk/openchange/libmapiadmin/mapiadmin.c	                        (rev 0)
+++ trunk/openchange/libmapiadmin/mapiadmin.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,64 @@
+/*
+   OpenChange Exchange Administration library.
+
+   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/>.
+ */
+
+#include <libmapiadmin/libmapiadmin.h>
+#include <libmapiadmin/proto_private.h>
+
+/**
+	\file
+	Housekeeping functions for mapiadmin
+*/
+
+/**
+	Create and initialise a mapiadmin_ctx structure
+
+	You should use mapiadmin_release to clean up the mapiadmin_ctx
+	structure when done.
+*/
+_PUBLIC_ struct mapiadmin_ctx *mapiadmin_init(struct mapi_session *session)
+{
+	struct mapiadmin_ctx	*mapiadmin_ctx;
+
+	if (!global_mapi_ctx) return NULL;
+	if (!session) return NULL;
+	if (!session->profile) return NULL;
+
+	mapiadmin_ctx = talloc_zero((TALLOC_CTX *)session, struct mapiadmin_ctx);
+
+	mapiadmin_ctx->binding = talloc_asprintf((TALLOC_CTX *)mapiadmin_ctx, "ncacn_np:%s", 
+						 session->profile->server);
+	mapiadmin_ctx->session = session;
+
+	return mapiadmin_ctx;
+}
+
+/**
+	Clean up a mapiadmin_ctx structure
+
+	The structure is assumed to have been allocated uding mapiadmin_init() or
+	equivalent code.
+*/
+_PUBLIC_ enum MAPISTATUS mapiadmin_release(struct mapiadmin_ctx *mapiadmin_ctx)
+{
+	MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	talloc_free(mapiadmin_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libmapiadmin/mapiadmin_user.c
===================================================================
--- trunk/openchange/libmapiadmin/mapiadmin_user.c	                        (rev 0)
+++ trunk/openchange/libmapiadmin/mapiadmin_user.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,574 @@
+/*
+   OpenChange Exchange Administration library.
+
+   Based on the work by Andrew Tridgell, 2004
+
+   Original source code available in SAMBA_4_0:
+   source/torture/rpc/testjoin.c
+
+   Copyright (C) Julien Kerihuel 2007-2008.
+
+   SAMR related code
+
+   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 <libmapiadmin/libmapiadmin.h>
+#include <libmapiadmin/proto_private.h>
+
+#include <param.h>
+#include <credentials.h>
+#include <samba/popt.h>
+#include <ldb_errors.h>
+#include <ldb_wrap.h>
+#include <util_ldb.h>
+#include <ldap_ndr.h>
+
+#include <core/error.h>
+#include <gen_ndr/ndr_samr.h>
+#include <gen_ndr/ndr_samr_c.h>
+
+#include <time.h>
+
+/**
+	\file
+	User management functions for mapiadmin
+*/
+
+/**
+ * open connection so SAMR + Join Domain
+ * common code needed when adding or removing users
+ */
+static enum MAPISTATUS mapiadmin_samr_connect(struct mapiadmin_ctx *mapiadmin_ctx,
+					      TALLOC_CTX *mem_ctx)
+{
+	NTSTATUS			status;
+	struct tevent_context		*ev;
+	struct mapi_profile		*profile;
+	struct samr_Connect		c;
+	struct samr_OpenDomain		o;
+	struct samr_LookupDomain	l;
+	struct policy_handle		handle;
+	struct policy_handle		domain_handle;
+	struct lsa_String		name;
+
+	MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL);
+
+	profile = mapiadmin_ctx->session->profile;
+	
+	mapiadmin_ctx->user_ctx = talloc_zero(mem_ctx, struct test_join);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_ENOUGH_RESOURCES ,NULL);
+
+	DEBUG(3, ("Connecting to SAMR\n"));
+
+	ev = tevent_context_init(mem_ctx);
+
+	status = dcerpc_pipe_connect(mapiadmin_ctx->user_ctx,
+				     &mapiadmin_ctx->user_ctx->p,
+				     mapiadmin_ctx->dc_binding ? 
+				     mapiadmin_ctx->dc_binding : 
+				     mapiadmin_ctx->binding,
+				     &ndr_table_samr,
+				     profile->credentials, ev, global_mapi_ctx->lp_ctx);
+					     
+	MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);	
+
+	profile = mapiadmin_ctx->session->profile;
+
+	c.in.system_name = NULL;
+	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	c.out.connect_handle = &handle;
+
+	status = dcerpc_samr_Connect(mapiadmin_ctx->user_ctx->p, 
+				     mapiadmin_ctx->user_ctx, &c);
+	if (!NT_STATUS_IS_OK(status)) {
+		const char *errstr = nt_errstr(status);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+			errstr = dcerpc_errstr(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->p->last_fault_code);
+		}
+		DEBUG(3, ("samr_Connect failed - %s\n", errstr));
+		return MAPI_E_CALL_FAILED;
+	}
+
+	DEBUG(3, ("Opening domain %s\n", profile->domain));
+
+	name.string = profile->domain;
+	l.in.connect_handle = &handle;
+	l.in.domain_name = &name;
+
+	l.out.sid = talloc(mem_ctx, struct dom_sid2 *);
+	talloc_steal(mapiadmin_ctx->user_ctx, l.out.sid);
+
+	status = dcerpc_samr_LookupDomain(mapiadmin_ctx->user_ctx->p, 
+					  mapiadmin_ctx->user_ctx, &l);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("LookupDomain failed - %s\n", nt_errstr(status)));
+		return MAPI_E_CALL_FAILED;
+	}
+
+	mapiadmin_ctx->user_ctx->dom_sid = *l.out.sid;
+	mapiadmin_ctx->user_ctx->dom_netbios_name = talloc_strdup(mapiadmin_ctx->user_ctx, profile->domain);
+	if (!mapiadmin_ctx->user_ctx->dom_netbios_name) return MAPI_E_CALL_FAILED;
+
+	o.in.connect_handle = &handle;
+	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	o.in.sid = *l.out.sid;
+	o.out.domain_handle = &domain_handle;
+
+	status = dcerpc_samr_OpenDomain(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &o);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("OpenDomain failed - %s\n", nt_errstr(status)));
+		return MAPI_E_CALL_FAILED;
+	}
+
+	mapiadmin_ctx->handle = talloc_memdup(mem_ctx, &domain_handle, sizeof (struct policy_handle));
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+struct tce_async_context {
+	int	found;
+};
+
+static int tce_search_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+	struct tce_async_context	*actx = talloc_get_type(req->context, struct tce_async_context);
+	int				ret;
+
+        switch (ares->type) {
+
+        case LDB_REPLY_ENTRY:
+		if (ldb_msg_find_element(ares->message, "msExchMailboxGuid") != NULL) {
+			DEBUG(3, ("[%s:%d]: msExchMailboxGuid found!\n", __FUNCTION__, __LINE__));
+			actx->found = 1;
+			talloc_free(ares);
+			return ldb_request_done(req, LDB_SUCCESS);
+		}
+                break;
+        case LDB_REPLY_DONE:
+                ret = 0;
+                break;
+        default:
+		DEBUG(3, ("[%s:%d]: unknown Reply Type ignore it\n", __FUNCTION__, __LINE__));
+		talloc_free(ares);
+                return LDB_ERR_OTHER;
+        }
+
+        if (talloc_free(ares) == -1) {
+		DEBUG(3, ("[%s:%d]: talloc_free failed\n", __FUNCTION__, __LINE__));
+                return LDB_ERR_OPERATIONS_ERROR;
+        }
+	
+	return LDB_SUCCESS;
+}
+
+/**
+ * Extend user attributes to be Exchange user
+ */
+_PUBLIC_ enum MAPISTATUS mapiadmin_user_extend(struct mapiadmin_ctx *mapiadmin_ctx)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	struct tevent_context		*ev = NULL;
+	struct mapi_profile		*profile;
+	struct ldb_context		*remote_ldb;
+	struct ldb_request		*req;
+	struct ldb_message		*msg;
+	struct ldb_result		*res;
+	struct ldb_control		**controls;
+	const char			*control_strings[2] = { "notification:0", NULL };
+	struct tce_async_context	*tce_ctx;
+	const struct dom_sid		*dom_sid;
+	char				*remote_ldb_url;
+	const char * const		dom_attrs[] = { "*", NULL };
+	int				ret;
+	uint32_t			count;
+	char				**values;
+	const char			*exch_attrs[7];
+	int				i;
+	char				*realm = NULL;
+	char				*org = NULL;
+	const char			*UserAccountControl;
+	struct ldb_dn			*account_dn;
+
+	/* Sanity checks */
+	MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	profile = mapiadmin_ctx->session->profile;
+	dom_sid = mapiadmin_ctx->user_ctx->user_sid;
+
+	/* initialize memory context */
+	mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_extend");
+
+	/* open LDAP connection */
+	ev = tevent_context_init(talloc_autofree_context());
+	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);
+	MAPI_RETVAL_IF(!remote_ldb, MAPI_E_NETWORK_ERROR, mem_ctx);
+
+	/* Search the user_dn */
+	account_dn = samdb_search_dn(remote_ldb, mem_ctx, NULL, 
+				     "(&(objectSid=%s)(objectClass=user))", 
+				     ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
+
+	ret = ldb_search(remote_ldb, mem_ctx, &res, account_dn, LDB_SCOPE_SUBTREE, dom_attrs, "(objectSid=%s)",
+			 ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
+	MAPI_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx);
+	MAPI_RETVAL_IF(res->count != 1, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Prepare a new message for modify */
+	msg = ldb_msg_new(mem_ctx);
+	MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	msg->dn = res->msgs[0]->dn;
+
+	/* message: givenName */
+	exch_attrs[0] = talloc_strdup(mem_ctx, mapiadmin_ctx->username);
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "givenName", exch_attrs[0]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* message: userAccountControl */
+	exch_attrs[1] = talloc_asprintf(mem_ctx, "513");
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "userAccountControl", 
+				   exch_attrs[1]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+	msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
+
+	/* message: mail */
+	retval = GetProfileAttr(profile, "ProxyAddress", &count, &values);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	for (i = 0; i < count; i++) {
+		if (values[i] && !strncasecmp("smtp", values[i], 4)) {
+			realm = strchr(values[i], '@');
+			realm += 1;
+		}
+	}
+	MAPI_RETVAL_IF(!realm, MAPI_E_NOT_FOUND, mem_ctx);
+
+	exch_attrs[2] = talloc_asprintf(mem_ctx, "%s@%s", mapiadmin_ctx->username, realm);
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mail", exch_attrs[2]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* message: mailNickname */
+	exch_attrs[3] = talloc_strdup(mem_ctx, mapiadmin_ctx->username);
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mailNickname", exch_attrs[3]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* message: mDBUseDefaults */
+	exch_attrs[4] = talloc_asprintf(mem_ctx, "TRUE");
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, 
+				   "mDBUseDefaults", exch_attrs[4]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* message: legacyExchangeDN */
+	org = talloc_strndup(mem_ctx, profile->mailbox,
+			     strlen(profile->mailbox) - strlen(profile->username));
+	exch_attrs[5] = talloc_asprintf(mem_ctx, "%s%s", org, mapiadmin_ctx->username);
+	talloc_free(org);
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, 
+				   "legacyExchangeDN", exch_attrs[5]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* message: msExchHomeServerName */
+	exch_attrs[6] = talloc_strdup(mem_ctx, profile->homemdb);
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, 
+				   "msExchHomeServerName", exch_attrs[6]);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	/* Prior we call ldb_modify, set up async ldb request on
+	 * msExchMailboxGuid 
+	 */
+	req = talloc_zero(mem_ctx, struct ldb_request);
+	tce_ctx = talloc_zero(mem_ctx, struct tce_async_context);
+	controls = ldb_parse_control_strings(remote_ldb, mem_ctx, control_strings);
+
+	ret = ldb_build_search_req(&req, remote_ldb, mem_ctx, 
+				   msg->dn,
+				   LDB_SCOPE_BASE,
+				   "(objectclass=*)",
+				   NULL,
+				   controls, 
+				   (void *)tce_ctx, 
+				   tce_search_callback, 
+				   NULL);
+	DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_build_search_req", ldb_strerror(ret)));
+	MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
+
+	ldb_set_timeout(mem_ctx, req, 60);
+
+	ret = ldb_request(remote_ldb, req);
+	DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_request", ldb_strerror(ret)));
+	MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
+
+	ret = ldb_modify(remote_ldb, msg);
+	DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_modify", ldb_strerror(ret)));
+	MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CORRUPT_DATA, mem_ctx);
+
+	/* async search */
+	ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_wait", ldb_strerror(ret)));
+	MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
+	MAPI_RETVAL_IF(!tce_ctx->found, MAPI_E_CALL_FAILED, mem_ctx);
+	
+	/* When successful replace UserAccountControl attr in the user
+	 * record 
+	 */
+	talloc_free(msg);
+	msg = ldb_msg_new(mem_ctx);
+	MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+	msg->dn = res->msgs[0]->dn;
+
+	UserAccountControl = talloc_asprintf(mem_ctx, "66048");
+	ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, 
+				   "UserAccountControl", UserAccountControl);
+	MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+
+	ret = samdb_replace(remote_ldb, mem_ctx, msg);
+	DEBUG(3, (MAPIADMIN_DEBUG_STR, "samdb_replace", ldb_strerror(ret)));
+	MAPI_RETVAL_IF((ret != 0), MAPI_E_CORRUPT_DATA, mem_ctx);
+
+	/* reset errno before leaving */
+	errno = 0;
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Add a user to Active Directory 
+ */
+_PUBLIC_ enum MAPISTATUS mapiadmin_user_add(struct mapiadmin_ctx *mapiadmin_ctx)
+{
+	TALLOC_CTX			*mem_ctx;
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	struct mapi_profile		*profile;
+	struct samr_CreateUser2		r;
+	struct samr_GetUserPwInfo	pwp;
+	struct samr_SetUserInfo		s;
+	union samr_UserInfo		u;
+	uint32_t			access_granted;
+	uint32_t			rid;
+	DATA_BLOB			session_key;
+	struct lsa_String		name;
+	int				policy_min_pw_len = 0;
+
+	mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_add");
+
+	retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	DEBUG(3, ("Creating account %s\n", mapiadmin_ctx->username));
+	profile = mapiadmin_ctx->session->profile;
+
+again:
+	name.string = mapiadmin_ctx->username;
+	r.in.domain_handle = mapiadmin_ctx->handle;
+	r.in.account_name = &name;
+	r.in.acct_flags = ACB_NORMAL;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.out.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
+	r.out.access_granted = &access_granted;
+	r.out.rid = &rid;
+
+	status = dcerpc_samr_CreateUser2(mapiadmin_ctx->user_ctx->p, 
+					 mapiadmin_ctx->user_ctx, &r);
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
+		mapiadmin_user_del(mapiadmin_ctx);
+		if (NT_STATUS_IS_OK(status)) {
+			goto again;
+		} else {
+		        MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
+		}
+	}
+
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("CreateUser2 failed - %s\n", nt_errstr(status)));
+	        MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
+	}
+
+	mapiadmin_ctx->user_ctx->user_sid = dom_sid_add_rid(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->dom_sid, rid);
+
+	pwp.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
+	pwp.out.info = talloc_zero(mem_ctx, struct samr_PwInfo);
+
+	status = dcerpc_samr_GetUserPwInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &pwp);
+	if (NT_STATUS_IS_OK(status)) {
+		policy_min_pw_len = pwp.out.info->min_password_length;
+	} else {
+		DEBUG(3, ("GetUserPwInfo failed - %s\n", nt_errstr(status)));
+	        MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
+        }
+
+	if (!mapiadmin_ctx->password) {
+		mapiadmin_ctx->password = generate_random_str(mapiadmin_ctx->user_ctx, MAX(8, policy_min_pw_len));
+	}
+
+	DEBUG(3, ("Setting account password '%s'\n", mapiadmin_ctx->password));
+
+	ZERO_STRUCT(u);
+	s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
+	s.in.info = &u;
+	s.in.level = 24;
+
+	encode_pw_buffer(u.info24.password.data, mapiadmin_ctx->password, STR_UNICODE);
+	u.info24.password_expired = 0;
+
+	status = dcerpc_fetch_session_key(mapiadmin_ctx->user_ctx->p, &session_key);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("SetUserInfo level %u - no session key - %s\n",
+			  s.in.level, nt_errstr(status)));
+		mapiadmin_user_del(mapiadmin_ctx);
+	        MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
+	}
+
+	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
+
+	status = dcerpc_samr_SetUserInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &s);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status)));
+		if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
+		        MAPI_RETVAL_IF(1, MAPI_E_BAD_VALUE, mem_ctx);
+		} else {
+		        MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx);
+		}
+	}
+
+	ZERO_STRUCT(u);
+	s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
+	s.in.info = &u;
+	s.in.level = 21;
+
+	u.info21.acct_flags = ACB_NORMAL | ACB_PWNOEXP;
+	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
+
+	u.info21.comment.string = talloc_asprintf(mapiadmin_ctx->user_ctx, 
+						  mapiadmin_ctx->comment ? 
+						  mapiadmin_ctx->comment :
+						  "Created by OpenChange: %s", 
+						  timestring(mapiadmin_ctx->user_ctx, time(NULL)));
+	
+	u.info21.full_name.string = talloc_asprintf(mapiadmin_ctx->user_ctx, 
+						    mapiadmin_ctx->fullname ?
+						    mapiadmin_ctx->fullname :
+						    "Account for OpenChange: %s", 
+						    timestring(mapiadmin_ctx->user_ctx, time(NULL)));
+	
+	u.info21.description.string = talloc_asprintf(mapiadmin_ctx->user_ctx, 
+						      mapiadmin_ctx->description ?
+						      mapiadmin_ctx->description :
+						      "OpenChange account created by host %s: %s", 
+					 lp_netbios_name(global_mapi_ctx->lp_ctx), 
+					 timestring(mapiadmin_ctx->user_ctx, time(NULL)));
+
+	DEBUG(3, ("Resetting ACB flags, force pw change time\n"));
+
+	status = dcerpc_samr_SetUserInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &s);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status)));
+	        MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx);
+	}
+	retval = mapiadmin_user_extend(mapiadmin_ctx);
+	if (retval != MAPI_E_SUCCESS) {
+		DEBUG(3, ("mapiadmin_user_extend: 0x%x\n", GetLastError()));
+	        mapiadmin_user_del(mapiadmin_ctx);
+	        MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED,mem_ctx);
+	}
+
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Delete a user from Active Directory 
+ */
+_PUBLIC_ enum MAPISTATUS mapiadmin_user_del(struct mapiadmin_ctx *mapiadmin_ctx)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	NTSTATUS		status;
+	struct samr_DeleteUser	d;
+	struct policy_handle	user_handle;
+	uint32_t		rid;
+	struct samr_LookupNames	n;
+	struct lsa_String	sname;
+	struct samr_OpenUser	r;
+
+	MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_del");
+
+ 	/* Initiate SAMR connection if not already done */
+	if (!mapiadmin_ctx->user_ctx) {
+		retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx);
+		MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);		
+	}
+
+	sname.string = mapiadmin_ctx->username;
+
+	n.in.domain_handle = mapiadmin_ctx->handle;
+	n.in.num_names = 1;
+	n.in.names = &sname;
+
+	n.out.rids = talloc_zero(mem_ctx, struct samr_Ids);
+	n.out.types = talloc_zero(mem_ctx, struct samr_Ids);
+
+	status = dcerpc_samr_LookupNames(mapiadmin_ctx->user_ctx->p, mem_ctx, &n);
+	if (NT_STATUS_IS_OK(status)) {
+		rid = n.out.rids->ids[0];
+	} else {
+		talloc_free(mem_ctx);
+		return MAPI_E_NOT_FOUND;
+	}
+
+	r.in.domain_handle = mapiadmin_ctx->handle;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.in.rid = rid;
+	r.out.user_handle = &user_handle;
+
+	status = dcerpc_samr_OpenUser(mapiadmin_ctx->user_ctx->p, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(3, ("OpenUser(%s) failed - %s\n", mapiadmin_ctx->username, nt_errstr(status)));
+		MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, mem_ctx);
+	}
+
+	d.in.user_handle = &user_handle;
+	d.out.user_handle = &user_handle;
+	status = dcerpc_samr_DeleteUser(mapiadmin_ctx->user_ctx->p, mem_ctx, &d);
+	MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+_PUBLIC_ enum MAPISTATUS mapiadmin_user_mod(struct mapiadmin_ctx *mapiadmin)
+{
+	return MAPI_E_NO_SUPPORT;
+}

Added: trunk/openchange/libmapiadmin.pc.in
===================================================================
--- trunk/openchange/libmapiadmin.pc.in	                        (rev 0)
+++ trunk/openchange/libmapiadmin.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: MAPI Administration
+Description: MAPI Administration Implementation
+Version: @PACKAGE_VERSION@
+Libs: @LIBS@
+Cflags: @CFLAGS@
+Requires: talloc dcerpc ndr samba-hostconfig ldb

Added: trunk/openchange/libocpf/Doxyfile.in
===================================================================
--- trunk/openchange/libocpf/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/libocpf/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1276 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "OpenChange Property Files"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = libocpf
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.h *.c *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =  *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c *_private.h ocpf_api.*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = libocpf/examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed \
+		         -e '20,40s/.*\<libmapi\/proto_private.h\>//'	\
+			 -e '20,40s/.*\<gen_ndr\/ndr_exchange.h\>//'		\
+			 -e '20,40s/.*\<param.h\>//'				\
+			 -e '20,40s/.*\<core\/error.h\>//'			\
+			 -e '20,40s/.*\<credentials.h\>//'			\
+			 -e '20,40s/.*\<ldb.h\>//'				\
+			 -e '20,40s/.*\<ldb_errors.h\>//'			\
+			 -e '20,40s/.*\<libmapi\/dlinklist.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/defs_private.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapi_nameid.h\>//'		\
+			 -e '20,40s/.*\<libmapi\/mapi_nameid_private.h\>//'	\
+			 -e '20,40s/.*\<libocpf\/proto_private.h\>//'	\
+			 -e '20,40s/.*\<libocpf\/ocpf_api.h\>//'		\
+			 -e '20,40s/.*\<libocpf\/ocpf.tab.h\>//'		\
+			 -e '20,40s/.*\<libocpf\/ocpf_dump.h\>//'		\
+			 -e '20,40s/.*\<libgen.h\>//'			\
+			 -e '20,40s/.*\<time.h\>//'				\
+			 -e '20,40s/.*\<sys\/*\>//'				\
+                         -e '20,40s/_PUBLIC_//'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/libocpf
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/libocpf/examples/common_OLEGUID.ocpf
===================================================================
--- trunk/openchange/libocpf/examples/common_OLEGUID.ocpf	                        (rev 0)
+++ trunk/openchange/libocpf/examples/common_OLEGUID.ocpf	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,29 @@
+/*
+ *  OpenChange Property File
+ *
+ *  Copyright (C) Julien Kerihuel 2008.
+ *
+ *  Registers common OLEGUID
+ *
+ *  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/>
+ */
+
+OLEGUID PSETID_Appointment      "00062002-0000-0000-c000-000000000046"
+OLEGUID PSETID_Task             "00062003-0000-0000-c000-000000000046"
+OLEGUID PSETID_Address          "00062004-0000-0000-c000-000000000046"
+OLEGUID PSETID_Common           "00062008-0000-0000-c000-000000000046"
+OLEGUID PSETID_Note             "0006200e-0000-0000-c000-000000000046"
+OLEGUID PSETID_Log              "0006200a-0000-0000-c000-000000000046"
+OLEGUID PS_PUBLIC_STRINGS       "00020329-0000-0000-c000-000000000046"
+OLEGUID PS_INTERNET_HEADERS     "00020386-0000-0000-c000-000000000046"

Added: trunk/openchange/libocpf/examples/sample_appointment.ocpf
===================================================================
--- trunk/openchange/libocpf/examples/sample_appointment.ocpf	                        (rev 0)
+++ trunk/openchange/libocpf/examples/sample_appointment.ocpf	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,67 @@
+/*
+ *  OpenChange Property File
+ *
+ *  Copyright (C) Julien Kerihuel 2008.
+ *
+ *  Sample appointment
+ *
+ *  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/>
+ */
+
+TYPE	"IPM.Appointment"
+
+FOLDER	"olFolderCalendar"
+
+OLEGUID	PSETID_Appointment	"00062002-0000-0000-c000-000000000046"
+OLEGUID	PSETID_Common		"00062008-0000-0000-c000-000000000046"
+OLEGUID	PS_PUBLIC_STRINGS	"00020329-0000-0000-c000-000000000046"
+
+SET $subject = "[OCPF] Julien Kerihuel Birthday"
+SET $start_date = T2008-03-06 22:00:00
+SET $end_date = T2008-03-06 23:45:00
+SET $reminder = 45
+SET $keywords = { "candles", "friends", "family" }
+SET $private = B"true"
+SET $wrong = 0
+
+PROPERTY {
+	 PR_CONVERSATION_TOPIC = $subject
+	 PR_NORMALIZED_SUBJECT = $subject
+	 PR_BODY = "Another year, another pleasure"	 
+	 PR_START_DATE = $start_date
+	 PR_END_DATE = $end_date
+	 PR_SENSITIVITY = 2
+};
+
+NPROPERTY {
+	  OOM:Label:PSETID_Appointment = 9
+	  	  
+	  OOM:Start:PSETID_Appointment  =  $start_date
+	  OOM:CommonStart:PSETID_Common =  $start_date
+	  OOM:End:PSETID_Appointment    = $end_date
+	  OOM:CommonEnd:PSETID_Common   = $end_date
+
+	  OOM:Location:PSETID_Appointment = "Home Sweet Home"
+
+	  /* MeetingStatus */
+	  MNID_ID:0x8217:PSETID_Appointment = $wrong
+	  
+	  OOM:Private:PSETID_Common = $private
+
+	  /* Set a reminder */
+	  MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder
+
+	  /* Add categories */
+	  MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = $keywords
+};
\ No newline at end of file

Added: trunk/openchange/libocpf/examples/sample_task.ocpf
===================================================================
--- trunk/openchange/libocpf/examples/sample_task.ocpf	                        (rev 0)
+++ trunk/openchange/libocpf/examples/sample_task.ocpf	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,51 @@
+/*
+ *  OpenChange Property File
+ *
+ *  Copyright (C) Julien Kerihuel 2008.
+ *
+ *  Sample task
+ *
+ *  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/>
+ */
+
+TYPE	"IPM.Task"
+FOLDER	"olFolderTasks"
+
+OLEGUID PSETID_Task             "00062003-0000-0000-c000-000000000046"
+OLEGUID	PSETID_Common		"00062008-0000-0000-c000-000000000046"
+OLEGUID	PS_PUBLIC_STRINGS	"00020329-0000-0000-c000-000000000046"
+
+SET	$subject	=	"[OCPF] Sample Task"
+SET	$body		=	"This is the sample task body"
+SET	$start_date	=	T2008-03-06 20:00:00
+SET	$end_date	=	T2008-03-06 23:00:00
+SET	$importance	=	2 /* IMPORTANCE_HIGH */
+SET	$task_status	=	3 /* Waiting */
+
+PROPERTY {
+	 PR_CONVERSATION_TOPIC = $subject
+	 PR_NORMALIZED_SUBJECT = $subject
+	 PR_BODY = $body
+	 PR_IMPORTANCE = $importance
+	 PR_SENSITIVITY = 2	/* needed to have private box ticked */
+};
+
+NPROPERTY {
+	  OOM:Companies:PSETID_Common = {"OpenChange Project", "Samba Project" }
+	  OOM:StartDate:PSETID_Task = $start_date
+	  OOM:DueDate:PSETID_Task = $end_date
+	  OOM:Status:PSETID_Task = $task_status
+	  OOM:Private:PSETID_Common = B"true"
+	  MNID_STRING:"Keywords":PS_PUBLIC_STRINGS = { "Category1", "Category2" }
+};
\ No newline at end of file

Added: trunk/openchange/libocpf/lex.h
===================================================================
--- trunk/openchange/libocpf/lex.h	                        (rev 0)
+++ trunk/openchange/libocpf/lex.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,29 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 __LEX_H_
+#define	__LEX_H_
+
+void error_message (const char *, ...) __attribute__ ((format (printf, 1, 2)));
+
+extern int error_flag;
+
+int ocpf_yylex(void);
+
+#endif /* __LEX_H_ */

Added: trunk/openchange/libocpf/lex.l
===================================================================
--- trunk/openchange/libocpf/lex.l	                        (rev 0)
+++ trunk/openchange/libocpf/lex.l	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,320 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 <stdarg.h>
+#include <ctype.h>
+
+#include "libocpf/ocpf_private.h"
+#include <libocpf/ocpf_api.h>
+#include <libocpf/ocpf.tab.h>
+#include <libocpf/lex.h>
+
+struct ocpf	*ocpf;
+unsigned lineno = 1;
+
+#define	YY_DECL int ocpf_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);
+
+
+static void unterminated(const char *, unsigned);
+
+%}
+
+%%
+TYPE		{ return kw_TYPE; }
+FOLDER		{ return kw_FOLDER; }
+OLEGUID		{ return kw_OLEGUID; }
+SET		{ return kw_SET; }
+PROPERTY	{ return kw_PROPERTY; }
+NPROPERTY	{ return kw_NPROPERTY; }
+TO		{ return kw_TO; }
+CC		{ return kw_CC; }
+BCC		{ return kw_BCC; }
+RECIPIENT	{ return kw_RECIPIENT; }
+OOM		{ return kw_OOM; }
+MNID_ID		{ return kw_MNID_ID; }
+MNID_STRING	{ return kw_MNID_STRING; }
+PT_STRING8	{ return kw_PT_STRING8; }
+PT_UNICODE	{ return kw_PT_UNICODE; }
+PT_SHORT	{ return kw_PT_SHORT; }
+PT_LONG		{ return kw_PT_LONG; }
+PT_SYSTIME	{ return kw_PT_SYSTIME; }
+PT_BOOLEAN	{ return kw_PT_BOOLEAN; }
+PT_MV_STRING8	{ return kw_PT_MV_STRING8; }
+PT_BINARY	{ return kw_PT_BINARY; }
+\{		{ return OBRACE; }
+\}		{ return EBRACE; }
+,		{ return COMMA; }
+;		{ return SEMICOLON; }
+:		{ return COLON; }
+\<		{ return LOWER; }
+\>		{ return GREATER; }
+=		{ return EQUAL;}
+\/\*			{ 
+			    int c, start_lineno = lineno;
+			    int level = 1;
+			    int seen_star = 0;
+			    int seen_slash = 0;
+			    while((c = input()) != EOF) {
+				if(c == '/') {
+				    if(seen_star) {
+					if(--level == 0)
+					    break;
+					seen_star = 0;
+					continue;
+				    }
+				    seen_slash = 1;
+				    continue;
+				}
+				if(seen_star && c == '/') {
+				    if(--level == 0)
+					break;
+				    seen_star = 0;
+				    continue;
+				}
+				if(c == '*') {
+				    if(seen_slash) {
+					level++;
+					seen_star = seen_slash = 0;
+					continue;
+				    } 
+				    seen_star = 1;
+				    continue;
+				}
+				seen_star = seen_slash = 0;
+				if(c == '\n') {
+				    lineno++;
+				    continue;
+				}
+			    }
+			    if(c == EOF)
+				unterminated("comment", start_lineno);
+			}
+"\""			{ 
+			    int start_lineno = lineno;
+			    int c, c2;
+			    char buf[0x4000];
+			    char *p = buf;
+			    int f = 0;
+			    int skip_ws = 0;
+			    
+			    while((c = input()) != EOF) {
+				if(isspace(c) && skip_ws) {
+				    if(c == '\n')
+					lineno++;
+				    continue;
+				}
+				skip_ws = 0;
+
+				if (c == '\\') {
+					c2 = c;
+					c = input();
+					if (c == '"') { 
+						*p++ = c;
+						c = input();
+					} else {
+						*p++ = c2;
+					}
+				}
+
+				if(c == '"') {
+					if(f) {
+						*p++ = '"';
+						f = 0;
+					} else {
+						f = 1;
+					}
+					continue;
+				}
+				if(f == 1) {
+					unput(c);
+					break;
+				}
+				if(c == '\n') {
+				    lineno++;
+				    while(p > buf && isspace((unsigned char)p[-1]))
+					p--;
+				    skip_ws = 1;
+				    continue;
+				}
+				*p++ = c;
+			    }
+			    if(c == EOF)
+				unterminated("string", start_lineno);
+			    *p++ = '\0';
+			    ocpf_yylval.name = buf;
+			    return STRING; 
+			}
+W"\""			{ 
+			    int start_lineno = lineno;
+			    int c, c2;
+			    char buf[0x4000];
+			    char *p = buf;
+			    int f = 0;
+			    int skip_ws = 0;
+			    
+			    while((c = input()) != EOF) {
+				if(isspace(c) && skip_ws) {
+				    if(c == '\n')
+					lineno++;
+				    continue;
+				}
+				skip_ws = 0;
+
+				if (c == '\\') {
+					c2 = c;
+					c = input();
+					if (c == '"') { 
+						*p++ = c;
+						c = input();
+					} else {
+						*p++ = c2;
+					}
+				}
+
+				if(c == '"') {
+					if(f) {
+						*p++ = '"';
+						f = 0;
+					} else {
+						f = 1;
+					}
+					continue;
+				}
+				if(f == 1) {
+					unput(c);
+					break;
+				}
+				if(c == '\n') {
+				    lineno++;
+				    while(p > buf && isspace((unsigned char)p[-1]))
+					p--;
+				    skip_ws = 1;
+				    continue;
+				}
+				*p++ = c;
+			    }
+			    if(c == EOF)
+				unterminated("string", start_lineno);
+			    *p++ = '\0';
+			    ocpf_yylval.name = buf;
+			    return UNICODE; 
+			}
+\$[-A-Za-z0-9_]+      	{ char *y = yytext + 1;
+			  ocpf_yylval.var = strdup((const char *)y);
+			  return VAR;
+			}
+B\"true\"|-?B\"false\" { char *y = yytext + 1;
+			   if (y && !strcmp(y, "\"true\"")) {
+				ocpf_yylval.b = true;
+			   } else {
+			       	ocpf_yylval.b = false;
+			   }
+			   return BOOLEAN;
+			}
+T[0-9]{4}-[0-9]{2}-[0-9]{2}[ ][0-9]{2}\:[0-9]{2}\:[0-9]{2} {
+			  ocpf_yylval.date = strdup((const char *)yytext + 1);
+			  return SYSTIME;
+			}
+0x[0-9A-Fa-f]+		{ char *e, *y = yytext;
+			ocpf_yylval.l = strtoul((const char *)y, &e, 0);
+			if (e == y)
+				error_message("malformed constant (%s)", yytext);
+			else
+				return INTEGER;
+			
+}
+S0x[0-9A-Fa-f]+|-S[0-9]+ {
+			   char *e, *y;
+			   y = (yytext[0] == 'S') ? yytext + 1 : yytext;
+			   ocpf_yylval.s = strtoul((const char *)y, &e, 0);
+			   if (e == y)
+				error_message("malformed constant (%s)", yytext);
+			   else
+				return SHORT;
+			 }
+
+L0x[0-9A-Fa-f]+|-?[0-9]+ { char *e, *y;
+			  y = (yytext[0] == 'L') ? yytext + 1 : yytext;
+			  ocpf_yylval.l = strtoul((const char *)y, &e, 0);
+			  if(e == y) 
+			    error_message("malformed constant (%s)", yytext); 
+			  else
+			    return INTEGER;
+			}
+D0x[0-9A-Fa-f]+	{char *e, *y = yytext + 1;
+			  ocpf_yylval.d = strtoull((const char *)y,
+						   &e, 0);
+			  if(e == y) 
+			    error_message("malformed constant (%s)", yytext); 
+			  else
+			    return DOUBLE;
+
+			}
+[A-Za-z][-A-Za-z0-9_]*	{
+			  ocpf_yylval.name = strdup((const char *)yytext);
+			  return IDENTIFIER;
+			}
+[ \t]+			;
+\n		{ ++lineno; }
+.      		{ error_message("Ignoring char(%c)\n", *yytext); }
+%%
+
+#ifndef yywrap
+int
+yywrap(void)
+{
+	return 1;
+}
+#endif
+
+void error_message(const char *format, ...)
+{
+	va_list	args;
+
+	va_start(args, format);
+	fprintf(stderr, "ERROR: %s:%d: ", ocpf_get_filename(), lineno);
+	vfprintf(stderr, format, args);
+	va_end(args);
+	error_flag++;
+}
+
+static void
+unterminated(const char *type, unsigned start_lineno)
+{
+    error_message("unterminated %s, possibly started on line %d\n", type, start_lineno);
+}
\ No newline at end of file

Added: trunk/openchange/libocpf/ocpf-documentation.doxy
===================================================================
--- trunk/openchange/libocpf/ocpf-documentation.doxy	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf-documentation.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,834 @@
+/**
+\mainpage OpenChange Property File (OCPF)
+
+\section ocpf OpenChange Property File (OCPF)
+
+\section Contents
+<ul>
+ <li><a href="#revision">        Revision History        </a></li>
+ <li><a href="#introduction"> 1. Introduction            </a></li>
+ <li><a href="#purpose">      2. Purpose and Scope       </a></li>
+ <li><a href="#limit">        3. Limitations and Bugs    </a></li>
+ <li><a href="#syntax">       4. Syntax                  </a></li>
+ <li><a href="#keywords">     5. Top Level Keywords      </a>
+   <ul>
+	<li><a href="#type">      5.1. TYPE              </a></li>
+	<li><a href="#folder">    5.2. FOLDER            </a></li>
+	<li><a href="#set">       5.3. SET               </a></li>
+	<li><a href="#oleguid">   5.4. OLEGUID           </a></li>
+	<li><a href="#recipient"> 5.5. RECIPIENT	 </a></li>
+	<li><a href="#property">  5.6. PROPERTY section  </a></li>
+	<li><a href="#nproperty"> 5.7. NPROPERTY section </a></li>
+   </ul>
+ </li>
+ <li><a href="#properties">  6. Known Properties         </a>
+   <ul>
+	<li><a href="#propname">  6.1. Property Name     </a></li>
+	<li><a href="#proptag">   6.2. Property Tag      </a></li>
+   </ul>
+ </li>
+ <li><a href="#nproperties"> 7. Named Properties         </a>
+   <ul>
+	<li><a href="#OOM">         7.1. OOM             </a></li>
+	<li><a href="#MNID_ID">     7.2. MNID_ID         </a></li>
+	<li><a href="#MNID_STRING"> 7.3. MNID_STRING     </a></li>
+   </ul>
+ </li>
+ <li><a href="#proptype">    8. Supported Property Types </a>
+   <ul>
+	<li><a href="#boolean">    8.1. PT_BOOLEAN        </a></li>
+	<li><a href="#short">      8.2. PT_SHORT          </a></li>
+        <li><a href="#long">       8.3. PT_LONG           </a></li>
+        <li><a href="#double">     8.4. PT_I8             </a></li>
+        <li><a href="#string8">    8.5. PT_STRING8        </a></li>
+	<li><a href="#unicode">    8.6. PT_UNICODE        </a></li>
+        <li><a href="#systime">    8.7. PT_SYSTIME        </a></li>
+        <li><a href="#mv_string8"> 8.8. PT_MV_STRING8     </a></li>
+	<li><a href="#binary">     8.9. PT_BINARY         </a></li>
+   </ul>
+ </li>
+ <li><a href="#comments">    9. Comments                  </a>
+ </li>
+ <li><a href="#tools">       10. OCPF and openchangeclient </a>
+   <ul>
+       <li><a href="#syntax">      10.1. ocpf_syntax       </a></li>
+       <li><a href="#sender">      10.2. ocpf_sender       </a></li>
+       <li><a href="#dump">        10.3  ocpf_dump         </a></li>
+   </ul>
+ </li>
+</ul>
+<br/>
+
+<a name="revision"></a><h2>Revision History</h2>
+<table align="center" width="80%">
+	<tr>
+	   <td style="text-align:center"><strong>Date</strong></td>
+	   <td style="text-align:center"><strong>Revision Number</strong></td>
+	   <td style="text-align:center"><strong>Author</strong></td>
+	   <td style="text-align:center"><strong>Revision Content</strong></td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">01/04/08</td>
+	   <td style="text-align:center"><strong>0.5</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Add RECIPIENT support</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">29/03/08</td>
+	   <td style="text-align:center"><strong>0.4</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Add PT_UNICODE support and ocpf_dump option</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">06/03/08</td>
+	   <td style="text-align:center"><strong>0.3</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Add PT_BINARY and Streams support</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">05/03/08</td>
+	   <td style="text-align:center"><strong>0.2</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Improve PT_MV_STRING8 support</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">03/03/08</td>
+	   <td style="text-align:center"><strong>0.1</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Initial Revision</td>
+	</tr>
+</table>
+<br/>
+
+<a name="introduction"></a><h2>1. Introduction</h2>
+
+OCPF stands for OpenChange Property Files. This is a tiny file format
+designed for scripting and which facilitates third-party applications
+interaction and developers work using OpenChange. The main objective
+of OCPF is to offer the possibility to go beyond OpenChange tools
+default properties and create a custom message with user-defined
+fields.
+<br/>
+
+<a name="purpose"></a><h2>2. Purpose and Scope</h2>
+
+OCPF is designed to be used in various kind of applications and for
+different purposes:
+<ul>
+
+  <li><strong>Research on properties</strong>: OpenChange developers
+  have often requested for an easy way to test properties and
+  properties values. Prior to OCPF, developers had to write an application
+  linked with libmapi and compile it so that they could test
+  properties. Moreover, adding new named properties in trunk was kept
+  under OpenChange commiters agreement. OCPF solves this issue and
+  allow developers to write OCPF files with custom properties that they can
+  send using OpenChange tools. Furthermore OCPF will provide the
+  community a convenient way to agree on a particular property.</li>
+
+  <li><strong>Web Applications</strong>: OCPF offers a scripted
+  language with substitution variables which makes it possible to use OCPF
+  templates and use OCPF in conjunction with Web Forms. Since OCPF API
+  supports the parsing of multiple files, developers can plan to have
+  a file with variable declarations and a separate OCPF template that just
+  specifies variables.</li>
+
+  <li><strong>Backup/Restore</strong>: OCPF format may offer an easy
+  way for a restore/backup application to dump to the local filesystem
+  and restore messages on Exchange server. Furthermore, substitution of
+  variables can possibly be used to maintain the new hierarchy, such
+  as changing folders ID across Exchange servers and help migrating
+  database from a server to another.</li>
+
+</ul>
+<br/>
+
+
+<a name="limit"></a><h2>3. Limitations and Bugs </a></h2>
+
+OCPF is a pretty new library and it currently has a some limitations:
+<ul>
+    <li> It only supports a very limited set of property types </li>
+    <li> It doesn't support attachment yet </li>
+</ul>
+
+These limitations will be removed in later versions of OCPF.
+
+If you find bugs, limitations or encounter issues while using the OCPF
+library, please consider reporting them on <a
+href="http://trac.openchange.org">http://trac.openchange.org</a> and
+select the libocpf component. (Note: registration is required to create
+new tickets).
+
+For questions about its usage or about libocpf development, please
+post on the <a href="http://mailman.openchange.org/listinfo/devel">
+OpenChange devel mailing-list.</a>
+<br/>
+
+
+<a name="syntax"></a><h2>4. Syntax</h2>
+
+The general OCPF syntax is pretty basic. It mostly consists of
+top-level keywords, sections and properties types.
+<br/>
+
+
+<a name="keywords"></a><h2>5. Top Level Keywords</h2>
+
+<a name="type"></a><h3>5.1 TYPE </h3>
+<ul>
+  <li><strong>Format:</strong> 
+\code
+      TYPE STRING
+\endcode
+  </li>
+
+  <li><strong>Description:</strong> 
+
+  This keyword specifies the message class of the message. Users can
+  either specify their custom type or use on of the following standard
+  values:
+      <ul>
+	<li>"IPM.Appointment"</li>
+	<li>"IPM.Contact"</li>
+	<li>"IPM.Journal"</li>
+	<li>"IPM.Note"</li>
+	<li>"IPM.StickyNote"</li>
+	<li>"IPM.Task"</li>
+	<li>"IPM.Post"</li>
+      </ul>
+  </li>
+  <li><strong>Note:</strong> 
+
+  TYPE can only be defined once and takes a string value as
+  parameter. String values must be quoted otherwise a <I>syntax
+  error</I> will be displayed on output.
+  </li>
+  <li><strong>Example:</strong>
+\code 
+      TYPE "IPM.Appointment" 
+\endcode 
+  </li>
+</ul>
+<br/>
+
+<a name="folder"></a><h3>5.2 FOLDER </h3>
+<ul>
+  <li><strong>Format:</strong>
+\code
+      FOLDER STRING
+      FOLDER DOUBLE
+      FOLDER VAR
+\endcode
+  </li>
+  <li><strong>Description:</strong>
+
+  This keyword defines the destination folder of the message. Users
+  can either specify a default folder using the string value or a
+  custom folder ID using its PR_FID double value. It is also possible
+  to substitute the value with a variable, but it is limited to DOUBLE
+  value.
+
+  When FOLDER is set with DOUBLE custom value and ocpf_OpenFolder
+  public function used, it can be set to any folder identifier within
+  the message store. The function will loop over mailbox folders until
+  it finds the folder with the given folder ID and opens it.
+
+  Possible STRING values:
+  <ul>
+	<li> olFolderTopInformationStore </li>
+	<li> olFolderDeletedItems </li>
+	<li> olFolderOutbox </li>
+	<li> olFolderSentMail </li>
+	<li> olFolderInbox</li>
+	<li> olFolderCommonView</li>
+	<li> olFolderCalendar </li>
+	<li> olFolderContacts </li>
+	<li> olFolderJournal </li>
+	<li> olFolderNotes </li>
+	<li> olFolderTasks </li>
+  </ul>
+  </li>
+  <li><strong>Note:</strong> 
+
+  FOLDER can only be defined once.
+  </li>
+  <li><strong>Examples:</strong>
+\code 
+FOLDER "olFolderCalendar"
+\endcode
+
+or
+
+\code
+FOLDER D0x9504000000000001
+\endcode
+
+or
+
+\code
+SET    $folder_id = D0x9504000000000001
+FOLDER $folder_id
+\endcode
+  </li>
+</ul>
+<br/>
+
+<a name="set"></a><h3>5.3. SET</h3>
+<ul>
+  <li><strong>Format:</strong>
+\code
+      SET VAR = PROPVALUE
+\endcode
+  </li>
+  <li><strong>Description:</strong>
+
+  This keyword registers a variable named VAR and sets its value to
+  PROPVALUE. Variables must be prefixed with a dollar sign ($) and their
+  value can be set to any supported property type. See section on
+  property values for further information.
+  </li>
+
+  <li><strong>Note:</strong> 
+
+  SET can be used as many times as needed by the user, however VAR
+  name must remain unique. When a variable name is registered for the
+  second time, the OCPF parser displays a warning on the standard output
+  and skips the assignment.
+  </li>
+
+  <li><strong>Example:</strong>
+\code
+     SET $var1 = 0xdeadbeef
+     SET $var2 = "Hello World"
+     SET $var3 = T2008-03-06 23:30:00
+\endcode
+</ul>
+<br/>
+
+<a name="oleguid"></a><h3>5.4. OLEGUID</h3>
+<ul>
+    <li><strong>Format:</strong>
+\code
+      OLEGUID IDENTIFIER STRING
+\endcode
+    </li>
+    <li><strong>Description:</strong>
+
+    This keyword registers an OLEGUID couple (IDENTIFIER and STRING
+    value) that can then be used when declaring named properties (see
+    NPROPERTY). OLEGUID keyword takes two parameters: first the name,
+    used with named properties (PSETID_Appointment, PS_PUBLIC_STRINGS
+    etc.) and secondly a string representing a GUID value.
+    </li>
+    <li><strong>Note:</strong>
+
+    OLEGUID are identified by their IDENTIFIER and STRING. Users can't
+    register the same OLEGUID IDENTIFIER or STRING twice. If such case
+    occurs, a warning message will be displayed on stdout.
+    </li>
+    <li><strong>Example:</strong>
+\code
+      OLEGUID PSETID_Appointment "00062002-0000-0000-c000-000000000046"
+
+      [...]
+
+NPROPERTY {
+	  OOM:Label:PSETID_Appointment = T2008-03-06 23:30:00
+	  [...]
+\endcode
+    </li>
+</ul>
+<br/>
+
+<a name="recipient"></a><h3>5.5. RECIPIENT </h3>
+<ul>
+  <li><strong>Format:</strong>
+\code
+      RECIPIENT TO STRING;STRING;STRING
+      RECIPIENT CC STRING;STRING
+      RECIPIENT BCC STRING
+\endcode
+  </li>
+  <li><strong>Description:</strong>
+
+  This keyword declares recipients. RECIPIENT is followed by a
+  recipient type (TO, CC or BCC) and a set of STRING (recipients)
+  separated with semicolon.
+  </li>
+  <li><strong>Example:</strong>
+\code
+      RECIPIENT TO "recipient1";"recipient2";"recipient3"
+      RECIPIENT CC "recipient4"
+      RECIPIENT BCC "recipient5 at remote.corp";"recipient6"
+\endcode
+  </li>
+</ul>
+<br/>
+
+<a name="property"></a><h3>5.6. PROPERTY section</h3>
+<ul>
+  <li><strong>Format:</strong>
+\code
+      PROPERTY {
+      	       [...]
+      };
+\endcode
+  </li>
+  <li><strong>Description:</strong>
+
+  This keyword declares a <i>known property</i> section. PROPERTY is
+  followed by an opening brace, a set of property declarations and
+  is ended with a closing brace and semicolon. This section only
+  recognizes properties as described in <a href="#properties">6. Known
+  properties</a>.
+  </li>
+  <li><strong>Note:</strong>
+
+  While we suggest keeping a single PROPERTY section, nothing prevents
+  the user from declaring as many PROPERTY sections as needed.
+  </li>
+  <li><strong>Example:</strong>
+\code
+     PROPERTY {
+              PR_SUBJECT = "Hello World"
+              0x1000001e = "Sample body content"
+     };
+\endcode
+  </li>
+</ul>
+<br/>
+
+
+<a name="nproperty"></a><h3>5.7. NPROPERTY section</h3>
+<ul>
+  <li><strong>Format:</strong>
+\code
+      NPROPERTY {
+                 [...]
+                };
+\endcode
+  </li>
+  <li><strong>Description:</strong>
+
+  This keyword declares a <i>named property</i> section. NPROPERTY is
+  followed by an opening brace, a set of named properties declarations
+  and is ended with a closing brace and semicolon. This section
+  only recognizes named properties as described in <a
+  href="#nproperties">7. Named Properties</a>.
+
+  </li>
+  <li><strong>Note:</strong>
+
+  While we suggest keeping a single NPROPERTY section, nothing
+  prevents the user from declaring as many NPROPERTY sections as
+  needed.
+  </li>
+  <li><strong>Example:</strong>
+\code
+      NPROPERTY {
+                OOM:Start:PSETID_Appointment = T2008-03-06 22:00:00
+                OOM:Location:PSETID_Appointment = "Home Sweet Home"
+                /* Meeting Status */
+                MNID_ID:0x8217:PSETID_Appointment = 0;
+      };
+\endcode
+  </li>
+</ul>
+<br/>
+<br/>
+
+
+<a name="properties"></a><h2>6. Known Properties</h2>
+
+A known properties is any property where the value doesn't change
+across Exchange servers and versions. Known properties can only be
+registered within a PROPERTY section (See <a href="#property">5.6
+PROPERTY section</a>). Known properties have the same general syntax:
+
+\code
+      IDENTIFIER = [PROPVALUE | VAR]
+      INTEGER    = [PROPVALUE | VAR]
+\endcode
+
+OCPF lets the user define <i>known properties</i> using two different
+methods: property names or property tags.
+
+Please note that OCPF doesn't check whether the value associated with
+the property matches the property type. For the moment it is the
+developer's responsibility to ensure that the property type matches
+its value.
+<br/>
+
+<a name="propname"></a><h3>6.1. Property Names</h3>
+
+	Property Names are defined with an IDENTIFIER which must match
+	one already registered in libmapi/conf/mapi-properties. For
+	example:
+\code
+      PR_SUBJECT      = "Hello World"
+      PR_START_DATE   = T2008-03-06 22:00:00
+      PR_PRIORITY     = 2
+\endcode
+<br/>
+
+<a name="proptag"></a><h3>6.2. Property Tags</h3>
+
+	Property Tags are the other way to set a property. This is an
+	integer value represented using hexadecimal notation and
+	which has two parts: the upper 16 bits are the property ID and
+	the lower 16 bits are the property type.
+
+	While users may prefer to use the property name notation for
+	declaration, libmapi/conf/mapi-properties remains incomplete
+	and there may be cases where you need to use the property tag
+	notation. The example below sets properties described in
+	previous example using their property tag notation.
+\code
+      0x0037001e     = "Hello World"
+      0x00600040     = T2008-03-06 22:00:00
+      0x00260003     = 2
+\endcode.
+<br/>
+
+
+<a name="nproperties"></a><h2>7. Named Properties</h2>
+
+The OCPF syntax for different kind of named properties is quite
+generic. It supports each of the three kinds of property
+(OOM, MNID_ID, MNID_STRING) and can set known named properties
+(those listed in libmapi/conf/mapi-named-properties) or register
+new named properties (except OOM properties).
+
+The types of properties, and how they can be used, are described
+below.
+<br/>
+
+<a name="OOM"></a><h3>7.1. OOM</h3>
+
+OOM stands for Outlook Object Model and is a friendly name associated
+to a named property. It has no meaning to Exchange, but it can
+be useful for OpenChange or MAPI developers.
+
+OOM are human readable shortcuts for most named
+properties and OOM values are are considered reliable. This is the
+reason why OOM can only be used if it exists in
+libmapi/conf/mapi-named-properties. This method - in our opinion - is
+the best method to guarantee developers a common and validated
+mapi-named-properties file.
+
+Theorically, property names can have the same OOM, property ID
+(MNID_ID) or name (MNID_STRING). The only way to guarantee named
+property uniqueness is to associate its value with a OLEGUID.
+
+OLEGUID needs to be registered before they can be used with named
+properties. See <a href="#oleguid">5.4 OLEGUID</a> for more
+information on how to register a OLEGUID.
+
+OOM named properties have the following syntax:
+\code
+      OOM:IDENTIFIER:IDENTIFIER = [PROPVALUE | VAR]
+\endcode
+
+The first IDENTIFIER represents the OOM value while the second one
+represents the OLEGUID. Note that identifiers are not enclosed with
+quotes. Below are some OOM assignments examples:
+
+\code
+      OOM:Label:PSETID_Appointment = 9
+      OOM:End:PSETID_Appointment = $end_date
+      OOM:Private:PSETID_Common = B"true"
+\endcode
+<br/>
+
+<a name="MNID_ID"></a><h3>7.2. MNID_ID</h3>
+
+Named properties that Exchange converts using their property ID (16
+bits) are known as MNID_ID named property kind. OCPF provides two
+different ways to define MNID_ID. It can either be a new named
+property or an existing one which wouldn't have any associated OOM.
+
+MNID_ID named property kind has the following syntax:
+\code
+      MNID_ID:INTEGER:PROPTYPE:IDENTIFIER  = [PROPVALUE | VAR]
+      MNID_ID:INTEGER:IDENTIFIER	   = [PROPVALUE | VAR]
+\endcode
+
+If the MNID_ID named property doesn't exist within
+libmapi/conf/mapi-named-property then you must specify its property
+type.
+
+As described in the example below, the main difference between known
+and custom MNID_ID named properties is whether or not we specify its
+property type. If your MNID_ID property has not been referenced within
+libmapi/conf/mapi-named-property, then you must supply its property
+type, otherwise you can skip it.
+
+Note: PROPTYPE can be any of the values described in <a
+href="#proptype"> 8. Supported Property Types </a>.
+
+\code
+      MNID_ID:0x8501:PT_LONG:PSETID_Common = $reminder	/* Reminder	 */
+      MNID_ID:0x8217:PSETID_Appointment    = 0		/* MeetingStatus */
+\endcode
+<br/>
+
+<a name="MNID_STRING"></a><h3>7.3. MNID_STRING</h3>
+
+Exchange also supports named properties which do not have a
+property ID but are described using property names. These named
+properties are known as MNID_STRING named property kind and Exchange
+maps these names to a temporary property type.
+
+MNID_STRING named property kind has the following syntax:
+\code
+      MNID_STRING:STRING:IDENTIFIER          = [PROPVALUE | VAR]
+      MNID_STRING:STRING:PROPTYPE:IDENTIFIER = [PROPVALUE | VAR]
+\endcode
+
+MNID_STRING difference between known and custom is the same as
+MNID_ID one. If the MNID_STRING property doesn't exist in
+libmapi/conf/mapi-named-properties, then users have to supply its
+PROPTYPE.
+
+NOTE: PROPTYPE can be any of the value described in <a
+href="#proptype"> 8. Supported Property Types </a>.
+
+Considering the behavior described above, we could set the "Keywords"
+MNID_STRING named property using any of the following example:
+\code
+       MNID_STRING:"Keywords":PS_PUBLIC_STRINGS               = {"one", "two" , "three" }
+       MNID_STRING:"Keywords":PT_MV_STRING8:PS_PUBLIC_STRINGS = {"one", "two" , "three" }
+\endcode
+
+<br/>
+
+
+<a name="proptype"></a><h2>8. Supported Property Types</h2>
+<a name="boolean"></a><h3>8.1. PT_BOOLEAN</h3>
+
+OCPF uses the following format for BOOLEAN values:
+\code
+      B"true"
+      B"false"
+\endcode
+<br/>
+
+<a name="short"></a><h3>8.2. PT_SHORT</h3>
+OCPF can use any of the following formats for SHORT values:
+\code
+     S0x1234
+     S32
+\endcode
+
+The short integer can either be in hexadecimal of decimal notation but
+must be prefixed with a "S" to specify this is a short integer
+value. If you omit to specify the "S", mismatch property type/value
+errors will occur while sending the message.
+
+<a name="long"></a><h3>8.3. PT_LONG</h3>
+OCPF can use any of the following formats for PT_LONG values:
+\code
+      0xdeadbeef
+      L0xdeadbeef
+      32
+\endcode
+
+The integer can either be in hexadecimal or decimal notation or
+prefixed with a "L" to specify this is long value. If you use the
+hexadecimal notation consider using the 'L' prefixed form since other form
+may disappear in further versions.
+<br/>
+
+<a name="double"></a><h3>8.4. PT_I8</h3>
+OCPF uses the following format for PT_I8 (uint64_t) values:
+\code
+      D0x9504000000000001
+\endcode
+<br/>
+
+<a name="string8"></a><h3>8.5. PT_STRING8</h3>
+
+OCPF defines a string as a set of characters (A-Za-z0-9_) enclosed
+with double quotes:
+\code
+      "I am a STRING"
+\endcode
+<br/>
+
+<a name="unicode"></a><h3>8.6. PT_UNICODE</h3>
+
+OCPF defines a unicode string as a set of characters enclosed with
+double quotes and prefixed with <strong>W</strong>:
+\code
+      W"I am a UNICODE string"
+\endcode
+<br/>
+
+<a name="systime"></a><h3>8.7. PT_SYSTIME</h3>
+
+OCPF defines date using the following format string:
+\code
+      TYYYY-MM-DD HH:MM:SS
+\endcode
+
+Dates are prefixed with a 'T' character and its content is represented
+with the syntax below:
+
+<ul>
+	<li> YYYY: year </li>
+	<li> MM: month </li>
+	<li> DD: day </li>
+	<li> HH: hours </li>
+	<li> MM: minutes </li>
+	<li> SS: seconds </li>
+</ul>
+
+\code
+	T2008-03-06 22:30:00 /* 2008, 6th of March 10:30:00PM */
+\endcode
+<br/>
+
+<a name="mv_string8"></a><h3>8.8. PT_MV_STRING8</h3>
+
+PT_MV_STRING8 are arrays ("multiple values") of strings. OCPF defines PT_MV_STRING8
+property values as STRING property values separated by commas and enclosed within
+braces.
+
+\code
+      { STRING, STRING, ..., STRING }	
+\endcode
+
+At least one STRING property value is required to create a valid
+PT_MV_STRING8 property. If two or more STRING property values are set,
+then they must be separated with comma.
+
+\code
+      { "single multi-string value" }
+      { "one" , "two", "three", "owned" }
+\endcode
+<br/>
+
+<a name="binary"></a><h3>8.9. PT_BINARY</h3>
+
+PT_BINARY are blobs of data. OCPF defines PT_BINARY property values
+using two different methods. This can either be raw/inline blob of
+data or filename/external.
+
+If users wish to add raw data blob for a given property, they need to
+enclose INTEGER values within braces. However many cases occur where
+the data blob is large (such as HTML content; PR_HTML has PT_BINARY
+property type). In such cases, users may rather prefer to write an
+external file and specify a filename.
+
+\code
+	{ INTEGER INTEGER [...] INTEGER }
+	< STRING >
+\endcode
+
+Note that if the blob of data (raw or pointed by filename) is too
+large to fit in the property values array, then OCPF will
+automatically open a stream for the property and write its data in the
+stream.
+
+\code
+	PR_HTML = { 0x48 0x65 0x6c 0x6c 0x6f } /* Hello */
+	PR_HTML = <"/tmp/sample.html">
+\endcode
+
+<a name="comments"></a><h2>9. Comments</h2>
+
+OCPF files can contain comments embedded in normal C-style comment
+markers. That is, a comment starts with a combination of / followed by *,
+and ends with combination of * followed by /.
+
+Anything contained with in comment markers is ignored by the OCPF tools,
+and is only for the convenience of human readers.
+
+\code
+/* This is a comment */
+\endcode
+
+<a name="tools"></a><h2>10. OCPF and openchangeclient</h2>
+
+OCPF support has been added to the openchangeclient utility.
+It now has the ability to parse and process OCPF files. Two different 
+options are supported; you can either check an OCPF files' syntax
+(--ocpf_syntax) or process the files (--ocpf_sender).
+
+Users can set OCPF files using --ocpf-file=filename. Note that you can
+specify --ocpf-file multiple times if you have split the OCPF contents
+into different files. However the whole OCPF files you specify must
+only represent a single message.
+
+Sample OCPF files are provided in the distribution (libocpf/examples),
+and can also be browsed from the <a href="examples.html">Examples section</a>
+of this documentation:
+<ul>
+  <li> <a href="sample__appointment_8ocpf-example.html">sample_appointment.ocpf</a> </li>
+  <li> <a href="sample__task_8ocpf-example.html">sample_task.ocpf</a> </li>
+</ul>
+
+<a name="syntax"></a><h2>10.1 ocpf_syntax</h2>
+Process specified OCPF files, display syntax errors if detected and dump
+OCPF context content on standard output.
+
+\code
+openchangeclient --ocpf-syntax	\
+		 --ocpf-file=libocpf/examples/sample_appointment.ocpf 
+\endcode
+
+<a name="sender"></a><h2>10.2. ocpf_sender</h2>
+
+Process specified OCPF files and create/send a message using OCPF context
+contents.
+
+\code
+openchangeclient --ocpf_sender \
+		 --ocpf-file=libocpf/examples/sample_appointment.ocpf
+\endcode
+
+<a name="dump"></a><h2>10.3 ocpf_dump</h2>
+Process specified MAPI message and generates the corresponding OCPF
+file on the filesystem.
+
+\code
+openchangeclient --fetch-items=Appointment
+MAILBOX (1 messages)
+|== test ==| : AA13000000000001/20C140000000003
+        Location: paris
+        Start time     :   Sat Mar 29 09:00:00 2008 CET
+        End time       :   Sat Mar 29 09:30:00 2008 CET
+        Timezone: (GMT+01:00) Brussels, Copenhagen, Madrid, Paris
+        Private: False
+        Status: Completed
+    fetchitems               : MAPI_E_SUCCESS (0x0)
+
+openchangeclient --ocpf-dump=AA13000000000001/20C140000000003
+OCPF output file: 20c140000000003.ocpf
+    OCPF Dump                : MAPI_E_SUCCESS (0x0)
+\endcode
+
+*/
+
+/** \example sample_appointment.ocpf
+    
+This example shows a sample OCPF file designed to create a calendar
+with the following details:
+- Event starting the 6th of March at 10:00PM and ending at 11:45PM
+- Reminder set 45 minutes before the beginning of event
+- Label set to Anniversary
+- Subject, Body, Location and Private flag set
+
+*/
+
+/** \example sample_task.ocpf
+
+This example shows a sample OCPF file designed to create a task with
+the following details:
+- Task starting the 6th of March at 8:00PM and ending at 11:00PM
+- Importance set to High
+- Waiting for someone else
+- Subject, Body and Private flag set
+
+*/

Added: trunk/openchange/libocpf/ocpf.h
===================================================================
--- trunk/openchange/libocpf/ocpf.h	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,32 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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	__OCPF_H_
+#define	__OCPF_H_
+
+#include <libmapi/libmapi.h>
+#include <libocpf/proto.h>
+
+#define	OCPF_SUCCESS	0x0
+#define	OCPF_ERROR	0x1
+
+extern struct ocpf	*ocpf;
+extern unsigned int	lineno;
+
+#endif /* ! __OCPF_H_ */

Added: trunk/openchange/libocpf/ocpf.y
===================================================================
--- trunk/openchange/libocpf/ocpf.y	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf.y	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,452 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 "libocpf/ocpf_private.h"
+#include <libocpf/ocpf.h>
+#include <libocpf/ocpf_api.h>
+#include <libocpf/lex.h>
+
+void yyerror(char *);
+
+union SPropValue_CTR	lpProp;
+struct ocpf_nprop      	nprop;
+int		       	typeset;
+uint16_t       	       	type;
+int			folderset;
+uint8_t			recip_type;
+
+%}
+
+%union {
+	uint8_t				i;
+	uint8_t				b;
+	uint16_t			s;
+	uint32_t			l;
+	uint64_t			d;
+	char				*name;
+	char				*nameW;
+	char				*date;
+	char				*var;
+	struct StringArray_r		MVszA;
+}
+
+%token <i> UINT8
+%token <b> BOOLEAN
+%token <s> SHORT
+%token <l> INTEGER
+%token <d> DOUBLE
+%token <name> IDENTIFIER
+%token <name> STRING
+%token <nameW> UNICODE
+%token <MVszA> MVSTRING
+%token <date> SYSTIME
+%token <var> VAR
+
+%token kw_TYPE
+%token kw_FOLDER
+%token kw_OLEGUID
+%token kw_SET
+%token kw_PROPERTY
+%token kw_NPROPERTY
+%token kw_RECIPIENT
+%token kw_TO
+%token kw_CC
+%token kw_BCC
+%token kw_OOM
+%token kw_MNID_ID
+%token kw_MNID_STRING
+
+%token kw_PT_BOOLEAN
+%token kw_PT_STRING8
+%token kw_PT_UNICODE
+%token kw_PT_SHORT
+%token kw_PT_LONG
+%token kw_PT_SYSTIME
+%token kw_PT_MV_STRING8
+%token kw_PT_BINARY
+
+%token OBRACE
+%token EBRACE
+%token COMMA
+%token SEMICOLON
+%token COLON
+%token LOWER
+%token GREATER
+%token EQUAL
+
+%start keywords
+
+%%
+
+keywords	: | keywords kvalues
+		{
+			memset(&lpProp, 0, sizeof (union SPropValue_CTR));
+		}
+		;
+
+kvalues		: Type
+		| Folder
+		| OLEGUID
+		| Set
+		| Property
+		| NProperty
+		| Recipient
+		;
+
+Type		: 
+		kw_TYPE STRING
+		{
+			if (!typeset) {
+				ocpf_type_add($2);
+				typeset++;
+			} else {
+				error_message("%s", "duplicated TYPE\n");
+				return -1;
+			}
+		}
+		;
+
+Folder		:
+		kw_FOLDER STRING
+		{
+			if (folderset == false) {
+				ocpf_folder_add($2, 0, NULL);
+				folderset = true;
+			} else {
+				error_message("%s", "duplicated FOLDER\n");
+			}
+		}
+		| kw_FOLDER DOUBLE
+		{
+			if (folderset == false) {
+				ocpf_folder_add(NULL, $2, NULL);
+				folderset = true;
+			} else {
+				error_message("%s", "duplicated FOLDER\n");
+			}
+		}
+		| kw_FOLDER VAR
+		{
+			if (folderset == false) {
+				ocpf_folder_add(NULL, 0, $2);
+				folderset = true;
+			} else {
+				error_message("%s", "duplicated FOLDER\n");
+			}
+		}
+		;
+
+OLEGUID		: 
+		kw_OLEGUID IDENTIFIER STRING
+		{ 
+			char *name;
+			char *guid;
+			
+			name = talloc_strdup(ocpf->mem_ctx, $2);
+			guid = talloc_strdup(ocpf->mem_ctx, $3);
+
+			ocpf_oleguid_add(name, guid);
+		}
+		;
+
+Set		:
+		kw_SET VAR EQUAL propvalue
+		{
+			ocpf_variable_add($2, lpProp, type, true);
+			memset(&lpProp, 0, sizeof (union SPropValue_CTR));
+		}
+		;
+
+Property	:
+		kw_PROPERTY OBRACE pcontent EBRACE SEMICOLON
+		{
+		}
+
+pcontent       	: | pcontent content
+		{
+			memset(&lpProp, 0, sizeof (union SPropValue_CTR));
+		}
+		;
+
+content		:
+		IDENTIFIER EQUAL propvalue
+		{
+		  ocpf_propvalue_s($1, lpProp, type, true);
+			ocpf_propvalue_free(lpProp, type);
+		}
+		| INTEGER EQUAL propvalue
+		{
+			ocpf_propvalue($1, lpProp, type, true);
+			ocpf_propvalue_free(lpProp, type);
+		}
+		| IDENTIFIER EQUAL VAR
+		{
+			ocpf_propvalue_var($1, 0x0, $3, true);
+		}
+		| INTEGER EQUAL VAR
+		{
+			ocpf_propvalue_var(NULL, $1, $3, true);
+		}
+		;
+
+propvalue	: STRING	
+		{ 
+			lpProp.lpszA = talloc_strdup(ocpf->mem_ctx, $1); 
+			type = PT_STRING8; 
+		}
+		| UNICODE
+		{
+			lpProp.lpszW = talloc_strdup(ocpf->mem_ctx, $1);
+			type = PT_UNICODE;
+		}
+		| SHORT		{ lpProp.i = $1; type = PT_SHORT; }
+		| INTEGER	{ lpProp.l = $1; type = PT_LONG; }
+		| BOOLEAN	{ lpProp.b = $1; type = PT_BOOLEAN; }
+		| DOUBLE	{ lpProp.d = $1; type = PT_DOUBLE; }
+		| SYSTIME
+		{
+			ocpf_add_filetime($1, &lpProp.ft);
+			type = PT_SYSTIME;
+		}
+		| OBRACE mvstring_contents STRING EBRACE
+		{
+			TALLOC_CTX *mem_ctx;
+
+			if (!lpProp.MVszA.cValues) {
+				lpProp.MVszA.cValues = 0;
+				lpProp.MVszA.lppszA = talloc_array(ocpf->mem_ctx, const char *, 2);
+			} else {
+				lpProp.MVszA.lppszA = talloc_realloc(NULL, lpProp.MVszA.lppszA, const char *,
+								     lpProp.MVszA.cValues + 2);
+			}
+			mem_ctx = (TALLOC_CTX *) lpProp.MVszA.lppszA;
+			lpProp.MVszA.lppszA[lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, $3);
+			lpProp.MVszA.cValues += 1;
+
+			type = PT_MV_STRING8;
+		}
+		| OBRACE binary_contents EBRACE
+		{
+			type = PT_BINARY;
+		}
+		| LOWER STRING GREATER
+		{
+			int	ret;
+
+			ret = ocpf_binary_add($2, &lpProp.bin);
+			type = (ret == OCPF_SUCCESS) ? PT_BINARY : PT_ERROR;
+		}
+		;
+
+mvstring_contents: | mvstring_contents mvstring_content
+
+
+mvstring_content  : STRING COMMA
+		  {
+			TALLOC_CTX *mem_ctx;
+
+			if (!lpProp.MVszA.cValues) {
+				lpProp.MVszA.cValues = 0;
+				lpProp.MVszA.lppszA = talloc_array(ocpf->mem_ctx, const char *, 2);
+			} else {
+				lpProp.MVszA.lppszA = talloc_realloc(NULL, lpProp.MVszA.lppszA, const char *,
+								     lpProp.MVszA.cValues + 2);
+			}
+			mem_ctx = (TALLOC_CTX *) lpProp.MVszA.lppszA;
+			lpProp.MVszA.lppszA[lpProp.MVszA.cValues] = talloc_strdup(mem_ctx, $1);
+			lpProp.MVszA.cValues += 1;
+		  }
+		  ;
+
+binary_contents: | binary_contents binary_content
+
+binary_content	: INTEGER
+		{
+			TALLOC_CTX *mem_ctx;
+
+			if ($1 > 0xFF) {
+				error_message("Invalid Binary constant: 0x%x > 0xFF\n", $1);
+			}
+
+			if (!lpProp.bin.cb) {
+				lpProp.bin.cb = 0;
+				lpProp.bin.lpb = talloc_array(ocpf->mem_ctx, uint8_t, 2);
+			} else {
+				lpProp.bin.lpb = talloc_realloc(NULL, lpProp.bin.lpb, uint8_t,
+								lpProp.bin.cb + 2);
+			}
+			mem_ctx = (TALLOC_CTX *) lpProp.bin.lpb;
+			lpProp.bin.lpb[lpProp.bin.cb] = $1;
+			lpProp.bin.cb += 1;
+		}
+		;
+
+NProperty	:
+		kw_NPROPERTY OBRACE npcontent EBRACE SEMICOLON
+		{
+		}
+
+npcontent	: | npcontent ncontent
+		{
+			memset(&lpProp, 0, sizeof (union SPropValue_CTR));
+		}
+		;
+
+ncontent	: kind EQUAL propvalue
+		{
+			ocpf_nproperty_add(&nprop, lpProp, NULL, type, true);
+		}
+		| known_kind EQUAL propvalue
+		{
+			ocpf_nproperty_add(&nprop, lpProp, NULL, type, true);
+		}
+		| kind EQUAL VAR
+		{
+			ocpf_nproperty_add(&nprop, lpProp, $3, type, true);
+		}
+		| known_kind EQUAL VAR
+		{
+			ocpf_nproperty_add(&nprop, lpProp, $3, type, true);
+		}
+		;
+
+kind		: kw_OOM COLON IDENTIFIER COLON IDENTIFIER
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.OOM = talloc_strdup(ocpf->mem_ctx, $3);
+			nprop.guid = $5;
+		}
+		| kw_MNID_ID COLON INTEGER COLON proptype COLON IDENTIFIER
+		{
+			nprop.registered = false;
+			nprop.mnid_id = $3;
+			nprop.guid = $7;
+		}
+		| kw_MNID_STRING COLON STRING COLON proptype COLON IDENTIFIER
+		{
+			nprop.registered = false;
+			nprop.mnid_string = talloc_strdup(ocpf->mem_ctx, $3);
+			nprop.guid = $7;
+		}
+		;
+
+proptype	: kw_PT_STRING8	
+		{
+ 			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_STRING8; 
+		}
+		| kw_PT_UNICODE
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_UNICODE; 
+		}
+		| kw_PT_SHORT
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_SHORT;
+		}
+		| kw_PT_LONG 
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_LONG; 
+		}
+		| kw_PT_BOOLEAN
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_BOOLEAN;
+		}
+		| kw_PT_SYSTIME
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_SYSTIME; 
+		}
+		| kw_PT_MV_STRING8
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_MV_STRING8;
+		}
+		| kw_PT_BINARY
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.propType = PT_BINARY;
+		}
+		;
+
+known_kind	: kw_MNID_ID COLON INTEGER COLON IDENTIFIER
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.registered = true;
+			nprop.mnid_id = $3;
+			nprop.guid = $5;
+		}
+		| kw_MNID_STRING COLON STRING COLON IDENTIFIER
+		{
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			nprop.registered = true;
+			nprop.mnid_string = talloc_strdup(ocpf->mem_ctx, $3);
+			nprop.guid = $5;
+		}
+		;
+
+Recipient	: 
+		kw_RECIPIENT recipClass recipients STRING
+		{
+			char	*recipient = NULL;
+
+			recipient = talloc_strdup(ocpf->mem_ctx, $4);
+			ocpf_recipient_add(recip_type, recipient);
+			talloc_free(recipient);
+
+			recip_type = 0;
+		}
+		;
+
+recipClass	: kw_TO
+		{
+			recip_type = MAPI_TO;
+		}
+		| kw_CC
+		{
+			recip_type = MAPI_CC;
+		}
+		| kw_BCC
+		{
+			recip_type = MAPI_BCC;
+		}
+		;
+
+recipients	: | recipients recipient
+
+recipient	: STRING SEMICOLON
+		{
+			char	*recipient = NULL;
+
+			recipient = talloc_strdup(ocpf->mem_ctx, $1);
+			ocpf_recipient_add(recip_type, recipient);
+			talloc_free(recipient);
+		}
+
+%%
+
+void yyerror(char *s)
+{
+	printf("%s: %d", s, lineno);
+}

Added: trunk/openchange/libocpf/ocpf_api.c
===================================================================
--- trunk/openchange/libocpf/ocpf_api.c	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_api.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,578 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 "libocpf/ocpf_private.h"
+#include <libocpf/ocpf.h>
+#include <libocpf/ocpf_api.h>
+#include <libocpf/ocpf.tab.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <time.h>
+
+/**
+   \file ocpf_api.c
+
+   \brief ocpf Private API
+ */
+
+
+void ocpf_do_debug(const char *format, ...)
+{
+	va_list ap;
+	char	*s = NULL;
+	int	ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	printf("%s:%d: %s\n", ocpf_get_filename(), lineno, s);
+	free(s);
+}
+
+const char *ocpf_get_filename(void)
+{
+	return ocpf->filename;
+}
+
+
+int ocpf_propvalue_var(const char *propname, uint32_t proptag, const char *variable, bool unescape)
+{
+	struct ocpf_var		*vel;
+	struct ocpf_property	*element;
+	uint32_t		aulPropTag;
+
+	if (!ocpf || !ocpf->mem_ctx) return -1;
+	if (!propname && !proptag) return -1;
+	if (propname && proptag) return -1;
+
+	/* Sanity check: do not insert the same property twice */
+	if (proptag) {
+		aulPropTag = proptag;
+	} else {
+		aulPropTag = get_proptag_value(propname);
+	}
+
+	for (element = ocpf->props; element->next; element = element->next) {
+		OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, OCPF_WARN_PROP_REGISTERED, NULL);
+	}
+
+	for (vel = ocpf->vars; vel->next; vel = vel->next) {
+		if (vel->name && !strcmp(vel->name, variable)) {
+			OCPF_RETVAL_IF(vel->propType != (aulPropTag & 0xFFFF), OCPF_WARN_PROPVALUE_MISMATCH, NULL);
+			element = NULL;
+			element = talloc_zero(ocpf->mem_ctx, struct ocpf_property);
+			element->aulPropTag = aulPropTag;
+			if (unescape && (((aulPropTag & 0xFFFF) == PT_STRING8) || 
+					 ((aulPropTag & 0xFFFF) == PT_UNICODE))) {
+				element->value = ocpf_write_unescape_string(vel->value);
+			} else {
+				element->value = vel->value;
+			}
+			DLIST_ADD(ocpf->props, element);
+			return OCPF_SUCCESS;
+		}
+	}
+
+	OCPF_RETVAL_IF(1, OCPF_WARN_VAR_NOT_REGISTERED, NULL);
+}
+
+
+int ocpf_set_propvalue(TALLOC_CTX *mem_ctx, const void **value, uint16_t proptype, uint16_t sproptype, 
+		       union SPropValue_CTR lpProp, bool unescape)
+{
+	char	*str = NULL;
+
+	OCPF_RETVAL_IF(proptype != sproptype, OCPF_WARN_PROPVALUE_MISMATCH, NULL);
+
+	switch (proptype) {
+	case PT_STRING8:
+		if (unescape) {
+			str = ocpf_write_unescape_string(lpProp.lpszA);
+		} else {
+			str = talloc_strdup(ocpf->mem_ctx, lpProp.lpszA);
+		}
+		*value = talloc_memdup(mem_ctx, str, strlen(str) + 1);
+		talloc_free(str);
+		return OCPF_SUCCESS;
+	case PT_UNICODE:
+		if (unescape) {
+			str = ocpf_write_unescape_string(lpProp.lpszW);
+		} else {
+			str = talloc_strdup(ocpf->mem_ctx, lpProp.lpszW);
+		}
+		*value = talloc_memdup(mem_ctx, str, strlen(str) + 1);
+		talloc_free(str);
+		return OCPF_SUCCESS;
+	case PT_SHORT:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.i, sizeof (uint16_t));
+		return OCPF_SUCCESS;
+	case PT_LONG:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.l, sizeof (uint32_t));
+		return OCPF_SUCCESS;
+	case PT_BOOLEAN:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.b, sizeof (uint8_t));
+		return OCPF_SUCCESS;
+	case PT_ERROR:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.err, sizeof (uint32_t));
+		return OCPF_SUCCESS;
+	case PT_DOUBLE:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.d, sizeof (uint64_t));
+		return OCPF_SUCCESS;
+	case PT_SYSTIME:
+		*value = talloc_memdup(mem_ctx, (const void *)&lpProp.ft, sizeof (struct FILETIME));
+		return OCPF_SUCCESS;
+	case PT_BINARY:
+		*value = (const void *)talloc_zero(mem_ctx, struct Binary_r);
+		((struct Binary_r *)*value)->cb = lpProp.bin.cb;
+		((struct Binary_r *)*value)->lpb = talloc_memdup(mem_ctx, (const void *)lpProp.bin.lpb, lpProp.bin.cb);
+		return OCPF_SUCCESS;
+	case PT_MV_STRING8:
+		*value = (const void *)talloc_zero(mem_ctx, struct StringArray_r);
+		((struct StringArray_r *)*value)->cValues = lpProp.MVszA.cValues;
+		((struct StringArray_r *)*value)->lppszA = talloc_array(mem_ctx, const char *, lpProp.MVszA.cValues);
+		{
+			uint32_t	i;
+
+			for (i = 0; i < lpProp.MVszA.cValues; i++) {
+				if (unescape) {
+					str = ocpf_write_unescape_string(lpProp.MVszA.lppszA[i]);
+				} else {
+					str = (char *)lpProp.MVszA.lppszA[i];
+				}
+				((struct StringArray_r *)*value)->lppszA[i] = talloc_strdup(mem_ctx, str);
+				talloc_free(str);
+			}
+		}
+		return OCPF_SUCCESS;
+	default:
+		OCPF_WARN(("%s (0x%.4x)", OCPF_WARN_PROP_TYPE, proptype));
+		return OCPF_ERROR;
+	}
+	return OCPF_ERROR;
+}
+
+int ocpf_propvalue_free(union SPropValue_CTR lpProp, uint16_t proptype)
+{
+	switch (proptype) {
+	case PT_STRING8:
+		talloc_free((char *)lpProp.lpszA);
+		break;
+	case PT_UNICODE:
+		talloc_free((char *)lpProp.lpszW);
+		break;
+	case PT_MV_STRING8:
+		talloc_free(lpProp.MVszA.lppszA);
+		break;
+	}
+	return OCPF_SUCCESS;
+}
+
+int ocpf_propvalue(uint32_t aulPropTag, union SPropValue_CTR lpProp, uint16_t proptype, bool unescape)
+{
+	struct ocpf_property	*element;
+	int			ret;
+
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+
+	/* Sanity check: do not insert the same property twice */
+	for (element = ocpf->props; element->next; element = element->next) {
+		OCPF_RETVAL_IF(element->aulPropTag == aulPropTag, OCPF_WARN_PROP_REGISTERED, NULL);
+	}
+
+	element = NULL;
+	element = talloc_zero(ocpf->mem_ctx, struct ocpf_property);
+	element->aulPropTag = aulPropTag;
+	ret = ocpf_set_propvalue((TALLOC_CTX *)element, &element->value, (uint16_t)aulPropTag & 0xFFFF, proptype, lpProp, unescape);
+	if (ret == -1) {
+		talloc_free(element);
+		return OCPF_ERROR;
+	}
+
+	DLIST_ADD(ocpf->props, element);
+	return OCPF_SUCCESS;
+}
+
+
+void ocpf_propvalue_s(const char *propname, union SPropValue_CTR lpProp, uint16_t proptype, bool unescape)
+{
+	uint32_t	aulPropTag;
+
+	aulPropTag = get_proptag_value(propname);
+	ocpf_propvalue(aulPropTag, lpProp, proptype, unescape);
+}
+
+
+/**
+   \details Add a named property
+
+   This function adds either a custom or a known named property and
+   supplies either the lpProp value or substitute with registered
+   variable.
+
+   \param nprop pointer on a ocpf named property entry
+   \param lpProp named property value
+   \param var_name variable name
+   \param proptype variable property type
+   \param unescape whether the property value should be escaped
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR.
+ */
+int ocpf_nproperty_add(struct ocpf_nprop *nprop, union SPropValue_CTR lpProp,
+		       const char *var_name, uint16_t proptype, bool unescape)
+{
+	enum MAPISTATUS		retval;
+	int			ret = 0;
+	struct ocpf_nproperty	*element;
+	struct ocpf_nproperty	*el;
+	struct ocpf_var		*vel;
+
+	if (!ocpf || !ocpf->mem_ctx) return -1;
+
+	element = talloc_zero(ocpf->mem_ctx, struct ocpf_nproperty);
+
+	if (nprop->guid) {
+		ret = ocpf_oleguid_check(nprop->guid, &element->oleguid);
+		OCPF_RETVAL_IF(ret == -1, OCPF_WARN_OLEGUID_UNREGISTERED, element);
+	}
+
+	if (nprop->OOM) {
+		/*
+		 * Sanity check: do not insert twice the same
+		 * (OOM,oleguid) couple
+		 */
+		for (el = ocpf->nprops; el->next; el = el->next) {
+			OCPF_RETVAL_IF((el->OOM && !strcmp(el->OOM, nprop->OOM)) &&
+				       (el->oleguid && !strcmp(el->oleguid, nprop->guid)),
+				       OCPF_WARN_OOM_REGISTERED, element);
+		}
+
+		element->kind = OCPF_OOM;
+		element->OOM = nprop->OOM;
+		retval = mapi_nameid_OOM_lookup(element->OOM, element->oleguid,
+						&element->propType);
+		OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, OCPF_WARN_OOM_UNKNOWN, element);
+	} else if (nprop->mnid_string) {
+		/* 
+		 * Sanity check: do not insert twice the same
+		 * (mnid_string,oleguid) couple 
+		 */
+		for (el = ocpf->nprops; el->next; el = el->next) {
+			OCPF_RETVAL_IF((el->mnid_string && !strcmp(el->mnid_string, nprop->mnid_string)) &&
+				       (el->oleguid && !strcmp(el->oleguid, nprop->guid)),
+				       OCPF_WARN_STRING_REGISTERED, element);
+		}
+
+		element->kind = OCPF_MNID_STRING;
+		element->mnid_string = nprop->mnid_string;
+		if (nprop->registered == true) {
+			retval = mapi_nameid_string_lookup(element->mnid_string, 
+							   element->oleguid,
+							   &element->propType);
+			OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, OCPF_WARN_STRING_UNKNOWN, element);
+		} else {
+			element->propType = nprop->propType;
+		}
+	} else if (nprop->mnid_id) {
+		/* 
+		 * Sanity check: do not insert twice the same
+		 * (mnid_id-oleguid) couple 
+		 */
+		for (el = ocpf->nprops; el->next; el = el->next) {
+			OCPF_RETVAL_IF((el->mnid_id == nprop->mnid_id) && 
+				       (el->oleguid && !strcmp(el->oleguid, nprop->guid)),
+				       OCPF_WARN_LID_REGISTERED, element);
+		}
+		element->kind = OCPF_MNID_ID;
+		element->mnid_id = nprop->mnid_id;
+		if (nprop->registered == true) {
+			retval = mapi_nameid_lid_lookup(element->mnid_id,
+							element->oleguid,
+							&element->propType);
+			OCPF_RETVAL_IF(retval != MAPI_E_SUCCESS, OCPF_WARN_LID_UNKNOWN, element);
+		} else {
+			element->propType = nprop->propType;
+		}
+	}
+
+	if (var_name) {
+		for (vel = ocpf->vars; vel->next; vel = vel->next) {
+			if (vel->name && !strcmp(vel->name, var_name)) {
+				OCPF_RETVAL_IF(element->propType != vel->propType, OCPF_WARN_PROPVALUE_MISMATCH, element);
+				element->value = vel->value;
+			}
+		}
+		OCPF_RETVAL_IF(!element->value, OCPF_WARN_VAR_NOT_REGISTERED, element);
+	} else {
+		ret = ocpf_set_propvalue((TALLOC_CTX *)element, &element->value, element->propType, proptype, lpProp, unescape);
+		if (ret == -1) {
+			talloc_free(element);
+			return OCPF_ERROR;
+		}
+	}
+
+	DLIST_ADD(ocpf->nprops, element);
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Register OCPF message type
+   
+   Register OCPF message type
+
+   \param type message type to register
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+ */
+int ocpf_type_add(const char *type)
+{
+	if (!ocpf || !ocpf->mem_ctx || !type) return OCPF_ERROR;
+
+	ocpf->type = talloc_strdup(ocpf->mem_ctx, type);
+
+	return OCPF_SUCCESS;
+}
+
+
+/* WARNING: This array doesn't hold all possible values */
+static struct ocpf_olfolder olfolders[] = {
+	{ olFolderTopInformationStore,	"olFolderTopInformationStore"	},
+	{ olFolderDeletedItems,		"olFolderDeletedItems"		},
+	{ olFolderOutbox,		"olFolderOutbox"		},
+	{ olFolderSentMail,		"olFolderSentMail"		},
+	{ olFolderInbox,		"olFolderInbox"			},
+	{ olFolderCommonView,		"olFolderCommonView"		},
+	{ olFolderCalendar,		"olFolderCalendar"		},
+	{ olFolderContacts,		"olFolderContacts"		},
+	{ olFolderJournal,		"olFolderJournal"		},
+	{ olFolderNotes,		"olFolderNotes"			},
+	{ olFolderTasks,		"olFolderTasks"			},
+	{ 0, NULL }
+};
+
+static int64_t ocpf_folder_name_to_id(const char *name)
+{
+	uint32_t	i;
+
+	if (!name) return OCPF_ERROR;
+
+	for (i = 0; olfolders[i].name; i++) {
+		if (olfolders[i].name && !strcmp(olfolders[i].name, name)) {
+			return olfolders[i].id;
+		}
+	}
+	return OCPF_ERROR;
+}
+
+/**
+   \details Register OCPF folder
+
+   Register the folder where the OCPF message needs to be saved
+
+   \param name the name of the default folder if specified
+   \param id the folder id of the message if specified
+   \param var_name the substitution variable to use for folder ID if
+   specified
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+ */
+int ocpf_folder_add(const char *name, uint64_t id, const char *var_name)
+{
+	struct ocpf_var		*element;
+
+	/* Sanity check */
+	if ((name && id) || (name && var_name) || (id && var_name)) return OCPF_ERROR;
+	if (!name && !id && !var_name) return OCPF_ERROR;
+
+	if (name) {
+		ocpf->folder = (uint64_t) ocpf_folder_name_to_id(name);
+		OCPF_RETVAL_IF(ocpf->folder == -1, OCPF_WARN_FOLDER_ID_UNKNOWN, NULL);
+	} else if (id) {
+		ocpf->folder = id;
+	} else if (var_name) {
+		for (element = ocpf->vars; element->next; element = element->next) {
+			if (element->name && !strcmp(element->name, var_name)) {
+				/* WARNING: we assume var data is double */
+				ocpf->folder = *((uint64_t *)element->value);
+			}
+		}
+	}
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Register new OLEGUID in ocpf context
+
+   This function registers a OLEGUID couple name, value in ocpf.
+
+   \param name the OLEGUID name
+   \param oleguid the guid string value
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+ */
+int ocpf_oleguid_add(const char *name, const char *oleguid)
+{
+	NTSTATUS		status;
+	struct ocpf_oleguid	*element;
+	struct GUID		guid;
+
+	/* Sanity checks */
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+	if (!name) return OCPF_ERROR;
+
+	/* Sanity check: Do not insert twice the same name or guid */
+	for (element = ocpf->oleguid; element->next; element = element->next) {
+		OCPF_RETVAL_IF(element->name && !strcmp(element->name, name),
+			       OCPF_WARN_OLEGUID_N_REGISTERED, NULL);
+
+		OCPF_RETVAL_IF(element->guid && !strcmp(element->guid, oleguid),
+			       OCPF_WARN_OLEGUID_G_REGISTERED, NULL);
+	}
+
+	element = talloc_zero(ocpf->mem_ctx, struct ocpf_oleguid);
+
+	status = GUID_from_string(oleguid, &guid);
+	OCPF_RETVAL_IF(!NT_STATUS_IS_OK(status), OCPF_WARN_OLEGUID_INVALID, element);
+
+	element->name = talloc_strdup(ocpf->mem_ctx, name);
+	element->guid = talloc_strdup(ocpf->mem_ctx, oleguid);
+
+	DLIST_ADD(ocpf->oleguid, element);
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Check if the given OLEGUID has been registered
+
+   \param name the OLEGUID to check
+   \param guid pointer on pointer to the guid result
+
+   \result OCPF_SUCCESS on success, otherwise OCPF_ERROR;
+ */
+int ocpf_oleguid_check(const char *name, const char **guid)
+{
+	struct ocpf_oleguid	*element;
+
+	for (element = ocpf->oleguid; element->next; element = element->next) {	
+		if (element->name && !strcmp(element->name, name)) {
+			*guid = element->guid;
+			return OCPF_SUCCESS;
+		}
+	}
+
+	return OCPF_ERROR;
+}
+
+
+/**
+   \details convert a string to FILETIME structure
+
+   This function converts a string - representing a date under the
+   following format "Tyyy-mm-dd hh:mm:ss" - into a FILETIME structure.
+
+   \param date the date to convert
+   \param ft pointer on the converted date
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+ */
+int ocpf_add_filetime(const char *date, struct FILETIME *ft)
+{
+	NTTIME		nt;
+	struct tm	tm;
+
+	if (!strptime(date, DATE_FORMAT, &tm)) {
+		printf("Invalid data format: Tyyy-mm-dd hh:mm:ss (e.g.: T2008-03-06 23:30:00");
+		return OCPF_ERROR;
+	}
+	
+	unix_to_nt_time(&nt, mktime(&tm));
+	ft->dwLowDateTime = (nt << 32) >> 32;
+	ft->dwHighDateTime = (nt >> 32);
+
+	return OCPF_SUCCESS;
+}
+
+
+int ocpf_variable_add(const char *name, union SPropValue_CTR lpProp, uint16_t propType, bool unescape)
+{
+	struct ocpf_var		*element;
+	int			ret;
+
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+	if (!name) return OCPF_ERROR;
+
+	/* Sanity check: Do not insert twice the same variable */
+	for (element = ocpf->vars; element->next; element = element->next) {
+		OCPF_RETVAL_IF(element->name && !strcmp(element->name, name),
+			       OCPF_WARN_VAR_REGISTERED, NULL);
+	}
+
+	element = talloc_zero(ocpf->mem_ctx, struct ocpf_var);
+	element->name = talloc_strdup((TALLOC_CTX *)element, name);
+	element->propType = propType;
+
+	ret = ocpf_set_propvalue((TALLOC_CTX *)element, &element->value, propType, propType, lpProp, unescape);
+	OCPF_RETVAL_IF(ret == -1, OCPF_WARN_VAR_TYPE, element);
+
+	DLIST_ADD(ocpf->vars, element);
+
+	return OCPF_SUCCESS;
+}
+
+
+int ocpf_binary_add(const char *filename, struct Binary_r *bin)
+{
+	int		fd;
+	struct stat	sb;
+
+	OCPF_RETVAL_IF(stat(filename, &sb), OCPF_WARN_FILENAME_STAT, NULL);
+	fd = open(filename, O_RDONLY);
+	OCPF_RETVAL_IF(fd == -1, OCPF_WARN_FILENAME_INVALID, NULL);
+	
+	bin->lpb = talloc_size(ocpf->mem_ctx, sb.st_size);
+	bin->cb = read(fd, bin->lpb, sb.st_size);
+
+	close(fd);
+
+	return OCPF_SUCCESS;
+}
+
+int ocpf_recipient_add(uint8_t recipClass, char *recipient)
+{
+	struct ocpf_recipients	*element;
+
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+	if (!recipient) return OCPF_ERROR;
+
+	element = talloc_zero(ocpf->mem_ctx, struct ocpf_recipients);
+	element->name = talloc_strdup((TALLOC_CTX *)element, recipient);
+	element->class = recipClass;
+
+	DLIST_ADD(ocpf->recipients, element);
+
+	return OCPF_SUCCESS;
+}

Added: trunk/openchange/libocpf/ocpf_api.h
===================================================================
--- trunk/openchange/libocpf/ocpf_api.h	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_api.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,183 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 __OCPF_API_H_
+#define	__OCPF_API_H_
+
+#include <libmapi/libmapi.h>
+
+struct ocpf_var
+{
+	struct ocpf_var		*prev;
+	struct ocpf_var		*next;
+	const char		*name;
+	const void		*value;
+	uint16_t		propType;
+};
+
+struct ocpf_oleguid
+{
+	struct ocpf_oleguid	*prev;
+	struct ocpf_oleguid	*next;
+	const char		*name;
+	const char		*guid;
+};
+
+struct ocpf_property
+{
+	struct ocpf_property	*prev;
+	struct ocpf_property	*next;
+	uint32_t		aulPropTag;
+	const void		*value;
+};
+
+struct ocpf_nprop
+{
+	const char	*OOM;
+	const char	*mnid_string;
+	uint16_t	mnid_id;
+	uint16_t       	propType;
+	const char	*guid;
+	bool		registered;
+};
+
+enum ocpf_ntype {
+	OCPF_OOM = 0x1,
+	OCPF_MNID_ID,
+	OCPF_MNID_STRING
+};
+
+struct ocpf_nproperty
+{
+	struct ocpf_nproperty	*prev;
+	struct ocpf_nproperty	*next;
+	enum ocpf_ntype		kind;
+	const char		*OOM;
+	const char		*mnid_string;
+	uint16_t		mnid_id;
+	uint16_t		propType;
+	const char		*oleguid;
+	const void		*value;
+};
+
+enum ocpf_recipClass {
+	OCPF_MAPI_TO = 0x1,
+	OCPF_MAPI_CC,
+	OCPF_MAPI_BCC
+};
+
+struct ocpf_recipients
+{
+	struct ocpf_recipients	*prev;
+	struct ocpf_recipients	*next;
+	char			*name;
+	enum ocpf_recipClass	class;
+};
+
+struct ocpf
+{
+	TALLOC_CTX		*mem_ctx;
+	const char		*type;
+	struct ocpf_var		*vars;
+	struct ocpf_oleguid    	*oleguid;
+	struct ocpf_property	*props;
+	struct ocpf_nproperty	*nprops;
+	struct ocpf_recipients	*recipients;
+	const char		*filename;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+	uint64_t		folder;
+};
+
+
+struct ocpf_olfolder
+{
+	int			id;
+	const char		*name;
+};
+
+#include <libocpf/proto_private.h>
+
+/**
+ * Defines
+ */
+#define	OCPF_WARN(x) (ocpf_do_debug x)				
+
+#define	OCPF_RETVAL_IF(x, msg, mem_ctx)  		       	\
+do {								\
+	if (x) {						\
+		OCPF_WARN(("%s", msg));				\
+		if (mem_ctx) {					\
+			talloc_free(mem_ctx);			\
+		}						\
+		return OCPF_ERROR;     				\
+	}							\
+} while (0);
+
+#define	OCPF_INITIALIZED		"OCPF context has already been initialized"
+#define	OCPF_NOT_INITIALIZED		"OCPF context has not been initialized"
+
+#define	OCPF_WRITE_NOT_INITIALIZED	"OCPF write context has not been initialized"
+
+#define	OCPF_FATAL_ERROR		"Fatal error encountered"
+#define	OCPF_WARN_FILENAME_INVALID	"Invalid filename"
+#define	OCPF_WARN_FILENAME_STAT		"Unable to stat file"
+
+#define	OCPF_WARN_PROP_REGISTERED	"Property already registered"
+#define	OCPF_WARN_PROP_TYPE		"Property type not supported"
+#define	OCPF_WARN_PROP_UNKNOWN		"Property Unknown"
+
+#define	OCPF_WARN_OOM_UNKNOWN		"Unknown OOM"
+#define	OCPF_WARN_OOM_REGISTERED	"OOM already registered"
+
+#define	OCPF_WARN_LID_UNKNOWN		"Unknown MNID_ID"
+#define	OCPF_WARN_LID_REGISTERED	"MNID_ID already registered"
+
+#define	OCPF_WARN_STRING_UNKNOWN	"Unknown MNID_STRING"
+#define	OCPF_WARN_STRING_REGISTERED	"MNID_STRING already registered"
+
+
+#define	OCPF_WARN_OLEGUID_N_REGISTERED	"OLEGUID name already registered"
+#define	OCPF_WARN_OLEGUID_G_REGISTERED	"OLEGUID GUID already registered"
+#define	OCPF_WARN_OLEGUID_UNREGISTERED	"OLEGUID unregistered"
+#define	OCPF_WARN_OLEGUID_INVALID	"OLEGUID invalid"
+
+#define	OCPF_WARN_VAR_REGISTERED	"Variable already registered"
+#define	OCPF_WARN_VAR_NOT_REGISTERED	"Unknown variable"
+#define	OCPF_WARN_VAR_TYPE		"Variable property type not supported"
+
+#define	OCPF_WARN_FOLDER_ID_UNKNOWN	"Unknown Folder"
+
+#define	OCPF_WARN_PROPVALUE_MISMATCH	"Property type and value mismatch"
+
+#define	OCPF_INVALID_PROPARRAY		"Invalid property array"
+#define	OCPF_INVALID_FILEHANDLE		"Invalid file handle"
+
+
+#define	OCPF_PROPERTY_BEGIN		"PROPERTY {\n"
+#define	OCPF_NPROPERTY_BEGIN		"NPROPERTY {\n"
+#define	OCPF_END			"};\n"
+#define	OCPF_NEWLINE			"\n"
+#define	OCPF_RECIPIENT_TO		"RECIPIENT TO "
+#define	OCPF_RECIPIENT_CC		"RECIPIENT CC "
+#define	OCPF_RECIPIENT_BCC		"RECIPIENT BCC "
+
+#define	DATE_FORMAT     "%Y-%m-%d %H:%M:%S"
+
+#endif /* __OCPF_API_H_ */

Added: trunk/openchange/libocpf/ocpf_dump.c
===================================================================
--- trunk/openchange/libocpf/ocpf_dump.c	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_dump.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,221 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 "libocpf/ocpf_private.h"
+#include <libocpf/ocpf.h>
+#include <libocpf/ocpf_api.h>
+#include <libocpf/ocpf.tab.h>
+#include <libocpf/ocpf_dump.h>
+
+/**
+   \file ocpf_dump.c
+
+   \brief ocpf Dump API
+ */
+
+static void ocpf_do_dump(const char *format, ...)
+{
+	va_list	ap;
+	char	*s = NULL;
+	int	ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	printf("%s\n", s);
+	free(s);
+}
+
+
+/**
+   \details Dump OCPF Type
+
+   Dump OCPF Registered Type
+*/
+_PUBLIC_ void ocpf_dump_type(void)
+{
+	OCPF_DUMP_TITLE(indent, "TYPE", OCPF_DUMP_TOPLEVEL);
+	indent++;
+	
+	INDENT();
+	OCPF_DUMP(("* %s", ocpf->type ? ocpf->type : "Undefined"));
+	indent--;
+}
+
+
+/**
+   \details Dump OCPF Destination Folder
+
+   Dump OCPF Registered Destination Folder
+ */
+_PUBLIC_ void ocpf_dump_folder(void)
+{
+	OCPF_DUMP_TITLE(indent, "FOLDER", OCPF_DUMP_TOPLEVEL);
+	indent++;
+
+	INDENT();
+	OCPF_DUMP(("* 0x%llx", ocpf->folder ? ocpf->folder : -1));
+	indent--;
+}
+
+
+/**
+   \details Dump OCPF Recipients
+
+   Dump OCPF Recipients
+ */
+_PUBLIC_ void ocpf_dump_recipients(void)
+{
+	struct ocpf_recipients	*element;
+
+	OCPF_DUMP_TITLE(indent, "RECIPIENTS", OCPF_DUMP_TOPLEVEL);
+	indent++;
+
+	INDENT();
+	printf("* To: ");
+	for (element = ocpf->recipients; element->next; element = element->next) {
+		if (element->class == OCPF_MAPI_TO) {
+			printf("%s;", element->name);
+		}
+	}
+	printf("\n");
+
+	INDENT();
+	printf("* Cc: ");
+	for (element = ocpf->recipients; element->next; element = element->next) {
+		if (element->class == OCPF_MAPI_CC) {
+			printf("%s;", element->name);
+		}
+	}
+	printf("\n");
+
+	INDENT();
+	printf("* Bcc: ");
+	for (element = ocpf->recipients; element->next; element = element->next) {
+		if (element->class == OCPF_MAPI_BCC) {
+			printf("%s;", element->name);
+		}
+	}
+	printf("\n");
+}
+
+
+/**
+   \details Dump OCPF OLEGUID
+
+   Dump OCPF Registered OLEGUID
+*/
+_PUBLIC_ void ocpf_dump_oleguid(void)
+{
+	struct ocpf_oleguid	*element;
+
+	OCPF_DUMP_TITLE(indent, "OLEGUID", OCPF_DUMP_TOPLEVEL);
+	indent++;
+	for (element = ocpf->oleguid; element->next; element = element->next) {
+		INDENT();
+		printf("%-25s: %s\n", element->name, element->guid);
+	}
+	indent--;
+}
+
+
+_PUBLIC_ void ocpf_dump_variable(void)
+{
+	struct ocpf_var		*element;
+
+	OCPF_DUMP_TITLE(indent, "VARIABLE", OCPF_DUMP_TOPLEVEL);
+	indent++;
+	for (element = ocpf->vars; element->next; element = element->next) {
+		INDENT();
+		printf("%s\n", element->name);
+	}
+	indent--;
+}
+
+_PUBLIC_ void ocpf_dump_property(void)
+{
+	struct ocpf_property	*element;
+	const char		*proptag;
+
+	OCPF_DUMP_TITLE(indent, "PROPERTIES", OCPF_DUMP_TOPLEVEL);
+	indent++;
+	for (element = ocpf->props; element->next; element = element->next) {
+		INDENT();
+		proptag = (const char *)get_proptag_name(element->aulPropTag);
+		printf("0x%.8x = %s\n", element->aulPropTag,
+		       (char *)(proptag ? proptag : "UNKNOWN"));
+	
+	}
+	indent--;
+}
+
+
+_PUBLIC_ void ocpf_dump_named_property(void)
+{
+	struct ocpf_nproperty	*element;
+
+	OCPF_DUMP_TITLE(indent, "NAMED PROPERTIES", OCPF_DUMP_TOPLEVEL);
+	indent++;
+
+	OCPF_DUMP_TITLE(indent, "OOM", OCPF_DUMP_SUBLEVEL);
+	indent++;
+	for (element = ocpf->nprops; element->next; element = element->next) {
+		if (element->kind == OCPF_OOM) {
+			INDENT();
+			printf("* %s\n", element->OOM);
+		}
+	}
+	indent--;
+
+	OCPF_DUMP_TITLE(indent, "MNID_ID", OCPF_DUMP_SUBLEVEL);
+	indent++;
+	for (element = ocpf->nprops; element->next; element = element->next) {
+		if (element->kind == OCPF_MNID_ID) {
+			INDENT();
+			printf("* 0x%.4x\n", element->mnid_id);
+		}
+	}
+	indent--;
+
+	OCPF_DUMP_TITLE(indent, "MNID_STRING", OCPF_DUMP_SUBLEVEL);
+	indent++;
+	for (element = ocpf->nprops; element->next; element = element->next) {
+		if (element->kind == OCPF_MNID_STRING) {
+			INDENT();
+			printf("* %s\n", element->mnid_string);
+		}
+	}
+	indent--;
+
+	indent--;
+}
+
+
+_PUBLIC_ void ocpf_dump(void)
+{
+	indent = 0;
+	ocpf_dump_type();
+	ocpf_dump_folder();
+	ocpf_dump_oleguid();
+	ocpf_dump_recipients();
+	ocpf_dump_variable();
+	ocpf_dump_property();
+	ocpf_dump_named_property();
+}

Added: trunk/openchange/libocpf/ocpf_dump.h
===================================================================
--- trunk/openchange/libocpf/ocpf_dump.h	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_dump.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,61 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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 __OCPF_DUMP_H_
+#define	__OCPF_DUMP_H_
+
+#define	INDENT()			\
+do {					\
+	uint32_t	i;		\
+					\
+	for (i = 0; i < indent; i++) {	\
+		printf("\t");		\
+	}				\
+} while (0);
+
+
+#define	OCPF_DUMP(x) (ocpf_do_dump x)
+
+#define	OCPF_DUMP_TITLE(indent, txt, type)		\
+do {							\
+	int	i;					\
+	int	txt_len;				\
+							\
+	printf("\n");					\
+	INDENT();					\
+	printf("%s:\n", txt);				\
+							\
+	INDENT();					\
+	txt_len = strlen(txt) + 1;     			\
+	for (i = 0; i < txt_len; i++) {			\
+		printf("%c", type ? '-' : '=');		\
+	}						\
+	printf("\n");					\
+} while (0);
+
+
+#define	OCPF_DUMP_TOPLEVEL	0
+#define	OCPF_DUMP_SUBLEVEL	1
+
+
+int indent;
+
+
+
+#endif /* ! __OCPF_DUMP_H_ */

Added: trunk/openchange/libocpf/ocpf_private.h
===================================================================
--- trunk/openchange/libocpf/ocpf_private.h	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_private.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,35 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   Copyright (C) Julien Kerihuel 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/>.
+*/
+
+#ifndef	__OCPF_PRIVATE_H_
+#define	__OCPF_PRIVATE_H_
+
+#include "config.h"
+#include <stdlib.h>
+
+#ifndef HAVE_COMPARISON_FN_T
+#define HAVE_COMPARISON_FN_T
+typedef int (*comparison_fn_t)(const void *, const void *);
+#else
+# ifndef comparison_fn_t
+typedef __compar_fn_t comparison_fn_t;
+# endif
+#endif
+
+#endif /* ! __OCPF_PRIVATE_H_ */

Added: trunk/openchange/libocpf/ocpf_public.c
===================================================================
--- trunk/openchange/libocpf/ocpf_public.c	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_public.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,558 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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/>.
+*/
+
+/**
+   \file ocpf_public.c
+
+   \brief public OCPF API
+ */
+
+#include "libocpf/ocpf_private.h"
+#include <libocpf/ocpf.h>
+#include <libocpf/ocpf_api.h>
+
+#include <sys/stat.h>
+
+int ocpf_yyparse(void);
+
+struct ocpf	*ocpf;
+extern FILE	*yyin;
+int		error_flag;
+
+
+/**
+   \details Initialize OCPF context
+
+   Initialize ocpf context and allocate memory for internal structures
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa ocpf_release, ocpf_parse
+ */
+_PUBLIC_ int ocpf_init(void)
+{
+	TALLOC_CTX	*mem_ctx;
+	
+	if (ocpf) return OCPF_ERROR;
+
+	mem_ctx = talloc_named(NULL, 0, "ocpf");
+	ocpf = talloc_zero(mem_ctx, struct ocpf);
+	ocpf->mem_ctx = mem_ctx;
+	ocpf->vars = talloc_zero(mem_ctx, struct ocpf_var);
+	ocpf->oleguid = talloc_zero(mem_ctx, struct ocpf_oleguid);
+	ocpf->props = talloc_zero(mem_ctx, struct ocpf_property);
+	ocpf->nprops = talloc_zero(mem_ctx, struct ocpf_nproperty);
+	ocpf->recipients = talloc_zero(mem_ctx, struct ocpf_recipients);
+	ocpf->lpProps = NULL;
+	ocpf->filename = NULL;
+	ocpf->cValues = 0;
+	ocpf->folder = 0;
+	
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Uninitialize OCPF context
+
+   Uninitialize the global OCPF context and release memory.
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa ocpf_init
+ */
+_PUBLIC_ int ocpf_release(void)
+{
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+
+	talloc_free(ocpf->mem_ctx);
+	ocpf = NULL;
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Parse OCPF file
+
+   Parse and process the given ocpf file.
+
+   \param filename the file to parse
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa ocpf_init
+ */
+_PUBLIC_ int ocpf_parse(const char *filename)
+{
+	int		ret;
+	struct stat	sb;
+
+	if (!filename) return OCPF_ERROR;
+	if (!ocpf || !ocpf->mem_ctx) return OCPF_ERROR;
+
+	ocpf->filename = filename;
+	lineno = 1;
+
+	/* Sanity check on filename */
+	OCPF_RETVAL_IF((!filename || (stat(filename, &sb) == -1)), 
+		       OCPF_WARN_FILENAME_INVALID, NULL);
+
+	yyin = fopen(filename, "r");
+	OCPF_RETVAL_IF(yyin == NULL, OCPF_WARN_FILENAME_INVALID, NULL);
+
+	ret = ocpf_yyparse();
+	fclose(yyin);
+
+	return ret;
+}
+
+
+#define	MAX_READ_SIZE	0x1000
+
+static enum MAPISTATUS ocpf_stream(TALLOC_CTX *mem_ctx,
+				   mapi_object_t *obj_parent,
+				   uint32_t aulPropTag,
+				   struct Binary_r *bin)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_stream;
+	DATA_BLOB		stream;
+	uint32_t		access_flags = 2;	/* MAPI_MODIFY by default */
+	uint32_t		size;
+	uint32_t		offset;
+	uint16_t		read_size;
+
+	mapi_object_init(&obj_stream);
+
+	/* Step1. Open the Stream */
+	retval = OpenStream(obj_parent, aulPropTag, access_flags, &obj_stream);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	/* Step2. Write the Stream */
+	size = MAX_READ_SIZE;
+	offset = 0;
+	while (offset <= bin->cb) {
+		stream.length = size;
+		stream.data = talloc_size(mem_ctx, size);
+		memcpy(stream.data, bin->lpb + offset, size);
+		
+		retval = WriteStream(&obj_stream, &stream, &read_size);
+		talloc_free(stream.data);
+		OCPF_RETVAL_IF(retval, retval, NULL);
+
+		/* Exit when there is nothing left to write */
+		if (!read_size) return MAPI_E_SUCCESS;
+		
+		offset += read_size;
+
+		if ((offset + size) > bin->cb) {
+			size = bin->cb - offset;
+		}
+	}
+
+	mapi_object_release(&obj_stream);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Build a SPropValue array from ocpf context
+
+   This function builds a SPropValue array from the ocpf context and
+   information stored.
+
+   \param mem_ctx the memory context to use for memory allocation
+   \param obj_folder pointer the folder object we use for internal
+   MAPI operations
+   \param obj_message pointer to the message object we use for
+   internal MAPI operations
+
+   \return MAPI_E_SUCCESS on success, otherwise -1.
+
+   \note Developers should call GetLastError() to retrieve the last
+   MAPI error code. Possible MAPI error codes are:
+   - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+
+   \sa ocpf_get_SPropValue
+ */
+_PUBLIC_ enum MAPISTATUS ocpf_set_SPropValue(TALLOC_CTX *mem_ctx, 
+					     mapi_object_t *obj_folder,
+					     mapi_object_t *obj_message)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray;
+	struct ocpf_property	*pel;
+	struct ocpf_nproperty	*nel;
+	uint32_t		i;
+
+	/* sanity checks */
+	MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Step 1. Allocate SPropValue */
+	ocpf->cValues = 0;
+	ocpf->lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
+
+	/* Step2. build the list of named properties we want to set */
+	if (ocpf->nprops && ocpf->nprops->next) {
+		nameid = mapi_nameid_new(mem_ctx);
+		for (nel = ocpf->nprops; nel->next; nel = nel->next) {
+			if (nel->OOM) {
+				mapi_nameid_OOM_add(nameid, nel->OOM, nel->oleguid);
+			} else if (nel->mnid_id) {
+				mapi_nameid_custom_lid_add(nameid, nel->mnid_id, nel->propType, nel->oleguid);
+			} else if (nel->mnid_string) {
+				mapi_nameid_custom_string_add(nameid, nel->mnid_string, nel->propType, nel->oleguid);
+			}
+		}
+		
+		/* Step3. GetIDsFromNames and map property types */
+		SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+		retval = GetIDsFromNames(obj_folder, nameid->count, 
+					 nameid->nameid, 0, &SPropTagArray);
+		if (retval != MAPI_E_SUCCESS) {
+			MAPIFreeBuffer(SPropTagArray);
+			MAPIFreeBuffer(nameid);
+			return retval;
+		}
+		mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+		MAPIFreeBuffer(nameid);
+
+
+		/* Step4. Add named properties */
+		for (nel = ocpf->nprops, i = 0; SPropTagArray->aulPropTag[i] && nel->next; nel = nel->next, i++) {
+			if (SPropTagArray->aulPropTag[i]) {
+				if (((SPropTagArray->aulPropTag[i] & 0xFFFF) == PT_BINARY) && 
+				    (((struct Binary_r *)nel->value)->cb > MAX_READ_SIZE)) {
+					retval = ocpf_stream(mem_ctx, obj_message, SPropTagArray->aulPropTag[i], 
+							     (struct Binary_r *)nel->value);
+					MAPI_RETVAL_IF(retval, retval, NULL);
+				} else {
+					ocpf->lpProps = add_SPropValue(mem_ctx, ocpf->lpProps, &ocpf->cValues,
+								       SPropTagArray->aulPropTag[i], nel->value);
+				}
+			}
+		}
+		MAPIFreeBuffer(SPropTagArray);
+	}
+
+	/* Step5. Add Known properties */
+	if (ocpf->props && ocpf->props->next) {
+		for (pel = ocpf->props; pel->next; pel = pel->next) {
+			if (((pel->aulPropTag & 0xFFFF) == PT_BINARY) && 
+			    (((struct Binary_r *)pel->value)->cb > MAX_READ_SIZE)) {
+				retval = ocpf_stream(mem_ctx, obj_message, pel->aulPropTag, 
+						     (struct Binary_r *)pel->value);
+				MAPI_RETVAL_IF(retval, retval, NULL);
+			} else {
+				ocpf->lpProps = add_SPropValue(mem_ctx, ocpf->lpProps, &ocpf->cValues, 
+							       pel->aulPropTag, pel->value);
+			}
+		}
+	}
+	/* Step 6. Add message class */
+	if (ocpf->type) {
+		ocpf->lpProps = add_SPropValue(mem_ctx, ocpf->lpProps, &ocpf->cValues,
+					       PR_MESSAGE_CLASS, (const void *)ocpf->type);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the OCPF SPropValue array
+
+   This function is an accessor designed to return the SPropValue
+   structure created with ocpf_set_SPropValue.
+
+   \param cValues pointer on the number of SPropValue entries
+
+   \return NULL on error, otherwise returns an allocated lpProps pointer
+
+   \sa ocpf_set_SPropValue
+ */
+_PUBLIC_ struct SPropValue *ocpf_get_SPropValue(uint32_t *cValues)
+{
+	if (!ocpf || !ocpf->lpProps) return NULL;
+	if (!ocpf->cValues) return NULL;
+
+	*cValues = ocpf->cValues;
+
+	return ocpf->lpProps;
+}
+
+
+static enum MAPISTATUS ocpf_folder_lookup(TALLOC_CTX *mem_ctx,
+					  uint64_t sfid,
+					  mapi_object_t *obj_parent,
+					  mapi_id_t folder_id,
+					  mapi_object_t *obj_ret)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		i;
+	const uint64_t		*fid;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(obj_parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows)) {
+		for (i = 0; i < SRowSet.cRows; i++) {
+			fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID);
+			if (fid && *fid == sfid) {
+				retval = OpenFolder(&obj_folder, *fid, obj_ret);
+				mapi_object_release(&obj_htable);
+				mapi_object_release(&obj_folder);
+				return MAPI_E_SUCCESS;
+			} else {
+				retval = ocpf_folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret);
+				if (retval == MAPI_E_SUCCESS) {
+					mapi_object_release(&obj_htable);
+					mapi_object_release(&obj_folder);
+					return MAPI_E_SUCCESS;
+				}
+			}
+		}
+	}
+
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&obj_folder);
+
+	errno = MAPI_E_NOT_FOUND;
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Open OCPF folder
+
+   This function opens the folder associated with the ocpf folder
+   global context value.
+   
+   \param obj_store the store object
+   \param obj_folder the folder to open
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
+
+   \note Developers should 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: obj_store is undefined
+   - MAPI_E_NOT_FOUND: The specified folder could not be found or is
+     not yet supported.
+
+     \sa ocpf_init, ocpf_parse
+ */
+_PUBLIC_ enum MAPISTATUS ocpf_OpenFolder(mapi_object_t *obj_store,
+					 mapi_object_t *obj_folder)
+{
+	enum MAPISTATUS	retval;
+	mapi_id_t	id_folder;
+	mapi_id_t	id_tis;
+
+	/* Sanity checks */
+	MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL);
+
+	MAPI_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
+	MAPI_RETVAL_IF(!ocpf->folder, MAPI_E_NOT_FOUND, NULL);
+
+	/* */
+	mapi_object_init(obj_folder);
+	if (ocpf->folder >= 1 && ocpf->folder <= 26) {
+		retval = GetDefaultFolder(obj_store, &id_folder, ocpf->folder);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+
+		retval = OpenFolder(obj_store, id_folder, obj_folder);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+
+	} else {
+		retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+
+		retval = ocpf_folder_lookup((TALLOC_CTX *)ocpf->mem_ctx, ocpf->folder, 
+					    obj_store, id_tis, obj_folder);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+ * We set external recipients at the end of aRow
+ */
+static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, const char *username, enum ulRecipClass RecipClass)
+{
+	uint32_t		last;
+	struct SPropValue	SPropValue;
+
+	SRowSet->aRow = talloc_realloc(mem_ctx, SRowSet->aRow, struct SRow, SRowSet->cRows + 2);
+	last = SRowSet->cRows;
+	SRowSet->aRow[last].cValues = 0;
+	SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue);
+	
+	/* PR_OBJECT_TYPE */
+	SPropValue.ulPropTag = PR_OBJECT_TYPE;
+	SPropValue.value.l = MAPI_MAILUSER;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_TYPE */
+	SPropValue.ulPropTag = PR_DISPLAY_TYPE;
+	SPropValue.value.l = 0;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_GIVEN_NAME */
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_7BIT_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_SMTP_ADDRESS */
+	SPropValue.ulPropTag = PR_SMTP_ADDRESS;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_ADDRTYPE */
+	SPropValue.ulPropTag = PR_ADDRTYPE;
+	SPropValue.value.lpszA = "SMTP";
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	SetRecipientType(&(SRowSet->aRow[last]), RecipClass);
+
+	SRowSet->cRows += 1;
+	return true;
+}
+
+
+/**
+   \details Set the message recipients from ocpf context
+
+   This function sets the recipient (To, Cc, Bcc) from the ocpf
+   context and information stored.
+
+   \param mem_ctx the memory context to use for memory allocation
+   \param obj_message pointer to the message object we use for
+   internal MAPI operations
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR.
+
+   \sa ocpf
+ */
+_PUBLIC_ enum MAPISTATUS ocpf_set_Recipients(TALLOC_CTX *mem_ctx,
+					     mapi_object_t *obj_message)
+{
+	enum MAPISTATUS		retval;
+	struct ocpf_recipients	*element;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	char			**usernames = NULL;
+	int			*recipClass = NULL;
+	uint32_t		count;
+	uint32_t		counter;
+	uint32_t		i;
+
+	MAPI_RETVAL_IF(!ocpf, MAPI_E_NOT_INITIALIZED, NULL);
+	MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+	MAPI_RETVAL_IF(!ocpf->recipients->next, MAPI_E_NOT_FOUND, NULL);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	/* Step 1. Group recipients and run ResolveNames */
+	usernames = talloc_array(mem_ctx, char *, 2);
+	recipClass = talloc_array(mem_ctx, int, 2);
+	for (element = ocpf->recipients, count = 0; element->next; element = element->next, count ++) {
+		usernames = talloc_realloc(mem_ctx, usernames, char *, count + 2);
+		recipClass = talloc_realloc(mem_ctx, recipClass, int, count + 2);
+		usernames[count] = talloc_strdup((TALLOC_CTX *)usernames, element->name);
+		recipClass[count] = element->class;
+	}
+	usernames[count] = 0;
+
+	retval = ResolveNames(mapi_object_get_session(obj_message), (const char **)usernames, 
+			      SPropTagArray, &SRowSet, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, retval, usernames);
+
+	/* Step2. Associate resolved recipients to their respective recipClass */
+	if (!SRowSet) {
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+
+	count = 0;
+	counter = 0;
+	for (i = 0; usernames[i]; i++) {
+		if (flaglist->aulPropTag[count] == MAPI_UNRESOLVED) {
+			set_external_recipients(mem_ctx, SRowSet, usernames[i], recipClass[i]);
+		}
+		if (flaglist->aulPropTag[count] == MAPI_RESOLVED) {
+			SetRecipientType(&(SRowSet->aRow[counter]), recipClass[i]);
+			counter++;
+		}
+		count++;
+	}
+
+	/* Step3. Finish to build the ModifyRecipients SRowSet */
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, SRowSet, SPropValue);
+
+	/* Step4. Call ModifyRecipients */
+	retval = ModifyRecipients(obj_message, SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
+	MAPIFreeBuffer(usernames);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/libocpf/ocpf_write.c
===================================================================
--- trunk/openchange/libocpf/ocpf_write.c	                        (rev 0)
+++ trunk/openchange/libocpf/ocpf_write.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,623 @@
+/*
+   OpenChange OCPF (OpenChange Property File) implementation.
+
+   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/>.
+*/
+
+/**
+   \file ocpf_write.c
+
+   \brief public OCPF write API
+ */
+
+#include "libocpf/ocpf_private.h"
+#include <libocpf/ocpf.h>
+#include <libocpf/ocpf_api.h>
+#include <libmapi/defs_private.h>
+
+#include <time.h>
+
+struct ocpf_guid {
+	char		*name;
+	const char	*oleguid;
+};
+
+static const struct ocpf_guid ocpf_guid[] = {
+	{ "PSETID_Appointment",  "00062002-0000-0000-c000-000000000046" },
+	{ "PSETID_Task",	 "00062003-0000-0000-c000-000000000046" },
+	{ "PSETID_Address",    	 "00062004-0000-0000-c000-000000000046" },
+	{ "PSETID_Common",	 "00062008-0000-0000-c000-000000000046" },
+	{ "PSETID_Note",       	 "0006200e-0000-0000-c000-000000000046" },
+	{ "PSETID_Log",		 "0006200a-0000-0000-c000-000000000046" },
+	{ "PS_PUBLIC_STRINGS",   "00020329-0000-0000-c000-000000000046" },
+	{ "PS_INTERNET_HEADERS", "00020386-0000-0000-c000-000000000046" },
+	{ NULL,			 NULL					}
+};
+
+static char *ocpf_write_get_guid_name(const char *oleguid)
+{
+	uint32_t			i;
+	static int			idx = 0;
+	static struct ocpf_oleguid	*guid = NULL;
+	struct ocpf_oleguid		*element;
+	char				*name;
+
+	if (!oleguid) return NULL;
+
+	if (!guid) {
+		guid = talloc_zero(ocpf->mem_ctx, struct ocpf_oleguid);
+	}
+
+	for (i = 0; ocpf_guid[i].oleguid; i++) {
+		if (!strcmp(oleguid, ocpf_guid[i].oleguid)) {
+			return ocpf_guid[i].name;
+		}
+	}
+
+	for (element = guid; element->next; element = element->next) {
+		if (!strcmp(oleguid, element->guid)) {
+			return (char *)element->name;
+		}
+	}
+
+	element->name = talloc_asprintf(ocpf->mem_ctx, "PSETID_Custom_%d", idx);
+	element->guid = talloc_strdup(ocpf->mem_ctx, oleguid);
+	DLIST_ADD(guid, element);
+	name = talloc_strdup(ocpf->mem_ctx, element->name);
+	idx++;
+
+	return name;
+}
+
+struct ocpf_proptype {
+	uint16_t	type;
+	const char	*name;
+};
+
+static const struct ocpf_proptype ocpf_proptype[] = {
+	{ 0x2,		"PT_SHORT"	},
+	{ 0x3,		"PT_LONG"	},
+	{ 0x4,		"PT_FLOAT"	},
+	{ 0x5,		"PT_DOUBLE"	},
+	{ 0x6,		"PT_CURRENCY"	},
+	{ 0x7,		"PT_APPTIME"	},
+	{ 0xa,		"PT_ERROR"	},
+	{ 0xb,		"PT_BOOLEAN"	},
+	{ 0xd,		"PT_OBJECT"	},
+	{ 0x14,		"PT_I8"		},
+	{ 0x1e,		"PT_STRING8"	},
+	{ 0x1f,		"PT_UNICODE"	},
+	{ 0x40,		"PT_SYSTIME"	},
+	{ 0x48,		"PT_CLSID"	},
+	{ 0x102,	"PT_BINARY"	},
+	{ 0x1002,	"PT_MV_SHORT"	},
+	{ 0x1003,	"PT_MV_LONG"	},
+	{ 0x101e,	"PT_MV_STRING8"	},
+	{ 0x101f,	"PT_MV_UNICODE"	},
+	{ 0,		NULL}
+};
+
+static const char *ocpf_write_get_proptype_name(uint16_t type)
+{
+	uint32_t	i;
+
+	for (i = 0; ocpf_proptype[i].name; i++) {
+		if (type == ocpf_proptype[i].type) {
+			return ocpf_proptype[i].name;
+		}
+	}
+	return NULL;
+}
+
+static void ocpf_write_propname(FILE *fp, uint32_t ulPropTag)
+{
+	const char	*propname;
+	char		*line;
+	ssize_t		len;
+
+	propname = get_proptag_name(ulPropTag);
+	if (propname) {
+		line = talloc_asprintf(ocpf->mem_ctx, "\t%s = ", propname);
+	} else {
+		line = talloc_asprintf(ocpf->mem_ctx, "\t0x%x = ", ulPropTag);
+	}
+	len = fwrite(line, strlen(line), 1, fp);
+	talloc_free(line);
+}
+
+static char *ocpf_write_systime(const struct FILETIME *ft)
+{
+	char		*line;
+	char		tempTime[60];
+	NTTIME		nt;
+	time_t		t;
+	struct tm	*tm;
+
+	nt = ft->dwHighDateTime;
+	nt = (nt << 32) | ft->dwLowDateTime;
+	t = nt_time_to_unix(nt);
+	tm = localtime(&t);
+
+	strftime(tempTime, sizeof(tempTime)-1, "T%Y-%m-%d %H:%M:%S\n", tm);
+	line = talloc_strdup(ocpf->mem_ctx, tempTime);
+
+	return line;
+}
+
+static char *ocpf_write_binary(const struct Binary_r *bin)
+{
+	uint32_t	i;
+	char		*line;
+	
+	line = talloc_asprintf(ocpf->mem_ctx, "{");
+	for (i = 0; i < bin->cb; i++) {
+		line = talloc_asprintf_append(line, " 0x%.2x", bin->lpb[i]);
+	}
+	line = talloc_asprintf_append(line, " }\n");
+
+	return line;
+}
+
+static char *ocpf_write_escape_string(const char *value)
+{
+	char	*str = NULL;
+	char	*stmp = NULL;
+	int	value_len;
+	int	len = 0;
+	int	tmp = 0;
+
+	value_len = strlen(value);
+	tmp = strcspn(value, "\\\"");
+
+	if (tmp == value_len) {
+		str = talloc_strdup(ocpf->mem_ctx, value);
+		return str;
+	} else {
+		str = talloc_strndup(ocpf->mem_ctx, value, tmp);
+		str = talloc_asprintf_append_buffer(str, "\\\%c", value[tmp]);
+	}
+	len += tmp + 1;
+
+	while (len < value_len) {
+		tmp = strcspn(value + len, "\\\"");
+		
+		if ((tmp + len) == value_len) {
+			str = talloc_asprintf_append_buffer(str, "%s", value + len);
+			break;
+		} else {
+			stmp = talloc_strndup(ocpf->mem_ctx, value + len, tmp);
+			str = talloc_asprintf_append_buffer(str, "%s\\\%c", stmp, value[len + tmp]);
+			talloc_free(stmp);
+			len += tmp + 1;
+		}
+	}
+
+	return str;
+}
+
+char *ocpf_write_unescape_string(const char *value)
+{
+	char	*str = NULL;
+	char	*stmp = NULL;
+	int	value_len;
+	int	len = 0;
+	int	tmp = 0;
+
+	value_len = strlen(value);
+	tmp = strcspn(value, "\\");
+
+	if (tmp == value_len) {
+		str = talloc_strdup(ocpf->mem_ctx, value);
+		return str;
+	}
+	
+	str = talloc_strndup(ocpf->mem_ctx, value, tmp + 1);
+	if (value[tmp + 1] && value[tmp + 1] == '\\') {
+		len += tmp + 2;
+	} else {
+		len += tmp + 1;
+	}
+
+	while (len < value_len) {
+		tmp = strcspn(value + len, "\\");
+		
+		if ((tmp + len) == value_len) {
+			str = talloc_asprintf_append(str, "%s", value + len);
+			break;
+		}
+			
+		stmp = talloc_strndup(ocpf->mem_ctx, value + len, tmp + 1);
+		str = talloc_asprintf_append(str, "%s", stmp);
+		if (value[len + tmp + 1] && 
+		    (value[len + tmp + 1] == '\\' || value[len + tmp + 1] == '"')) {
+			len += tmp + 2;
+		} else {
+			len += tmp + 1;
+		}
+		talloc_free(stmp);
+	}
+
+	return str;
+}
+
+static char *ocpf_write_mv_string8(const struct StringArray_r *value)
+{
+	char		*str = NULL;
+	char		*tmp = NULL;
+	uint32_t	i;
+
+	str = talloc_asprintf(ocpf->mem_ctx, "{ ");
+	for (i = 0; i < value->cValues; i++) {
+		tmp = ocpf_write_escape_string((const char *)value->lppszA[i]);
+		if (i != value->cValues - 1) {
+			str = talloc_asprintf_append_buffer(str, "\"%s\", ", tmp);
+		} else {
+			str = talloc_asprintf_append_buffer(str, "\"%s\" }", tmp);
+		}
+		talloc_free(tmp);
+	}
+
+	return str;
+}
+
+static char *ocpf_write_property(bool *found, uint32_t ulPropTag, const void *value)
+{
+	char	*line = NULL;
+	char	*str = NULL;
+
+	switch (ulPropTag & 0xFFFF) {
+	case PT_STRING8:
+		str = ocpf_write_escape_string((const char *)value);
+		line = talloc_asprintf(ocpf->mem_ctx, "\"%s\"\n", str);
+		talloc_free(str);
+		*found = true;
+		break;
+	case PT_UNICODE:
+		str = ocpf_write_escape_string((const char *)value);
+		line = talloc_asprintf(ocpf->mem_ctx, "U\"%s\"\n", str);
+		talloc_free(str);
+		*found = true;
+		break;
+	case PT_SHORT:
+		line = talloc_asprintf(ocpf->mem_ctx, "S%d\n", *((const uint16_t *)value));
+		*found = true;
+		break;
+	case PT_LONG:
+		line = talloc_asprintf(ocpf->mem_ctx, "%d\n", *((const uint32_t *)value));			
+		*found = true;
+		break;
+	case PT_BOOLEAN:
+		line = talloc_asprintf(ocpf->mem_ctx, "B\"%s\"\n", (*((const uint8_t *)value) == true) ? "true" : "false");
+		*found = true;
+		break;
+	case PT_DOUBLE:
+		line = talloc_asprintf(ocpf->mem_ctx, "D0x%"PRIx64"\n", *(const uint64_t *)value);
+		*found = true;
+		break;
+	case PT_SYSTIME:
+		line = ocpf_write_systime((const struct FILETIME *)value);
+		*found = true;
+		break;
+	case PT_BINARY:
+		line = ocpf_write_binary((const struct Binary_r *)value);
+		*found = true;
+		break;
+	case PT_MV_STRING8:
+		line = ocpf_write_mv_string8((const struct StringArray_r *)value);
+		*found = true;
+		break;
+	}
+
+	return line;
+}
+
+
+static char *ocpf_write_recipients(enum ocpf_recipClass recipClass)
+{
+	struct ocpf_recipients	*element;
+	char			*line = NULL;
+	bool			found = false;
+
+	line = talloc_zero(ocpf->mem_ctx, char);
+	for (element = ocpf->recipients, found = false; element->next; element = element->next) {
+		if (found && element->class == recipClass) {
+			line = talloc_asprintf_append(line, ";");
+			found = false;
+		}
+		if (element->class == recipClass) {
+			line = talloc_asprintf_append(line, "\"%s\"", element->name);
+			found = true;
+		}
+	}
+	return line;
+}
+
+
+static int ocpf_write_add_recipients(enum ocpf_recipClass recipClass, const char *recipients)
+{
+	char		*tmp = NULL;
+	uint32_t	i = 0;
+
+	if (!recipients) return OCPF_ERROR;
+
+	if ((tmp = strtok((char *)recipients, ";")) == NULL) {
+		return OCPF_ERROR;
+	}
+
+	ocpf_recipient_add(recipClass, tmp);
+
+	for (i = 1; (tmp = strtok(NULL, ";")) != NULL; i++) {
+		ocpf_recipient_add(recipClass, tmp);
+	}
+
+	return OCPF_SUCCESS;
+}
+
+static bool ocpf_write_exclude_property(uint32_t ulPropTag)
+{
+	uint32_t	i;
+	uint32_t	propArray[] = { PR_DISPLAY_TO, 
+					PR_DISPLAY_CC, 
+					PR_DISPLAY_BCC, 
+					0};
+
+	for (i = 0; propArray[i]; i++) {
+		if (propArray[i] == ulPropTag) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+   \details Specify the OCPF file name to write
+ 
+   Specify the ocpf file to create
+
+   \param filename output filename
+   \param folder_id the folder 
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa ocpf_init
+ */
+_PUBLIC_ int ocpf_write_init(const char *filename, mapi_id_t folder_id)
+{
+	OCPF_RETVAL_IF(!filename, OCPF_WRITE_NOT_INITIALIZED, NULL);
+	OCPF_RETVAL_IF(!folder_id, OCPF_WRITE_NOT_INITIALIZED, NULL);
+	OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, OCPF_NOT_INITIALIZED, NULL);
+
+	ocpf->filename = talloc_strdup(ocpf->mem_ctx, filename);
+	ocpf->folder = folder_id;
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Create the OCPF structure required for the commit
+   operation
+
+   This function process properties and named properties from the
+   specified mapi_SPropValue_array and generates an OCPF structure
+   with all the attributes required to create an OCPF file in the
+   commit operation.
+
+   \param obj_message the message object
+   \param mapi_lpProps the array of mapi properties returned by
+   GetPropsAll
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa GetPropsAll, ocpf_write_commit
+ */
+_PUBLIC_ int ocpf_write_auto(mapi_object_t *obj_message,
+			     struct mapi_SPropValue_array *mapi_lpProps)
+{
+	enum MAPISTATUS		retval;
+	uint32_t		i;
+	uint16_t		propID;
+	struct SPropValue	lpProps;
+	const char		*type;
+	const char		*recipient;
+	char			*tmp_guid;
+	const char     		*guid;
+	struct MAPINAMEID	*nameid;
+	uint16_t		count;
+	struct ocpf_nprop	nprop;
+
+	OCPF_RETVAL_IF(!ocpf->filename, OCPF_WRITE_NOT_INITIALIZED, NULL);
+	OCPF_RETVAL_IF(!ocpf || !ocpf->mem_ctx, OCPF_NOT_INITIALIZED, NULL);
+	OCPF_RETVAL_IF(!mapi_lpProps, OCPF_INVALID_PROPARRAY, NULL);
+
+	/* store message type */
+	type = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_MESSAGE_CLASS);
+	ocpf_type_add(type);
+
+	/* store recipients */
+	recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_TO);
+	ocpf_write_add_recipients(OCPF_MAPI_TO, recipient);
+
+	recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_CC);
+	ocpf_write_add_recipients(OCPF_MAPI_CC, recipient);
+
+	recipient = (const char *) find_mapi_SPropValue_data(mapi_lpProps, PR_DISPLAY_BCC);
+	ocpf_write_add_recipients(OCPF_MAPI_BCC, recipient);
+
+	/* store properties and OLEGUID in OCPF context */
+	for (i = 0; i < mapi_lpProps->cValues; i++) {
+		propID = mapi_lpProps->lpProps[i].ulPropTag >> 16;
+		cast_SPropValue(&mapi_lpProps->lpProps[i], &lpProps);
+		
+		if (propID < 0x8000) {
+			if (ocpf_write_exclude_property(lpProps.ulPropTag) == false) {
+				/* HACK: replace PR_CONVERSATION_TOPIC with PR_SUBJECT */
+				if (lpProps.ulPropTag == PR_CONVERSATION_TOPIC) {
+					lpProps.ulPropTag = PR_SUBJECT;
+					ocpf_propvalue(lpProps.ulPropTag, lpProps.value, lpProps.ulPropTag & 0xFFFF, false);
+					cast_SPropValue(&mapi_lpProps->lpProps[i], &lpProps);
+				}
+				ocpf_propvalue(mapi_lpProps->lpProps[i].ulPropTag, 
+					       lpProps.value, mapi_lpProps->lpProps[i].ulPropTag & 0xFFFF, false);
+			}
+		} else {
+			nameid = talloc_zero(ocpf->mem_ctx, struct MAPINAMEID);
+			retval = GetNamesFromIDs(obj_message, ((lpProps.ulPropTag & 0xFFFF0000) | PT_NULL),
+						 &count, &nameid);
+			memset(&nprop, 0, sizeof (struct ocpf_nprop));
+			switch (nameid->ulKind) {
+			case MNID_ID:
+				nprop.mnid_id = nameid->kind.lid;
+				break;
+			case MNID_STRING:
+				nprop.mnid_string = talloc_strdup(ocpf->mem_ctx, nameid->kind.lpwstr.Name);
+				break;
+			}
+			nprop.propType = lpProps.ulPropTag & 0xFFFF;
+			tmp_guid = GUID_string(ocpf->mem_ctx, &nameid->lpguid);
+			nprop.guid = ocpf_write_get_guid_name(tmp_guid);
+
+			/* OLEGUID has to be inserted prior named properties */
+			if (ocpf_oleguid_check(nprop.guid, &guid) != OCPF_SUCCESS)
+				ocpf_oleguid_add(nprop.guid, tmp_guid);
+			
+			nprop.registered = false;
+			ocpf_nproperty_add(&nprop, lpProps.value, NULL, nprop.propType, false);
+
+			talloc_free(nameid);
+		}
+	}
+
+	return OCPF_SUCCESS;
+}
+
+
+/**
+   \details Write OCPF structure to OCPF file
+
+   This function dumps the OCPF structure content into the OCPF file
+   defined in ocpf_write_init.
+
+   \return OCPF_SUCCESS on success, otherwise OCPF_ERROR
+
+   \sa ocpf_write_init, ocpf_write_auto
+ */
+_PUBLIC_ int ocpf_write_commit(void)
+{
+	FILE			*fp;
+	struct ocpf_property	*element;
+	struct ocpf_nproperty	*nelement;
+	struct ocpf_oleguid	*nguid;
+	char			*line;
+	bool			found = false;
+	char			*definition = NULL;
+	ssize_t			len;
+
+	fp = fopen(ocpf->filename, "w+");
+	OCPF_RETVAL_IF(!fp, OCPF_INVALID_FILEHANDLE, NULL);
+
+	/* message type */
+	line = talloc_asprintf(ocpf->mem_ctx, "TYPE   \"%s\"\n\n", ocpf->type);
+	len = fwrite(line, strlen(line), 1, fp);
+	talloc_free(line);
+
+	/* folder id */
+	line = talloc_asprintf(ocpf->mem_ctx, "FOLDER D0x%"PRIx64"\n\n", ocpf->folder);
+	len = fwrite(line, strlen(line), 1, fp);
+	talloc_free(line);
+
+	/* OLEGUID */
+	for (nguid = ocpf->oleguid; nguid->next; nguid = nguid->next) {
+		line = talloc_asprintf(ocpf->mem_ctx, "OLEGUID %-25s \"%s\"\n", nguid->name, nguid->guid);
+		len = fwrite(line, strlen(line), 1, fp);
+		talloc_free(line);
+	}
+	len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+
+	/* RECIPIENT TO */
+	line = ocpf_write_recipients(OCPF_MAPI_TO);
+	if (line && strlen(line)) {
+		len = fwrite(OCPF_RECIPIENT_TO, strlen(OCPF_RECIPIENT_TO), 1, fp);
+		len = fwrite(line, strlen(line), 1, fp);
+		len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+		talloc_free(line);
+	}
+
+	/* RECIPIENT CC */
+	line = ocpf_write_recipients(OCPF_MAPI_CC);
+	if (line && strlen(line)) {
+		len = fwrite(OCPF_RECIPIENT_CC, strlen(OCPF_RECIPIENT_CC), 1, fp);
+		len = fwrite(line, strlen(line), 1, fp);
+		len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+		talloc_free(line);
+	}
+
+	/* RECIPIENT BCC */
+	line = ocpf_write_recipients(OCPF_MAPI_BCC);
+	if (line && strlen(line)) {
+		len = fwrite(OCPF_RECIPIENT_BCC, strlen(OCPF_RECIPIENT_BCC), 1, fp);
+		len = fwrite(line, strlen(line), 1, fp);
+		len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+		talloc_free(line);
+	}
+
+	len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+
+	/* known properties */
+	len = fwrite(OCPF_PROPERTY_BEGIN, strlen(OCPF_PROPERTY_BEGIN), 1, fp);
+	for (element = ocpf->props; element->next; element = element->next) {
+		line = ocpf_write_property(&found, element->aulPropTag, element->value);
+		if (found == true) {
+			ocpf_write_propname(fp, element->aulPropTag);
+			len = fwrite(line, strlen(line), 1, fp);
+			talloc_free(line);
+			found = false;
+		}
+	}
+	len = fwrite(OCPF_END, strlen(OCPF_END), 1, fp);
+	len = fwrite(OCPF_NEWLINE, strlen(OCPF_NEWLINE), 1, fp);
+
+	/* named properties */
+	len = fwrite(OCPF_NPROPERTY_BEGIN, strlen(OCPF_NPROPERTY_BEGIN), 1, fp);
+	for (nelement = ocpf->nprops; nelement->next; nelement = nelement->next) {
+		line = ocpf_write_property(&found, nelement->propType, nelement->value);
+		if (found == true) {
+			if (nelement->mnid_id) {
+				definition = talloc_asprintf(ocpf->mem_ctx, "\tMNID_ID:0x%.4x:%s:%s = ",
+							     nelement->mnid_id,
+							     ocpf_write_get_proptype_name(nelement->propType),
+							     ocpf_write_get_guid_name(nelement->oleguid));
+			} else if (nelement->mnid_string) {
+				definition = talloc_asprintf(ocpf->mem_ctx, "\tMNID_STRING:\"%s\":%s:%s = ",
+							     nelement->mnid_string,
+							     ocpf_write_get_proptype_name(nelement->propType),
+							     ocpf_write_get_guid_name(nelement->oleguid));
+			}
+			
+			len = fwrite(definition, strlen(definition), 1, fp);
+			len = fwrite(line, strlen(line), 1, fp);
+
+			talloc_free(definition);
+			talloc_free(line);
+			found = false;
+		}
+	}
+	len = fwrite(OCPF_END, strlen(OCPF_END), 1, fp);
+
+	fclose(fp);
+	return OCPF_SUCCESS;
+}

Added: trunk/openchange/libocpf.pc.in
===================================================================
--- trunk/openchange/libocpf.pc.in	                        (rev 0)
+++ trunk/openchange/libocpf.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: OpenChange Property File
+Description: OCPF file format support
+Version: @PACKAGE_VERSION@
+Libs: @LIBS@ -locpf
+Cflags: @CFLAGS@
+Requires: libmapi

Added: trunk/openchange/mapiproxy/Doxyfile.in
===================================================================
--- trunk/openchange/mapiproxy/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/mapiproxy/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1498 @@
+# Doxyfile 1.5.7.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MAPIProxy
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, 
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen to replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penality. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will rougly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by 
+# doxygen. The layout file controls the global structure of the generated output files 
+# in an output format independent way. The create the layout file that represents 
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a 
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name 
+# of the layout file.
+
+LAYOUT_FILE            = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = mapiproxy \
+                         mapiproxy/documentation \
+                         mapiproxy/modules
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.h \
+                         *.c \
+                         *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c \
+                         *_private.h \
+                         ocpf_api.*
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed 							\
+			-e '20,40s/.*\<libmapi\/proto_private.h\>//'		\
+			-e '20,40s/.*\<gen_ndr\/ndr_exchange.h\>//'		\
+			-e '20,40s/.*\<param.h\>//'				\
+			-e '20,40s/.*\<errno.h\>//'				\
+			-e '20,40s/.*\<core\/error.h\>//'			\
+			-e '20,40s/.*\<credentials.h\>//'			\
+			-e '20,40s/.*\<ldb.h\>//'				\
+			-e '20,40s/.*\<ldb_errors.h\>//'			\
+			-e '20,40s/.*\<libmapi\/dlinklist.h\>//'		\
+			-e '20,40s/.*\<libmapi\/defs_private.h\>//'		\
+			-e '20,40s/.*\<libmapi\/mapi_nameid.h\>//'		\
+			-e '20,40s/.*\<libmapi\/mapi_nameid_private.h\>//'	\
+			-e '20,40s/.*\<libocpf\/proto_private.h\>//'		\
+			-e '20,40s/.*\<libocpf\/ocpf_api.h\>//'			\
+			-e '20,40s/.*\<libocpf\/ocpf.tab.h\>//'			\
+			-e '20,40s/.*\<libgen.h\>//'				\
+			-e '20,40s/.*\<time.h\>//'				\
+			-e '20,40s/.*\<sys\/*\>//'				\
+			-e '20,40s/_PUBLIC_//'"
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/mapiproxy
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER 
+# are set, an additional index file will be generated that can be used as input for 
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated 
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file .
+
+QHG_LOCATION           = 
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature. Other possible values 
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# By default doxygen will write a font called FreeSans.ttf to the output 
+# directory and reference it in all dot files that doxygen generates. This 
+# font does not include all possible unicode characters however, so when you need 
+# these (or just want a differently looking font) you can specify the font name 
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font, 
+# which can be done by putting it in a standard location or by setting the 
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory 
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the 
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a 
+# different font using DOT_FONTNAME you can set the path where dot 
+# can find it using this tag.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,676 @@
+/*
+   MAPI Proxy
+
+   This proxy is based on dcesrv_remote.c code from Stefan Metzemacher
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008-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 "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+#include <libmapi/dlinklist.h>
+#include <libmapi/defs_private.h>
+#include <util/debug.h>
+
+/**
+   \file dcesrv_mapiproxy.c
+
+   \brief mapiproxy main file
+ */
+
+
+static NTSTATUS mapiproxy_op_reply(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	DEBUG(5, ("mapiproxy::mapiproxy_op_reply\n"));
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS mapiproxy_op_bind_proxy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+{
+	NTSTATUS				status;
+	const struct ndr_interface_table	*table;
+	struct dcesrv_mapiproxy_private		*private;
+	const char				*binding;
+	const char				*user;
+	const char				*pass;
+	const char				*domain;
+	struct cli_credentials			*credentials;
+	bool					machine_account;
+
+	/* Retrieve parametric options */
+	binding = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "binding");
+	machine_account = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "use_machine_account", false);
+
+	private = dce_call->context->private;
+
+	if (!binding) {
+		DEBUG(0, ("You must specify a DCE/RPC binding string\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	user = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "username");
+	pass = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "password");
+	domain = lp_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "domain");
+
+	table = ndr_table_by_uuid(&iface->syntax_id.uuid);
+	if (!table) {
+		dce_call->fault_code = DCERPC_FAULT_UNK_IF;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	if (user && pass) {
+		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using specified account\n"));
+		credentials = cli_credentials_init(private);
+		if (!credentials) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx);
+		cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
+		if (domain) {
+			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
+		}
+		cli_credentials_set_password(credentials, pass, CRED_SPECIFIED);
+	} else if (machine_account) {
+		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using machine account\n"));
+		credentials = cli_credentials_init(private);
+		if (!credentials) {
+			return NT_STATUS_NO_MEMORY;
+		}
+		cli_credentials_set_conf(credentials, dce_call->conn->dce_ctx->lp_ctx);
+		if (domain) {
+			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
+		}
+		status = cli_credentials_set_machine_account(credentials, dce_call->conn->dce_ctx->lp_ctx);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	} else if (dce_call->conn->auth_state.session_info->credentials) {
+		DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: Using delegated credentials\n"));
+		credentials = dce_call->conn->auth_state.session_info->credentials;
+	} else {
+		DEBUG(1, ("dcerpc_mapiproxy: RPC proxy: You must supply binding, user and password or have delegated credentials\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (((dce_call->pkt.ptype == DCERPC_PKT_BIND) && dce_call->pkt.u.bind.assoc_group_id) ||
+	    ((dce_call->pkt.ptype == DCERPC_PKT_ALTER) && dce_call->pkt.u.alter.assoc_group_id)) {
+		struct dcerpc_binding		*b;
+		struct composite_context	*pipe_conn_req;
+
+		/* parse binding string to the structure */
+		status = dcerpc_parse_binding(dce_call->context, binding, &b);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("Failed to parse dcerpc binding '%s'\n", binding));
+			return status;
+		}
+		
+		DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b)));
+		
+		switch (dce_call->pkt.ptype) {
+		case DCERPC_PKT_BIND:
+			b->assoc_group_id = dce_call->pkt.u.bind.assoc_group_id;
+			break;
+		case DCERPC_PKT_ALTER:
+			b->assoc_group_id = dce_call->pkt.u.alter.assoc_group_id;
+			break;
+		default:
+			break;
+		}
+
+		pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
+							   credentials, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
+		status = dcerpc_pipe_connect_b_recv(pipe_conn_req, dce_call->context, &(private->c_pipe));
+		
+		talloc_free(credentials);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
+ 		
+	} else {
+		status = dcerpc_pipe_connect(dce_call->context,
+					     &(private->c_pipe), binding, table,
+					     credentials, dce_call->event_ctx,
+					     dce_call->conn->dce_ctx->lp_ctx);
+
+		talloc_free(credentials);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		dce_call->context->assoc_group_id = private->c_pipe->assoc_group_id;
+	}
+
+	DEBUG(5, ("dcerpc_mapiproxy: RPC proxy: CONNECTED\n"));
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details This function is called when the client binds to one of
+   the interfaces mapiproxy handles.
+
+   \param dce_call pointer to the session context
+   \param iface pointer to the dcesrv interface structure with
+   function hooks
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+static NTSTATUS mapiproxy_op_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
+{
+	struct dcesrv_mapiproxy_private		*private;
+	bool					server_mode;
+
+	DEBUG(5, ("mapiproxy::mapiproxy_op_bind: [session = 0x%x] [session server id = 0x%"PRIx64" 0x%x 0x%x]\n", dce_call->context->context_id,
+		  dce_call->conn->server_id.id, dce_call->conn->server_id.id2, dce_call->conn->server_id.node));
+
+	/* Retrieve server mode parametric option */
+	server_mode = lp_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "server", false);
+
+	/* Initialize private structure */
+	private = talloc(dce_call->context, struct dcesrv_mapiproxy_private);
+	if (!private) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	
+	private->c_pipe = NULL;
+	private->exchname = NULL;
+	private->server_mode = server_mode;
+	dce_call->context->private = private;
+
+	if (server_mode == false) {
+		return mapiproxy_op_bind_proxy(dce_call, iface);
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Called when the client disconnects from one of the
+   endpoints managed by mapiproxy.
+
+   \param context pointer to the connection context
+   \param iface pointer to the dcesrv interface structure with
+   function hooks
+ */
+static void mapiproxy_op_unbind(struct dcesrv_connection_context *context, const struct dcesrv_interface *iface)
+{
+	struct dcesrv_mapiproxy_private	*private = (struct dcesrv_mapiproxy_private *) context->private;
+
+	DEBUG(5, ("mapiproxy::mapiproxy_op_unbind\n"));
+
+	mapiproxy_module_unbind(context->conn->server_id, context->context_id);
+	mapiproxy_server_unbind(context->conn->server_id, context->context_id);
+
+	if (private) {
+		talloc_free(private->c_pipe);
+		talloc_free(private);
+	}
+
+	talloc_free(context);
+
+	return;
+}
+
+
+/**
+   \details This is the function called when mapiproxy receives a
+   request. The request has already been extracted and its information
+   filled into structures
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param pull pointer on pointer to the ndr_pull structure
+   \param r generic pointer on pointer to the pulled ndr content
+
+   \return NT_STATUS_OK on success, other NTSTATUS error
+ */
+static NTSTATUS mapiproxy_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull, void **r)
+{
+	enum ndr_err_code			ndr_err;
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+
+	DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_pull\n"));
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	dce_call->fault_code = 0;
+
+	if (opnum >= table->num_calls) {
+		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	*r = talloc_size(mem_ctx, table->calls[opnum].struct_size);
+	if (!*r) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/* directly alter the pull struct before it got pulled from ndr */
+	mapiproxy_module_ndr_pull(dce_call, mem_ctx, pull);
+
+	ndr_err = table->calls[opnum].ndr_pull(pull, NDR_IN, *r);
+
+	mapiproxy_module_pull(dce_call, mem_ctx, *r);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0, ("mapiproxy: mapiproxy_ndr_pull: ERROR\n"));
+		dcerpc_log_packet(dce_call->conn->packet_log_dir, table, opnum, NDR_IN, 
+				  &dce_call->pkt.u.request.stub_and_verifier);
+		dce_call->fault_code = DCERPC_FAULT_NDR;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details This is the function called when mapiproxy receive a
+   response. The response has already been extracted and its
+   information filled into structures
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param push pointer to the ndr_push structure
+   \param r generic pointer to the data pushed
+
+   \return NT_STATUS_OK on success, otherwise a NTSTATUS error
+ */
+static NTSTATUS mapiproxy_op_ndr_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_push *push, const void *r)
+{
+	struct dcesrv_mapiproxy_private		*private;
+	enum ndr_err_code			ndr_err;
+	const struct ndr_interface_table	*table;
+	const struct ndr_interface_call		*call;
+	uint16_t				opnum;
+	const char				*name;
+
+	DEBUG(5, ("mapiproxy::mapiproxy_op_ndr_push\n"));
+
+	private = dce_call->context->private;
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	name = table->calls[opnum].name;
+	call = &table->calls[opnum];
+
+	dce_call->fault_code = 0;
+
+	if (private->server_mode == false) {
+		/* NspiGetProps binding strings replacement */
+		if ((mapiproxy_server_loaded(NDR_EXCHANGE_NSP_NAME) == false) &&
+		    table->name && !strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) {
+			switch (opnum) {
+			case NDR_NSPIGETPROPS:
+				mapiproxy_NspiGetProps(dce_call, (struct NspiGetProps *)r);
+				break;
+			case NDR_NSPIQUERYROWS:
+				mapiproxy_NspiQueryRows(dce_call, (struct NspiQueryRows *)r);
+				break;
+			default:
+				break;
+			}
+		}
+
+		/* RfrGetNewDSA FQDN replacement */
+		if ((mapiproxy_server_loaded(NDR_EXCHANGE_DS_RFR_NAME) == false) &&
+		    table->name && !strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) {
+			switch (opnum) {
+			case NDR_RFRGETNEWDSA:
+				mapiproxy_RfrGetNewDSA(dce_call, (struct RfrGetNewDSA *)r);
+				break;
+			default:
+				DEBUG(0, ("exchange_ds_rfr: OTHER DS-RFR CALL DETECTED!\n"));
+				break;
+			}
+		}
+	}
+
+	mapiproxy_module_push(dce_call, mem_ctx, (void *)r);
+
+	ndr_err = table->calls[opnum].ndr_push(push, NDR_OUT, r);
+
+	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+		DEBUG(0, ("mapiproxy: mapiproxy_ndr_push: ERROR\n"));
+		dce_call->fault_code = DCERPC_FAULT_NDR;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details This function is called after the pull but before the
+   push. Moreover it is called before the request is forward to the
+   remote endpoint.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r generic pointer to the call mapped data
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+static NTSTATUS mapiproxy_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	struct dcesrv_mapiproxy_private		*private;
+	struct ndr_push				*push;
+	enum ndr_err_code			ndr_err;
+	struct mapiproxy			mapiproxy;
+	const struct ndr_interface_table	*table;
+	const struct ndr_interface_call		*call;
+	uint16_t				opnum;
+	const char				*name;
+	NTSTATUS				status;
+
+	private = dce_call->context->private;
+	table = dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	name = table->calls[opnum].name;
+	call = &table->calls[opnum];
+
+	mapiproxy.norelay = false;
+	mapiproxy.ahead = false;
+
+	if (!private) {
+		dce_call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	DEBUG(5, ("mapiproxy::mapiproxy_op_dispatch: %s(0x%x): %zd bytes\n",
+		  table->calls[opnum].name, opnum, table->calls[opnum].struct_size));
+
+	if (private->server_mode == false) {
+		if (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) {
+			ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r);
+		}
+
+		private->c_pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
+	}
+
+	if ((private->server_mode == true) || (mapiproxy_server_loaded(NDR_EXCHANGE_NSP_NAME) == true)) {
+		ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r);
+		status = mapiproxy_server_dispatch(dce_call, mem_ctx, r, &mapiproxy);
+		ndr_print_function_debug(call->ndr_print, name, NDR_OUT | NDR_SET_VALUES, r);
+		if (!NT_STATUS_IS_OK(status)) {
+			return NT_STATUS_NET_WRITE_FAULT;
+		}
+	} else {
+		if (table->name && !strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) {
+			if (opnum == NDR_NSPIDNTOMID) {
+				mapiproxy_NspiDNToMId(dce_call, (struct NspiDNToMId *)r);
+			}
+		}
+	}
+
+	if (private->server_mode == false) {
+	ahead:
+		if (mapiproxy.ahead == true) {
+			push = ndr_push_init_ctx(dce_call, 
+						 lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx));
+			NT_STATUS_HAVE_NO_MEMORY(push);
+			ndr_err = call->ndr_push(push, NDR_OUT, r);
+			if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+				DEBUG(0, ("mapiproxy: mapiproxy_op_dispatch:push: ERROR\n"));
+				dce_call->fault_code = DCERPC_FAULT_NDR;
+				return NT_STATUS_NET_WRITE_FAULT;
+			}
+		}
+		
+		status = mapiproxy_module_dispatch(dce_call, mem_ctx, r, &mapiproxy);
+		if (!NT_STATUS_IS_OK(status)) {
+			private->c_pipe->last_fault_code = dce_call->fault_code;
+			return NT_STATUS_NET_WRITE_FAULT;
+		}
+		
+		private->c_pipe->last_fault_code = 0;
+		if (mapiproxy.norelay == false) {
+			status = dcerpc_ndr_request(private->c_pipe, NULL, table, opnum, mem_ctx, r);
+		}
+		
+		dce_call->fault_code = private->c_pipe->last_fault_code;
+		if (dce_call->fault_code != 0 || !NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("mapiproxy: call[%s] failed with %s! (status = %s)\n", name, 
+				  dcerpc_errstr(mem_ctx, dce_call->fault_code), nt_errstr(status)));
+			return NT_STATUS_NET_WRITE_FAULT;
+		}
+		
+		if ((dce_call->fault_code == 0) && 
+		    (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_OUT) && mapiproxy.norelay == false) {
+			ndr_print_function_debug(call->ndr_print, name, NDR_OUT | NDR_SET_VALUES, r);
+		}
+		
+		if (mapiproxy.ahead == true) goto ahead;
+	}
+	
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Register an endpoint
+
+   \param dce_ctx pointer to the dcerpc context
+   \param iface pointer to the dcesrv interface with function hooks
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+static NTSTATUS mapiproxy_register_one_iface(struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface)
+{
+	const struct ndr_interface_table	*table = iface->private;
+	int					i;
+
+	for (i = 0; i < table->endpoints->count; i++) {
+		NTSTATUS	ret;
+		const char	*name = table->endpoints->names[i];
+
+		ret = dcesrv_interface_register(dce_ctx, name, iface, NULL);
+		if (!NT_STATUS_IS_OK(ret)) {
+			DEBUG(1,("mapiproxy_op_init_server: failed to register endpoint '%s'\n", name));
+			return ret;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initializes the server and register emsmdb,nspi and rfr
+   interfaces
+
+   \param dce_ctx pointer to the dcesrv context
+   \param ep_server pointer to the endpoint server list
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+static NTSTATUS mapiproxy_op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
+{
+	NTSTATUS		ret;
+	struct dcesrv_interface	iface;
+	char     		**ifaces;
+	uint32_t		i;
+	static bool		initialized = false;
+
+	if (initialized == true) return NT_STATUS_OK;
+
+	/* Register mapiproxy modules */
+	ret = mapiproxy_module_init(dce_ctx);
+	NT_STATUS_NOT_OK_RETURN(ret);
+
+	/* Register mapiproxy servers */
+	ret = mapiproxy_server_init(dce_ctx);
+	NT_STATUS_NOT_OK_RETURN(ret);
+
+	ifaces = str_list_make(dce_ctx, lp_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "interfaces"), NULL);
+
+	for (i = 0; ifaces[i]; i++) {
+		/* Register the interface */
+		if (!ep_server->interface_by_name(&iface, ifaces[i])) {
+			DEBUG(0, ("mapiproxy_op_init_server: failed to find interface '%s'\n", ifaces[i]));
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+
+		ret = mapiproxy_register_one_iface(dce_ctx, &iface);
+		if (!NT_STATUS_IS_OK(ret)) {
+			DEBUG(0, ("mapiproxy_op_init_server: failed to register interface '%s'\n", ifaces[i]));
+			return ret;
+		}
+	}
+
+	initialized = true;
+	return NT_STATUS_OK;
+}
+
+
+static bool mapiproxy_fill_interface(struct dcesrv_interface *iface, const struct ndr_interface_table *tbl)
+{
+	iface->name = tbl->name;
+	iface->syntax_id = tbl->syntax_id;
+	
+	iface->bind = mapiproxy_op_bind;
+	iface->unbind = mapiproxy_op_unbind;
+	
+	iface->ndr_pull = mapiproxy_op_ndr_pull;
+	iface->dispatch = mapiproxy_op_dispatch;
+	iface->reply = mapiproxy_op_reply;
+	iface->ndr_push = mapiproxy_op_ndr_push;
+
+	iface->private = tbl;
+
+	return true;
+}
+
+
+static bool mapiproxy_op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version)
+{
+	const struct ndr_interface_list	*l;
+
+	for (l = ndr_table_list(); l; l = l->next) {
+		if (l->table->syntax_id.if_version == if_version &&
+		    GUID_equal(&l->table->syntax_id.uuid, uuid) == 0) {
+			return mapiproxy_fill_interface(iface, l->table);
+		}
+	}
+
+	return false;
+}
+
+
+static bool mapiproxy_op_interface_by_name(struct dcesrv_interface *iface, const char *name)
+{
+	const struct ndr_interface_table	*tbl;
+
+	tbl = ndr_table_by_name(name);
+
+	if (tbl) {
+		return mapiproxy_fill_interface(iface, tbl);
+	}
+
+	return false;
+}
+
+
+/**
+   \details register the mapiproxy endpoint server.
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS dcerpc_server_mapiproxy_init(void)
+{
+	NTSTATUS			ret;
+	struct dcesrv_endpoint_server	ep_server;
+
+	ZERO_STRUCT(ep_server);
+
+	/* Fill in our name */
+	ep_server.name = "mapiproxy";
+
+	/* Fill in all the operations */
+	ep_server.init_server = mapiproxy_op_init_server;
+
+	ep_server.interface_by_uuid = mapiproxy_op_interface_by_uuid;
+	ep_server.interface_by_name = mapiproxy_op_interface_by_name;
+
+	/* Register ourselves with the DCE/RPC subsystem */
+	ret = dcerpc_register_ep_server(&ep_server);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register 'mapiproxy' endpoint server!"));
+		return ret;
+	}
+
+	/* Full DCE/RPC interface table needed */
+	ndr_table_init();
+	
+	return ret;
+}
+
+/**
+   \details Register mapiproxy dynamic shared object modules
+
+   This function registers mapiproxy modules located
+ */
+
+/**
+   \details Entry point of mapiproxy dynamic shared object.
+
+   This function first registers exchange endpoints and ndr tables,
+   then attempts to register the mapiproxy interface.
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL;
+ */
+NTSTATUS samba_init_module(void)
+{
+	NTSTATUS status;
+
+	/* Step1. Register Exchange endpoints */
+	status = dcerpc_server_exchange_emsmdb_init();
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = dcerpc_server_exchange_nsp_init();
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = dcerpc_server_exchange_ds_rfr_init();
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	/* Step2. Register Exchange ndr tables */
+	status = ndr_table_register(&ndr_table_exchange_emsmdb);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = ndr_table_register(&ndr_table_exchange_nsp);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	status = ndr_table_register(&ndr_table_exchange_ds_rfr);
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	/* Step3. Finally register mapiproxy endpoint */
+	status = dcerpc_server_mapiproxy_init();
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	return NT_STATUS_OK;
+}
+
+/* include server boiler template */
+#include <gen_ndr/ndr_exchange_s.c>

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy.h
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,69 @@
+/*
+   MAPI Proxy
+
+   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	__DCESRV_MAPIPROXY_H__
+#define	__DCESRV_MAPIPROXY_H__
+
+#ifndef	_GNU_SOURCE
+#define	_GNU_SOURCE 1
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <talloc.h>
+#include <dcerpc.h>
+#include <samba/session.h>
+
+#include <dcerpc_server.h>
+#include <util.h>
+#include <param.h>
+#include <credentials.h>
+
+#include <gen_ndr/exchange.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <mapiproxy/libmapiproxy/libmapiproxy.h>
+
+struct dcesrv_mapiproxy_private {
+	struct dcerpc_pipe	*c_pipe;
+	char			*exchname;
+	bool			server_mode;
+};
+
+enum exchange_handle {
+	EXCHANGE_HANDLE_NSP,
+	EXCHANGE_HANDLE_EMSMDB,
+	EXCHANGE_HANDLE_DS_RFR
+};
+
+/* Forward declarations */
+struct composite_context;
+
+#define MAXHOSTNAMELEN	255
+#define	SERVERNAME      "/cn=Servers/cn="
+
+#endif	/* !__DCESRV_MAPIPROXY_H__ */

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,208 @@
+/*
+   MAPI Proxy - NSPI
+
+   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 "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+
+/**
+   \file dcesrv_mapiproxy_nspi.c
+
+   \brief NSPI hook functions
+ */
+
+/**
+   \details Retrieve the servername from a DN string
+ 
+   \param dn the DN string
+
+   \return a talloc'd server name
+ */
+static char *x500_get_servername(const char *dn)
+{
+	char *pdn;
+	char *servername;
+
+	if (!dn) {
+		return NULL;
+	}
+
+	pdn = strcasestr(dn, SERVERNAME);
+	if (pdn == NULL) return NULL;
+
+	pdn += strlen(SERVERNAME);
+	servername = strsep(&pdn, "/");
+
+	return (talloc_strdup(NULL, servername));
+}
+
+
+/**
+   \details This function replaces network address from the binding
+   strings returned by Exchange for the PR_EMS_AB_NETWORK_ADDRESS
+   property and limit the binding strings scope to ncacn_ip_tcp.
+
+   \param dce_call pointer to the session context
+   \param r pointer to the NspiGetProps structure
+
+   \return true on success, otherwise false
+ */
+bool mapiproxy_NspiGetProps(struct dcesrv_call_state *dce_call, struct NspiGetProps *r)
+{
+	uint32_t		i;
+	uint32_t		propID = -1;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SRow		*SRow;
+	struct StringArray_r	*slpstr;
+	struct SPropValue	*lpProp;
+
+	/* Sanity checks */
+	if (!r->out.ppRows) return false;
+	if (!(*r->out.ppRows)->cValues) return false;
+
+	/* Step 1. Find PR_EMS_AB_NETWORK_ADDRESS index */
+	propID = -1;
+	SPropTagArray = r->in.pPropTags;
+	for (i = 0; i < SPropTagArray->cValues; i++) {
+		if (SPropTagArray->aulPropTag[i] == PR_EMS_AB_NETWORK_ADDRESS) {
+			propID = i;
+			break;
+		}
+	}
+	if (propID == -1) return false;
+
+	/* Step 2. Retrieve the SLPSTRArray */
+	SRow = *r->out.ppRows;
+	lpProp = &SRow->lpProps[propID];
+
+	if (!lpProp) return false;
+	if (lpProp->ulPropTag != PR_EMS_AB_NETWORK_ADDRESS) return false;
+
+	slpstr = &(lpProp->value.MVszA);
+
+	/* Step 3. Modify Exchange binding strings and only return ncacn_ip_tcp */
+	slpstr->cValues = 1;
+	slpstr->lppszA[0] = talloc_asprintf(dce_call, "ncacn_ip_tcp:%s.%s", 
+					    lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 
+					    lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+	strlower_m((char *)slpstr->lppszA[0]);
+
+	return true;
+}
+
+
+/**
+   \details This function replaces the Exchange server name with
+   mapiproxy netbios name for the PR_EMS_AB_HOME_MDB property and
+   saves the original name in a global variable for further usage -
+   such as mapiproxy_NspiDNToMId.
+
+   \param dce_call pointer to the session context
+   \param r pointer to the NspiQueryRows structure
+
+   \sa mapiproxy_NspiDNToMId
+*/
+bool mapiproxy_NspiQueryRows(struct dcesrv_call_state *dce_call, struct NspiQueryRows *r)
+{
+	struct dcesrv_mapiproxy_private	*private;
+	uint32_t		i;
+	uint32_t		propID = -1;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SRowSet		*SRowSet;
+	struct SPropValue	*lpProp;
+	char			*lpszA;
+	char			*exchname;
+
+	private = dce_call->context->private;
+
+	/* Sanity checks */
+	if (!r->out.ppRows) return false;
+	if (!(*r->out.ppRows)->cRows) return false;
+	if (!r->in.pPropTags) return false;
+
+	/* Step 1. Find PR_EMS_AB_HOME_MDB index */
+	propID = -1;
+	SPropTagArray = r->in.pPropTags;
+	for (i = 0; i < SPropTagArray->cValues; i++) {
+		if (SPropTagArray->aulPropTag[i] == PR_EMS_AB_HOME_MDB) {
+			propID = i;
+			break;
+		}
+	}
+	if (propID == -1) return false;
+
+	/* Retrieve the lpszA */
+	SRowSet = *r->out.ppRows;
+	lpProp = &(SRowSet->aRow->lpProps[propID]);
+
+	if (!lpProp) return false;
+	if (lpProp->ulPropTag != PR_EMS_AB_HOME_MDB) return false;
+
+	if (private->exchname) {
+		if (strstr(lpProp->value.lpszA, private->exchname)) {
+			lpProp->value.lpszA = string_sub_talloc((TALLOC_CTX *) dce_call, lpProp->value.lpszA, private->exchname, 
+								lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));	
+		}
+	} else {
+		lpszA = talloc_strdup(dce_call, lpProp->value.lpszA);
+		if ((exchname = x500_get_servername(lpszA))) {
+			private->exchname = talloc_strdup(NULL, exchname);
+			lpProp->value.lpszA = string_sub_talloc((TALLOC_CTX *) dce_call, lpProp->value.lpszA, exchname, 
+								lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
+			talloc_free(exchname);
+		}
+		talloc_free(lpszA);
+	}
+
+	return true;
+}
+
+
+/**
+   \details This function looks if the server DN string in the request
+   holds the mapiproxy netbios name and replaces it with the original
+   Exchange server one fetched from NspiQueryRows or NspiGetProps.
+
+   \param dce_call pointer to the session context
+   \param r pointer to the NspiDNToMId structure
+
+   \return true on success or false if no occurrence of the mapiproxy
+   netbios name was found.
+*/
+bool mapiproxy_NspiDNToMId(struct dcesrv_call_state *dce_call, struct NspiDNToMId *r)
+{
+	struct dcesrv_mapiproxy_private	*private;
+	const char			*proxyname;
+	uint32_t			i;
+
+	private = dce_call->context->private;
+	proxyname = lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
+
+	if (!private->exchname) return false;
+
+	for (i = 0; i < r->in.pNames->Count; i++) {
+		if (strstr(r->in.pNames->Strings[i], proxyname)) {
+			r->in.pNames->Strings[i] = string_sub_talloc((TALLOC_CTX *) dce_call, r->in.pNames->Strings[i], proxyname, private->exchname);
+			return true;
+		}
+	}
+
+	return false;
+}

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy_proto.h
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_proto.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_proto.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,153 @@
+/*
+   MAPI Proxy
+
+   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	__DCESRV_MAPIPROXY_PROTO_H__
+#define	__DCESRV_MAPIPROXY_PROTO_H__
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+
+/* definitions from dcesrv_mapiproxy.c */
+NTSTATUS dcerpc_server_mapiproxy_init(void);
+NTSTATUS samba_init_module(void);
+
+NTSTATUS dcerpc_server_exchange_nsp_init(void);
+NTSTATUS dcerpc_server_exchange_emsmdb_init(void);
+
+/* definitions from dcesrv_mapiproxy_nspi.c */
+bool mapiproxy_NspiGetProps(struct dcesrv_call_state *, struct NspiGetProps *);
+bool mapiproxy_NspiQueryRows(struct dcesrv_call_state *, struct NspiQueryRows *);
+bool mapiproxy_NspiDNToMId(struct dcesrv_call_state *, struct NspiDNToMId *);
+
+/* definitions from dcesrv_mapiproxy_rfr.c */
+bool mapiproxy_RfrGetNewDSA(struct dcesrv_call_state *, struct RfrGetNewDSA *);
+
+/* init functions definitions from gen_ndr/ndr_exchange_s.c */
+
+NTSTATUS dcerpc_server_exchange_store_admin3_init(void);
+NTSTATUS dcerpc_server_exchange_store_admin2_init(void);
+NTSTATUS dcerpc_server_exchange_store_admin1_init(void);
+NTSTATUS dcerpc_server_exchange_ds_rfr_init(void);
+NTSTATUS dcerpc_server_exchange_sysatt_cluster_init(void);
+NTSTATUS dcerpc_server_exchange_system_attendant_init(void);
+NTSTATUS dcerpc_server_exchange_mta_init(void);
+NTSTATUS dcerpc_server_exchange_drs_init(void);
+NTSTATUS dcerpc_server_exchange_xds_init(void);
+NTSTATUS dcerpc_server_exchange_mta_qadmin_init(void);
+NTSTATUS dcerpc_server_exchange_store_information_init(void);
+NTSTATUS dcerpc_server_exchange_nsp_init(void);
+NTSTATUS dcerpc_server_exchange_emsmdb_init(void);
+NTSTATUS dcerpc_server_exchange_unknown_init(void);
+
+/* definitions from samba4: librpc/ndr/ndr_table.c */
+NTSTATUS				ndr_table_init(void);
+NTSTATUS				ndr_table_register(const struct ndr_interface_table *);
+const struct ndr_interface_table	*ndr_table_by_uuid(const struct GUID *);
+const struct ndr_interface_list		*ndr_table_list(void);
+const struct ndr_interface_table	*ndr_table_by_name(const char *);
+
+/* The following definitions come from dcesrv_mapiproxy_unused.c  */
+void dcesrv_ec_store_admin3_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin3_dummy *);
+void dcesrv_ec_store_admin2_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin2_dummy *);
+void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin1_dummy *);
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetNewDSA *);
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetFQDNFromLegacyDN *);
+void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_cluster_dummy *);
+void dcesrv_sysatt_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_dummy *);
+void dcesrv_MtaBind(struct dcesrv_call_state *, TALLOC_CTX *,struct MtaBind *);
+void dcesrv_MtaBindAck(struct dcesrv_call_state *, TALLOC_CTX *,struct MtaBindAck *);
+void dcesrv_ds_abandon(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_abandon *);
+void dcesrv_ds_add_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_add_entry *);
+void dcesrv_ds_bind(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_bind *);
+void dcesrv_ds_compare(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_compare *);
+void dcesrv_ds_list(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_list *);
+void dcesrv_ds_modify_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_modify_entry *);
+void dcesrv_ds_modify_rdn(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_modify_rdn *);
+void dcesrv_ds_read(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_read *);
+void dcesrv_ds_receive_result(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_receive_result *);
+void dcesrv_ds_remove_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_remove_entry *);
+void dcesrv_ds_search(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_search *);
+void dcesrv_ds_unbind(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_unbind *);
+void dcesrv_ds_wait(struct dcesrv_call_state *, TALLOC_CTX *,struct ds_wait *);
+void dcesrv_dra_replica_add(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_add *);
+void dcesrv_dra_replica_delete(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_delete *);
+void dcesrv_dra_replica_synchronize(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_replica_synchronize *);
+void dcesrv_dra_reference_update(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_reference_update *);
+void dcesrv_dra_authorize_replica(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_authorize_replica *);
+void dcesrv_dra_unauthorize_replica(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_unauthorize_replica *);
+void dcesrv_dra_adopt(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_adopt *);
+void dcesrv_dra_set_status(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_set_status *);
+void dcesrv_dra_modify_entry(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_modify_entry *);
+void dcesrv_dra_delete_subref(struct dcesrv_call_state *, TALLOC_CTX *,struct dra_delete_subref *);
+void dcesrv_xds_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct xds_dummy *);
+void dcesrv_exchange_mta_qadmin(struct dcesrv_call_state *, TALLOC_CTX *,struct exchange_mta_qadmin *);
+void dcesrv_exchange_store_information_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct exchange_store_information_dummy *);
+
+
+/* NSPI protocol functions */
+enum MAPISTATUS dcesrv_NspiBind(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiBind *);
+enum MAPISTATUS dcesrv_NspiUnbind(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiUnbind *);
+enum MAPISTATUS dcesrv_NspiUpdateStat(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiUpdateStat *);
+enum MAPISTATUS dcesrv_NspiQueryRows(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiQueryRows *);
+enum MAPISTATUS dcesrv_NspiSeekEntries(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiSeekEntries *);
+enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetMatches *);
+enum MAPISTATUS dcesrv_NspiResortRestriction(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResortRestriction *);
+enum MAPISTATUS dcesrv_NspiDNToMId(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiDNToMId *);
+enum MAPISTATUS dcesrv_NspiGetPropList(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetPropList *);
+enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetProps *);
+enum MAPISTATUS dcesrv_NspiCompareMIds(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiCompareMIds *);
+enum MAPISTATUS  dcesrv_NspiModProps(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiModProps *);
+enum MAPISTATUS dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetSpecialTable *);
+enum MAPISTATUS dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetTemplateInfo *);
+enum MAPISTATUS dcesrv_NspiModLinkAtt(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiModLinkAtt *);
+enum MAPISTATUS dcesrv_NspiDeleteEntries(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiDeleteEntries *);
+enum MAPISTATUS dcesrv_NspiQueryColumns(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiQueryColumns *);
+enum MAPISTATUS dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetNamesFromIDs *);
+enum MAPISTATUS dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiGetIDsFromNames *);
+enum MAPISTATUS dcesrv_NspiResolveNames(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResolveNames *);
+enum MAPISTATUS dcesrv_NspiResolveNamesW(struct dcesrv_call_state *, TALLOC_CTX *,struct NspiResolveNamesW *);
+enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoConnect *);
+enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoDisconnect *);
+enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoRpc *);
+
+
+void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcGetMoreRpc *);
+enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRRegisterPushNotification *);
+enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRUnregisterPushNotification *);
+void dcesrv_EcDummyRpc(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDummyRpc *);
+void dcesrv_EcRGetDCName(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRGetDCName *);
+void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *, TALLOC_CTX *,struct EcRNetGetDCName *);
+void dcesrv_EcDoRpcExt(struct dcesrv_call_state *, TALLOC_CTX *,struct EcDoRpcExt *);
+enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *, TALLOC_CTX *, struct EcDoConnectEx *);
+void dcesrv_unknown_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct unknown_dummy *);
+
+__END_DECLS
+
+#endif	/* ! __DCESRV_MAPIPROXY_PROTO_H__ */

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy_rfr.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_rfr.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_rfr.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,49 @@
+/*
+   MAPI Proxy - RFR
+
+   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 "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+
+/**
+   \file dcesrv_mapiproxy_rfr.c
+
+   \brief NSPI Referral hook functions
+ */
+
+
+/**
+   \details This function replaces the Exchange server FQDN with
+   mapiproxy one.
+
+   \return true on success, otherwise false
+ */
+bool mapiproxy_RfrGetNewDSA(struct dcesrv_call_state *dce_call, struct RfrGetNewDSA *r)
+{
+	/* Sanity checks */
+	if (!r->out.ppszServer) return false;
+
+	*r->out.ppszServer = talloc_asprintf(dce_call, "%s.%s", 
+					     lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 
+					     lp_realm(dce_call->conn->dce_ctx->lp_ctx));
+	strlower_m((char *)*r->out.ppszServer);
+
+	return true;
+}

Added: trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy_unused.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,772 @@
+/*
+   MAPI Proxy
+
+   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/>.
+ */
+
+#define	_GNU_SOURCE 1
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <talloc.h>
+#include <dcerpc.h>
+
+#include <gen_ndr/exchange.h>
+
+#include <dcerpc_server.h>
+#include <util.h>
+#include <param.h>
+
+#include "gen_ndr/ndr_exchange.h"
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+/*
+   endpoint server for the exchange_store_admin3 pipe
+*/
+
+/*
+  ec_store_admin3_dummy
+*/
+void dcesrv_ec_store_admin3_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ec_store_admin3_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+   endpoint server for the exchange_store_admin2 pipe
+*/
+
+/*
+  ec_store_admin2_dummy
+*/
+void dcesrv_ec_store_admin2_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ec_store_admin2_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+   endpoint server for the exchange_store_admin1 pipe
+*/
+
+/*
+  ec_store_admin1_dummy
+*/
+void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ec_store_admin1_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+   endpoint server for the exchange_ds_rfr pipe
+*/
+
+/*
+  RfrGetNewDSA
+*/
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				    struct RfrGetNewDSA *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  RfrGetFQDNFromLegacyDN
+*/
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+					      struct RfrGetFQDNFromLegacyDN *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_sysatt_cluster pipe
+*/
+
+/*
+  sysatt_cluster_dummy
+*/
+void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct sysatt_cluster_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_system_attendant pipe
+*/
+
+/*
+  sysatt_dummy
+*/
+void dcesrv_sysatt_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct sysatt_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_mta pipe
+*/
+
+/*
+  MtaBind
+*/
+void dcesrv_MtaBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct MtaBind *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  MtaBindAck
+*/
+void dcesrv_MtaBindAck(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct MtaBindAck *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_drs pipe
+*/
+
+/*
+  ds_abandon
+*/
+void dcesrv_ds_abandon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_abandon *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_add_entry
+*/
+void dcesrv_ds_add_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_add_entry *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_bind
+*/
+void dcesrv_ds_bind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_bind *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_compare
+*/
+void dcesrv_ds_compare(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_compare *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_list
+*/
+void dcesrv_ds_list(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_list *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_modify_entry
+*/
+void dcesrv_ds_modify_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_modify_entry *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_modify_rdn
+*/
+void dcesrv_ds_modify_rdn(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_modify_rdn *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_read
+*/
+void dcesrv_ds_read(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_read *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_receive_result
+*/
+void dcesrv_ds_receive_result(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_receive_result *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_remove_entry
+*/
+void dcesrv_ds_remove_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_remove_entry *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_search
+*/
+void dcesrv_ds_search(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_search *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_unbind
+*/
+void dcesrv_ds_unbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_unbind *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  ds_wait
+*/
+void dcesrv_ds_wait(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct ds_wait *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_replica_add
+*/
+void dcesrv_dra_replica_add(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_replica_add *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_replica_delete
+*/
+void dcesrv_dra_replica_delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_replica_delete *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_replica_synchronize
+*/
+void dcesrv_dra_replica_synchronize(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_replica_synchronize *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_reference_update
+*/
+void dcesrv_dra_reference_update(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_reference_update *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_authorize_replica
+*/
+void dcesrv_dra_authorize_replica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_authorize_replica *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_unauthorize_replica
+*/
+void dcesrv_dra_unauthorize_replica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_unauthorize_replica *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_adopt
+*/
+void dcesrv_dra_adopt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_adopt *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_set_status
+*/
+void dcesrv_dra_set_status(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_set_status *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_modify_entry
+*/
+void dcesrv_dra_modify_entry(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_modify_entry *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/*
+  dra_delete_subref
+*/
+void dcesrv_dra_delete_subref(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct dra_delete_subref *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_xds pipe
+*/
+
+/*
+  xds_dummy
+*/
+void dcesrv_xds_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct xds_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_mta_qadmin pipe
+*/
+
+/*
+  exchange_mta_qadmin
+*/
+void dcesrv_exchange_mta_qadmin(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct exchange_mta_qadmin *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/*
+   endpoint server for the exchange_store_information pipe
+*/
+
+/*
+  exchange_store_information_dummy
+*/
+void dcesrv_exchange_store_information_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct exchange_store_information_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/* 
+   endpoint server for the exchange_nsp pipe
+*/
+
+/* 
+  NspiBind 
+*/
+
+enum MAPISTATUS dcesrv_NspiBind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiBind *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiUnbind 
+*/
+enum MAPISTATUS dcesrv_NspiUnbind(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiUnbind *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiUpdateStat 
+*/
+enum MAPISTATUS dcesrv_NspiUpdateStat(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiUpdateStat *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiQueryRows 
+*/
+enum MAPISTATUS dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiQueryRows *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiSeekEntries 
+*/
+enum MAPISTATUS dcesrv_NspiSeekEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				       struct NspiSeekEntries *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetMatches 
+*/
+enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				      struct NspiGetMatches *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiResortRestriction 
+*/
+enum MAPISTATUS dcesrv_NspiResortRestriction(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+					     struct NspiResortRestriction *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiDNToMId
+*/
+enum MAPISTATUS dcesrv_NspiDNToMId(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				   struct NspiDNToMId *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetPropList 
+*/
+enum MAPISTATUS dcesrv_NspiGetPropList(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				       struct NspiGetPropList *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetProps 
+*/
+enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				    struct NspiGetProps *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiCompareMIds 
+*/
+enum MAPISTATUS dcesrv_NspiCompareMIds(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				       struct NspiCompareMIds *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiModProps 
+*/
+enum MAPISTATUS dcesrv_NspiModProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				    struct NspiModProps *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetSpecialTable 
+*/
+enum MAPISTATUS dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiGetSpecialTable *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetTemplateInfo 
+*/
+enum MAPISTATUS dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiGetTemplateInfo *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiModLInkAtt 
+*/
+enum MAPISTATUS dcesrv_NspiModLinkAtt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+				      struct NspiModLinkAtt *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiDeleteEntries 
+*/
+enum MAPISTATUS dcesrv_NspiDeleteEntries(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+					 struct NspiDeleteEntries *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiQueryColumns 
+*/
+enum MAPISTATUS dcesrv_NspiQueryColumns(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiQueryColumns *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetNamesFromIDs 
+*/
+enum MAPISTATUS dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+					   struct NspiGetNamesFromIDs *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiGetIDsFromNames 
+*/
+enum MAPISTATUS dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+					   struct NspiGetIDsFromNames *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiResolveNames 
+*/
+enum MAPISTATUS dcesrv_NspiResolveNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiResolveNames *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  NspiResolveNamesW 
+*/
+enum MAPISTATUS dcesrv_NspiResolveNamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct NspiResolveNamesW *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/* 
+   endpoint server for the exchange_emsmdb pipe
+*/
+
+/* 
+  EcDoConnect 
+*/
+enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDoConnect *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcDoDisconnect 
+*/
+enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDoDisconnect *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcDoRpc 
+*/
+enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDoRpc *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcGetMoreRpc 
+*/
+void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcGetMoreRpc *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcRRegisterPushNotification 
+*/
+enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcRRegisterPushNotification *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcRUnregisterPushNotification 
+*/
+enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcRUnregisterPushNotification *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcDummyRpc 
+*/
+void dcesrv_EcDummyRpc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDummyRpc *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcRGetDCName 
+*/
+void dcesrv_EcRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcRGetDCName *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcRNetGetDCName 
+*/
+void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcRNetGetDCName *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/* 
+  EcDoRpcExt 
+*/
+void dcesrv_EcDoRpcExt(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDoRpcExt *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/* 
+  EcDoConnect Ex
+*/
+enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct EcDoConnectEx *r)
+{
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+/* 
+   endpoint server for the exchange_unknown pipe
+*/
+
+/* 
+  unknown_dummy 
+*/
+void dcesrv_unknown_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+		       struct unknown_dummy *r)
+{
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}

Added: trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy
===================================================================
--- trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/mapiproxy-documentation.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1467 @@
+/**
+\mainpage
+
+<center><img src="mapiproxy.png"></center>
+
+\section Contents
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<ul>
+ <li><a href="#revision">        Revision History        </a></li>
+ <li><a href="#introduction"> 1. Introduction            </a>
+  <ul>
+    <li><a href="#purpose"> 1.1. Purpose and Scope</a></li>
+    <li><a href="#overview">1.2. General Overview</a></li>
+    <li><a href="#bugs">    1.3. Bugs and Limitations </a></li>
+  </ul>
+ </li>
+ <li><a href="#install">  2. Installation</a>
+  <ul>
+    <li><a href="#download">  2.1. Download MAPIProxy</a></li>
+    <li><a href="#samba4">    2.2. Samba4 installation</a></li>
+    <li><a href="#mpinstall"> 2.3. MAPIProxy installation</a></li>
+  </ul>
+ </li>
+ <li><a href="#config"> 3. Configuration</a>
+  <ul>
+    <li><a href="#minute">    3.1. 5-Minute Configuration</a></li>
+  </ul>
+ </li>
+ <li><a href="#concepts"> 4. Technical Concepts</a>
+   <ul>
+    <li><a href="#bindings">   4.1. NSPI Bindings Replacement</a></li>
+    <li><a href="#rfr">        4.2. NSPI Referral FQDN Replacement</a></li>
+    <li><a href="#retrograde"> 4.3. Force EMSMDB Protocol Version</a></li>
+    <li><a href="#idl">        4.4. OpenChange IDL file</a></li>
+   </ul>
+ </li>
+ <li><a href="#mod_dev"> 5. Stackable Modules </a>
+   <ul>
+    <li><a href="#mpm_overview"> 5.1. General Overview</a></li>
+    <li><a href="#mpm_ep">       5.2. Module entry point</a></li>
+    <li><a href="#mpm_hooks">    5.3. Module Hooks</a></li>
+    <li><a href="#mpm_mapiproxy">5.4. mapiproxy structure</a></li>
+   </ul>
+ </li>
+ <li><a href="#modules"> 6. Available Modules </a>
+   <ul>
+    <li><a href="#mod_downgrade"> 6.1. Downgrade Module</a></li>
+    <li><a href="#mod_pack">      6.2. Pack Module</a></li>
+    <li><a href="#mod_cache">     6.3. Cache Module</a></li>
+   </ul>
+ </li>
+ <li><a href="#server_mode"> 7. Server Mode </a>
+   <ul>
+    <li><a href="#server_conf">     7.1. 5-Minute Configuration</a></li>
+    <li><a href="#server_overview"> 7.2. General Overview </a></li>
+   </ul>
+ </li>
+ <li><a href="#faq">8. Frequently Asked Questions</a>
+  <ul>
+   <li><a href="#notcompleted"> 8.1. The action could not be completed</a></li>
+   <li><a href="#cantopen">	8.2. Profile creation goes fine, but Outlook can't open your default e-mail folders</a></li>
+   <li><a href="#dc">           8.3. Does MAPIProxy need to be domain controller?</a></li>
+   <li><a href="#gnutls">       8.4. Generating Samba's private keys takes infinite time</a></li>
+   <li><a href="#gmake">	8.5. On Ubuntu <i>make samba-git</i> exits with <i>gmake: not found</i></a></li>
+  </ul>
+ </li>
+</ul>
+</td>
+</tr>
+</table>
+<br/>
+
+<a name="revision"></a><h2>Revision History</h2>
+<table align="center" width="80%">
+	<tr>
+	   <td style="text-align:center"><strong>Date</strong></td>
+	   <td style="text-align:center"><strong>Revision Number</strong></td>
+	   <td style="text-align:center"><strong>Author</strong></td>
+	   <td style="text-align:center"><strong>Revision Content</strong></td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">01/02/09</td>
+	   <td style="text-align:center"><strong>0.6.1</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Add configuration info for server mode.</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">04/01/09</td>
+	   <td style="text-align:center"><strong>0.6</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">server mode documented, update
+	   mapiproxy naming to MAPIProxy.</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">29/12/08</td>
+	   <td style="text-align:center"><strong>0.5.5</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Add 3 new questions to FAQ section</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">09/12/08</td>
+	   <td style="text-align:center"><strong>0.5.4</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Add dcesrv:assoc group checking
+	   to smb.conf configuration requirements</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">10/07/08</td>
+	   <td style="text-align:center"><strong>0.5.3</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Rename smbd process to samba
+	   session API and update documentation</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">08/26/08</td>
+	   <td style="text-align:center"><strong>0.5.2</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">documentation update on NSPI
+	   replacement and new FAQ question added</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">08/26/08</td>
+	   <td style="text-align:center"><strong>0.5.1</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">documentation on NSPI referral added</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">08/11/08</td>
+	   <td style="text-align:center"><strong>0.5</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">unbind hook added, cache
+	   module documentation and scenario added </td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">07/23/08</td>
+	   <td style="text-align:center"><strong>0.4</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">MAPIProxy API hooks, IDL
+	   update, mapiproxy structure description and documentation
+	   added for the cache module</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">06/25/08</td>
+	   <td style="text-align:center"><strong>0.3.2</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Minor installation update</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">06/04/08</td>
+	   <td style="text-align:center"><strong>0.3.1</strong></td>
+	   <td style="text-align:center">Brad Hards</td>
+	   <td style="text-align:left">Minor edits</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">05/27/08</td>
+	   <td style="text-align:center"><strong>0.3</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">Available modules section
+	   added</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">05/24/08</td>
+	   <td style="text-align:center"><strong>0.2</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:left">EMSMDB protocol version
+	   subsection updated, modules system section added, 5-minute
+	   configuration updated</td>
+	</tr>
+	<tr>
+	   <td style="text-align:center">05/15/08</td>
+	   <td style="text-align:center"><strong>0.1</strong></td>
+	   <td style="text-align:center">Julien Kerihuel</td>
+	   <td style="text-align:center">Initial Revision</td>
+	</tr>
+</table>
+<br/>
+
+<a name="introduction"></a><h2>1. Introduction</h2>
+
+<a name="purpose"></a><h3>1.1. Purpose and Scope</h3>
+
+MAPIProxy is an endpoint server for Samba4 which proxies ExchangeRPC
+traffic from MAPI clients (Outlook, openchangeclient, etc.) to
+Microsoft Exchange Server (and back). It can either act as a
+transparent proxy, for hacking, monitoring or debugging purposes or
+modify traffic on the fly and so provide new features. It is primarily
+developed for - but not limited to - third-party implementors looking
+for a development framework they can use for MAPI acceleration
+purposes.
+
+This project is originally based on dcerpc_remote.c code from Stefan
+Metzemacher (Samba4 trunk) and is released under GPLv3 or later. It
+creates a dynamic shared object file which is loaded into samba and 
+uses the Samba configuration file (smb.conf) to set common options.
+
+<br/>
+<a name="overview"></a><h3>1.2. General overview</h3>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_overview.png" />
+</td>
+</tr>
+</table>
+<center>Figure 1. General MAPIProxy network overview</center>
+
+The MAPIProxy traffic can be divided into 3 different parts as
+described in the figure above:
+
+<ul>
+<li style="text-align:justify;"><strong>[1] clients to
+MAPIProxy:</strong><br/>The origin of a client connect does not 
+have much importance: it can either be an incoming connection from a
+real MAPI client, a connection relayed from another third-party
+proxy or another MAPIProxy instance. MAPIProxy runs as an endpoint
+server registered when samba starts. When the Samba4 endpoint mapper
+receives an incoming connection asking for one of the ExchangeRPC
+endpoints: NSPI (Name Service Provider Interface - Address Book) or
+EMSMDB (Exchange Message Store), the endpoint mapper redirects
+ExchangeRPC traffic to MAPIProxy which will pull, push and dispatch
+MAPI operations.</li>
+
+<li style="text-align:justify;"><strong>[2] MAPIProxy to
+MAPIProxy:</strong><br/>The main objective of MAPIProxy is not to
+directly connect to the remote message server, but rather to relay
+some kind of modified MAPI traffic to the next MAPIProxy hop. This
+configuration can be used to add a compression layer between MAPIProxy
+instances, or to send specific third-party vendor information.
+However, a proxied connection directly from a MAPI client to an 
+Exchange server (i.e. <i>client-MAPIProxy-server</i> is possible and
+such a configuration could be used for many other purposes.<br/></li>
+
+<li><strong>[3] MAPIProxy to server:</strong><br/>This last node is
+responsible for restoring MAPI contents and pushing it to the real
+Exchange server. </li> 
+</ul>
+<br/>
+
+<a name="bugs"></a><h2>1.3. Bugs and Limitations</h2></a>
+
+If you find bugs, limitations or have features you would like to see
+included in MAPIProxy, please register on the OpenChange Ticket System
+and create new tickets for the MAPIProxy component:
+<ul>
+<li><a
+href="http://trac.openchange.org">http://trac.openchange.org</a>
+(OpenChange Ticket System)</li>
+<li><a
+href="http://trac.openchange.org/query?status=new&status=assigned&status=reopened&component=mapiproxy&order=priority">MAPIProxy
+Component Tickets</a></li>
+</ul>
+<br/>
+
+
+<a name="install"></a><h2>2. Installation</h2>
+<a name="download"></a><h3>2.1. Download MAPIProxy</h3>
+
+MAPIProxy is only available through SVN at the moment. A tarball 
+release will only be made when we have a stabilized API with a
+preliminary set of useful features. You will need a <a
+href="http://subversion.tigris.org/">SVN client</a> to download
+openchange (including  MAPIProxy)..
+
+\code
+ $ svn co https://svn.openchange.org/openchange/trunk openchange
+\endcode
+
+<a name="samba4"></a><h3>2.2. Samba4 installation</h3>
+
+The MAPIProxy implementation requires a very recent Samba4 version
+in order to run properly. If Samba4 is planned to be installed
+from scratch for MAPIProxy only, please use the <i>make samba-git</i>
+compilation rule provided in the build system. This command will
+automate most part of the samba4 installation process. The only
+requirement for this step is to have an up to date <a
+href="http://git.or.cz/">GIT version</a> installed on the system.
+
+\code
+  # make samba-git
+\endcode
+
+When the installation process is finished, a running samba4
+installation will be located in <i>/usr/local/samba/</i>. You will possibly be
+required to run <i>ldconfig</i> before you move to next steps. Please
+refer to <i>doc/howto.txt</i> for further information on openchange
+compilation.
+<br/>
+
+<a name="mpinstall"></a><h3>2.3. MAPIProxy installation</h3>
+
+If you have existing OpenChange DSO in the
+<i>/usr/local/samba/modules/dcerpc_server/</i> folder, such as
+<i>dcesrv_exchange.so</i>, <strong>please remove them prior loading
+samba with MAPIProxy.</strong>
+
+\code
+  $ ./autogen.sh
+  $ ./configure --prefix=/usr/local/samba
+  $ make
+  # make install
+  # rm -rf /usr/local/samba/modules/dcerpc_server/dcesrv_exchange.so
+\endcode
+
+<br/>
+
+
+<a name="config"></a><h2>3. Configuration</h2>
+<a name="minute"></a><h3>3.1. 5-Minute Configuration</h3>
+
+This 5-Minute configuration will help you set up a minimal MAPIProxy
+using specified credentials and relaying traffic from Outlook clients
+to a remote Exchange server. This configuration will be performed in three
+steps:
+
+<ul>
+<li><strong>[1] Provision Samba</strong>:<br/>From samba4/source4
+directory, run under the root account:
+\code
+# ./setup/provision --realm=OPENCHANGE.LOCAL --domain=OPENCHANGE \
+                    --adminpass=openchange --server-role='domain controller'
+\endcode
+
+If you don't have DNS resolution and your realm can't be resolved,
+samba will be unable to authenticate the user in its user database. You
+must specify a realm which MAPI clients and MAPIProxy can resolve.
+
+If everything works fine, the provisioning script will have created
+all the databases, populated the AD (Active Directory) and generated a
+valid smb.conf file.
+</li>
+
+<li><strong>[2] Add a user account</strong>:<br/>
+
+In this configuration, we'll set the same credentials both for the
+user in the windows domain and on the Samba4 server. Let say there is
+already a user named <i>testuser</i> with its password set to
+<i>openchange</i> on the Exchange server:
+\code
+# ./setup/newuser testuser
+New Password: openchange
+\endcode
+</li>
+
+<li><strong>[3] Configure MAPIProxy options</strong>:<br/>
+
+In this final step, we only need to customize a small set of parameters:
+<ul>
+
+ <li style="text-align:justify;"><strong>dcerpc endpoint
+ servers</strong>:<br/> MUST include epmapper and mapiproxy separated
+ with comma.</li>
+
+ <li
+ style="text-align:justify;"><strong>dcerpc_mapiproxy:binding</strong>:<br/>
+ This is the binding string used to connect to the remote Exchange
+ server. The format of this string is: transport:address[flags]. In the
+ example below, we'll be using the TCP over IP transport, connect on
+ 192.168.1.1 and add the print flag so MAPI packets get dissected on
+ samba stdout (or logfile).</li>
+
+ <li
+ style="text-align:justify;"><strong>dcerpc_mapiproxy:username</strong>
+ and <strong>dcerpc_mapiproxy:password</strong>:<br/>The specified
+ credentials we will be using to connect to the remote Exchange
+ server.</li>
+
+ <li
+ style="text-align:justify;"><strong>dcerpc_mapiproxy:domain</strong>:<br/>
+ The Windows domain the remote Exchange server belongs to.</li>
+
+ <li
+ style="text-align:justify;"><strong>dcerpc_mapiproxy:interfaces</strong>:<br/>
+ In our case, we want to relay the whole ExchangeRPC traffic, so we
+ need to load both the EMSMDB and NSP interface. In the meantime,
+ people interested in NSPI proxy only would only have to load the
+ exchange_nsp interface.</li>
+
+<li
+style="text-align:justify;"><strong>dcerpc_mapiproxy:modules</strong>:<br/>
+MAPIProxy provides a stackable modular system which primary objective
+is to provide developers an API for modules development. In our case
+we want to activate the <i>downgrade</i> module responsible for the
+EcDoConnect/EcDoRpc EMSMDB RPC functions negotiation.</li>
+
+</ul>
+
+\code
+[globals]
+        netbios name    = MAPIPROXY
+        workgroup       = OPENCHANGE
+        realm           = OPENCHANGE.LOCAL
+        server role     = domain controller
+
+	### Configuration required by mapiproxy ###
+	dcesrv:assoc group checking = false
+        dcerpc endpoint servers = epmapper, mapiproxy
+
+        dcerpc_mapiproxy:binding = ncacn_ip_tcp:192.168.1.1[print]
+        dcerpc_mapiproxy:username = testuser
+        dcerpc_mapiproxy:password = openchange
+        dcerpc_mapiproxy:domain = EXCHANGE
+        dcerpc_mapiproxy:interfaces = exchange_emsmdb, exchange_nsp, exchange_ds_rfr
+	dcerpc_mapiproxy:modules = downgrade
+	### Configuration required by mapiproxy ###
+
+
+[netlogon]
+        path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts
+        read only = no
+
+[sysvol]
+        path = /usr/local/samba/var/locks/sysvol
+        read only = no
+\endcode
+</li>
+</ul>
+
+We are now ready to run samba:
+\code
+ # samba -d5 -i -M single
+\endcode
+
+If everything works properly, the following lines should be displayed
+in samba output:
+\code
+DCERPC endpoint server 'exchange_emsmdb' registered
+DCERPC endpoint server 'exchange_nsp' registered
+DCERPC endpoint server 'exchange_ds_rfr' registered
+DCERPC endpoint server 'mapiproxy' registered
+dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_np:[\pipe\epmapper]'
+dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncacn_ip_tcp:[135]'
+dcesrv_interface_register: interface 'epmapper' registered on endpoint 'ncalrpc:[EPMAPPER]'
+MAPIPROXY module 'downgrade' registered
+MAPIPROXY module 'downgrade' loaded
+mapiproxy_module_load 'downgrade' (Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc)
+dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\lsass]'
+dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
+dcesrv_interface_register: interface 'exchange_emsmdb' registered on endpoint 'ncacn_ip_tcp:'
+dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\lsass]'
+dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
+dcesrv_interface_register: interface 'exchange_nsp' registered on endpoint 'ncacn_ip_tcp:[]'
+dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\lsass]'
+dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_np:[\pipe\protected_storage]'
+dcesrv_interface_register: interface 'exchange_ds_rfr' registered on endpoint 'ncacn_ip_tcp:[]'
+\endcode
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<strong>You should now be able to configure Outlook to use 
+an Exchange account with the proxy IP address and run Outlook
+seamlessly (both online or cached exchange mode).</strong>
+</td>
+</tr>
+</table>
+<br/>
+
+<a name="concepts"></a><h2>4. Technical Concepts</h2>
+<a name="bindings"></a><h3>4.1. NSPI Bindings Replacement</h3>
+
+When Outlook sets up an Exchange account using either the mail applet
+from the configuration panel or the account editor within Outlook, it
+uses the NSPI protocol (Name Service Provider Interface, effectively
+the address book provider). In this case, NSPI is used to resolve the
+Exchange username and fetch from Exchange server all information
+needed by Outlook to initiate direct connection to the EMSMDB pipe 
+(effectively the message store) the next time it connects to the server.
+<br/>
+
+At some point of the profile's creation process, Outlook queries
+Exchange for some specific connection information using the
+<strong>NspiGetProps (0x9) RPC operation </strong>. More specifically,
+when Outlook requests for the
+<strong>PR_EMS_AB_NETWORK_ADDRESS</strong> MAPI property, Exchange
+returns a list <strong>binding strings</strong>. Outlook next stores
+these binding strings at some location - associated to the Outlook
+profile - in the windows registry and uses them for future
+connections.<br/>
+
+Outlook can also rely on other information returned by NSPI functions
+and connect to the real Exchange server rather than MAPIProxy. Such
+case occurs when Outlook is able to resolve the exchange server using
+its hostname. This reference to the original Exchange server can be
+found when Outlook requests for the
+<strong>PR_EMS_AB_HOME_MDB</strong> MAPI property during the
+<strong>NspiQueryRows (0x3) RPC operation</strong>. MAPIProxy replaces
+the Exchange server name with its own netbios name and forward the
+reply to the client.<br/>
+
+In the meantime, this information is next used by Outlook to query a
+minimal entry ID for a distinguished name using this server
+name. MAPIProxy needs to substitute the server name in the inbound
+request string with the original exchange one.<br/>
+
+MAPIProxy needs to avoid Outlook clients being aware of this remote
+server address and trying to communicate directly with the remote server
+instead of using the proxy. In order to do this, MAPIProxy alters the
+Outlook-Exchange MAPI traffic and replaces these binding strings with
+the MAPIProxy FQDN and netbios name.
+
+<br/>
+<a name="rfr"></a><h3>4.2. NSPI Referral Replacement</h3>
+
+The Address Book Name Service Provider Interface (NSPI) Referral
+Service is a service used by Outlook to retrieve the name of an NSPI
+server. No NSPI connection should be initiated without first querying
+for the correct NSPI server. In this case, RFR returns the fully
+qualified domain name of the real Exchange server and starts using it
+if available. <br/>
+
+MAPIProxy needs to avoid Outlook clients being aware of this server
+address and trying to communicate directly with the remote server
+instead of using the proxy. In order to do this, MAPIProxy alters the
+Outlook-Exchange MAPI traffic and replaces the server DN returned by
+<strong>RfrGetNewDSA (0x0) RPC operation</strong> with the MAPIProxy
+realm as specified in smb.conf.
+
+<br/>
+<a name="retrograde"></a><h3>4.3. Force EMSMDB Protocol Version</h3>
+
+When Outlook starts and presumably calls MapiLogonEx, it first opens a
+connection to the Exchange server on the NSPI pipe, then on the EMSMDB
+pipe. Under Outlook 2003, the very first EMSMDB RPC call Outlook makes
+can be considered as a kind of <i>protocol version
+negotiation</i>. Depending on which version of Outlook is used, and how
+the Exchange server replies to the EMSMDB connect request, Outlook will
+either keep using the same pool of RPC calls or downgrade.
+
+For example Outlook 2003 (default behavior) tests if the remote server
+supports the 2 new EMSMDB calls (EcDoConnectEx/EcDoRpcExt2) introduced
+in Exchange 2003. If Exchange replies to the EcDoConnectEx request
+with a dcerpc_fault, it means the server does not support the RPC
+operation, presumably has a version before 2003, and Outlook needs to
+downgrade its version in order to communicate with the server:
+<ul>
+  <li>EcDoConnectEx (0xa) call
+    <ul>
+       <li>On success, Outlook will use EcDoRpcExt2 (0xb) to handle MAPI traffic</li>
+       <li>On failure (dcerpc_fault: nca_op_rng_error), Outlook calls
+       EcDoConnect (0x0) and use EcDoRpc (0x2) to handle MAPI
+       traffic</li>
+   </ul> 
+  </li>
+</ul>
+
+If MAPIProxy runs in an environment with Outlook clients and
+Exchange servers using a version above 2003, a last step is required
+to successfully use Outlook. The EcDoConnect RPC reply returns the Exchange
+server version (as an array of 3 short integers). When Outlook detects this
+particular server version, it automatically closes the connection and keep
+requesting indefinitely for EcDoConnectEx. To deal with this, MAPIProxy 
+modifies  the EcDoConnect reply sent by Exchange and replaces the server version
+with a one equal to that sent by Exchange 2000.
+
+In the meantime, if we reproduce this test with Outlook 2000 which
+doesn't support these 2 new RPC calls, Outlook will directly call
+EcDoConnect.
+
+The main difference between the EcDoConnectEx/EcDoRpcExt2 operations and
+the EcDoConnect/EcDoRpc operations is that the former use 
+both XOR 0xA5 obfuscation and LZ77 compression/Direct2 encoding;
+while the latter only use the XOR obfuscation to handle MAPI content.
+If MAPIProxy wants to act as an intelligent proxy (for example, to 
+be able to analyze MAPI content on the fly, compress MAPI data etc),
+receiving non compressed MAPI traffic would probably improve the
+overall process.
+
+Below is a list of Exchange/Outlook pairs and the EMSMDB connect
+function they will use by default:
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+ <tr style="border:none">
+  <td style="border:none"><strong>Exchange version</strong></td>
+  <td style="border:none"><strong>Outlook version</strong></td>
+  <td style="border:none"><strong>EMSMDB connect function</strong></td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0;">5.5/2000</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0;">any</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0;">EcDoConnect (0x0)</td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2003</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2000</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">EcDoConnect (0x0)</td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2007</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2000</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">EcDoConnect
+  (0x0)<br/>Microsoft officially says it is unsupported</td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2003</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2003-2007</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">EcDoConnectEx (0xa)</td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2007</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2003</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">EcDoConnectEx (0xa)</td>
+ </tr>
+ <tr>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2007</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">2007</td>
+  <td style="border:none;border-bottom:1px solid #e0e0e0">EcDoConnectEx (0xa)</td>
+ </tr>
+</table>
+
+MAPIProxy reproduces the Exchange 2000 behavior and prevents Outlook
+from communicating with the Exchange server using the
+EcDoConnectEx/EcDoRpcExt2 as described in Figure 2 below. When Outlook
+sends an EcDoConnectEx request, MAPIProxy does not relay the request to
+the remote Exchange server and immediately returns a dcerpc_fault to
+Outlook. Outlook, assuming the server doesn't support this call uses
+EcDoConnect instead. From this call, MAPIProxy relay the information
+to Exchange.
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_emsmdb_graph.png" width="75%" height="75%" />
+</td>
+</tr>
+</table>
+<center>Figure 2. MAPIProxy behavior on Outlook EMSMDB connection</center>
+
+From the Exchange side, the server will analyze this EcDoConnect
+request as a call sent by Outlook 2000 or below version. Exchange
+works fine using this protocol version unless Exchange 2007 SP1 which
+appears to introduce client version restrictions <i>by default</i>. In
+the meantime, existing tests demonstrate similar restrictions would
+apply to Outlook 2003 connection (without MAPIProxy) and prevent
+Outlook version before 2007 connecting to Exchange 2007. Further information
+and solution is available at the following addresses:
+<ul>
+  <li><a href="http://support.microsoft.com/kb/555851">Earlier Outlook clients cant connect to Exchange 2007 Server</a></li>
+  <li><a href="http://msexchangeteam.com/archive/2006/02/20/419994.aspx">Exchange 12 and Public Folders</a></li>
+</ul>
+<br/>
+
+<a name="idl"></a><h3> 4.4. OpenChange IDL File </h3>
+
+IDL stands for Interface Definition Language and OpenChange uses this
+format to describe ExchangeRPC communications. This file is processed
+by pidl (Perl IDL compiler provided by Samba4) which turns this
+protocol description into C-code dealing with the push, pull and print
+operations.
+
+OpenChange development policy in trunk used to push a new MAPI call in
+the IDL only when the associated libmapi implementation and mapitest
+unit is developed, but this was preventing from distributing MAPIProxy
+with further openchange releases. Furthermore, the OpenChange IDL is
+now almost complete and merging back to the trunk helps improving
+libmapi reliability.
+
+<br/>
+
+
+<a name="mod_dev"></a><h2>5. Stackable Modules</h2>
+<a name="mpm_overview"></a><h3>5.1. General Overview</h3>
+
+The MAPIProxy stackable modules system provides implementors a
+development framework to add new features. This stackable mechanism
+allows developers to write modules with a very specific scope of 
+which modifications will transparently be relayed to the next module
+until it is finally pushed by MAPIProxy to
+the next hop (Figure 3.).
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mpm_stack.png" width="75%" height="75%" />
+</td>
+</tr>
+</table>
+<center>Figure 3. MAPIProxy module stack and EcDoRpc interaction </center>
+
+With this system, developers can focus their effort on ExchangeRPC
+traffic - or any other protocol samba supports - interception,
+modification, analysis and avoid spending time on implementing a new
+endpoint server. Furthermore it provides an easier way for
+implementors to divide the work in smaller units and develop each of
+them in a separated module.
+<br/>
+
+MAPIProxy modules are dynamic shared objects with an entry point and a
+limited set of hooks. These modules have to be installed in the
+<i>dcerpc_mapiproxy</i> folder within the samba4 modules directory
+(e.g. <i>/usr/local/samba/modules</i>). MAPIProxy modules specified
+in the Samba configuration file (smb.conf) will be loaded into MAPIProxy
+at runtime and interact with each other in the same order they were
+defined:
+
+\code
+	dcerpc_mapiproxy:modules = downgrade,dummy
+\endcode
+
+All MAPIProxy modules will be registered but only those specified on
+the <strong>dcerpc_mapiproxy:modules</strong> parametric option line
+will be added to the chained list of effective modules.
+<br/><br/>
+
+
+<a name="mpm_ep"></a><h3>5.2. Module entry point</h3>
+
+MAPIProxy modules must have an entry point function named
+<strong>samba_init_module</strong>. This function needs to set general
+information about the module, specify the module's hooks and finally
+call the <strong>mapiproxy_module_register</strong> function to
+register itself in the MAPIProxy module subsystem.
+
+\code
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	module;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	module.name        = "sample";
+	module.description = "A sample module";
+	module.endpoint    = "any";
+
+	/* Fill in all the operations */
+	module.init     = sample_init;
+	module.push     = sample_push;
+	module.ndr_pull = sample_ndr_pull;
+	module.pull     = sample_pull;
+	module.dispatch = NULL;
+	module.unbind   = NULL;
+
+	/* Register ourselves with the MAPIPROXY subsytem */
+	ret = mapiproxy_module_register(&module);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register 'sample' mapiproxy module!\n"));
+		return ret;
+	}
+
+	return ret;
+}
+\endcode
+
+<ul>
+    <li><strong>module.name</strong>:<br/>
+    This is the module name. This name will be used by
+    dcerpc_mapiproxy:modules in smb.conf to load the module</li>
+
+    <li><strong>module.description</strong>:<br/> 
+    This field lets developers specify a brief module description for
+    information purpose only.</li>
+
+    <li><strong>module.endpoint</strong>:<br/> 
+    This field defines the interface which this module is designed to
+    work with. The primary objective is to avoid calling the module
+    hooks if the module doesn't have any impact on the requests or
+    replies. For example, a module only interacting with the EcDoRpc
+    function should define <i>exchange_emsmdb</i>.
+
+    In the meantime, it can happen that a module requires to interact
+    with more than a single interface. In such case, use the
+    '<strong>any</strong>' keyword which will call the modules functions
+    with any endpoints proxied by MAPIProxy.</li>
+</ul>
+
+
+<a name="mpm_hooks"></a><h3> 5.3. Module Hooks</h3>
+
+MAPIProxy offers a set of hooks which modules can implement to
+modify/change/alter client to server MAPI traffic. The figure below
+shows how and when hooks are called during a request/response
+lifetime.
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_hook_life.png" />
+</td>
+</tr>
+</table>
+<center> Figure 4. Usage of MAPIProxy Hooks during a request/response life time </center>
+
+<ul>
+
+<li><strong>init</strong>: This is the initialization function for the
+module which is only called once - when the module is loaded. It is
+generally used to retrieve smb.conf parametric options for the module
+and initialize some global structures</li>
+
+<li><strong>pull</strong>: This is the function called when MAPIProxy
+receives a MAPI request. The request has already been extracted and
+its information filled into MAPI structures
+
+<li><strong>push</strong>: This is the function called when MAPIProxy
+receive a MAPI response. The response has already been extracted and
+its information filled into MAPI structures</li>
+
+<li><strong>dispatch</strong>: Similarly to the MAPIProxy
+top-level dispatch function, it is used to dispatch the
+information. This function is called after the pull but before the
+push. Moreover it is called before the request is forward to the
+remote endpoint.</li>
+
+<li><strong>ndr_pull</strong>: This is the function called before
+data from a request is extracted from the NDR blob.</li>
+
+<li><strong>ndr_push</strong>: This is the function called before
+data from a response is extracted from the NDR blob.</li>
+
+<li><strong>unbind</strong>: This is the function called when the
+connection closes. It can be used to free data associated to a given
+session and stored within a module global list.</li>
+
+</ul>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<strong>Please note that the module API is still under development and
+is likely to change in further revisions.</strong>
+</td>
+</tr>
+</table>
+
+
+<a name="mpm_mapiproxy"></a><h3> 5.4. mapiproxy structure </h3>
+MAPIProxy uses a structure modules can modify in their dispatch routine
+and which impact on the general MAPIProxy behavior.
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_struct.png" />
+</td>
+</tr>
+</table>
+<center> Figure 5. overview of mapiproxy structure variables scope </center>
+
+<ul> 
+
+<li><strong>norelay</strong>: This boolean variable can be used by
+modules to tell MAPIProxy not to relay the incoming
+<strong>request</strong> to the remote server through
+<i>dcerpc_ndr_request()</i> but directly jump to the push (response)
+MAPIProxy code. This variable is for example in use within the cache
+module when we read stream from the local filesystem and play it back
+to MAPI clients.</li>
+
+<li><strong>ahead</strong>: This boolean variable can be used by
+modules to tell MAPIProxy not to relay the incoming
+<strong>response</strong> to the client through the <i>push</i> and
+<i>dcerpc_ndr_request</i> routine but loop over the dispatch
+routine. This variable is for example in use within the cache module
+when we want to read a stream ahead from Exchange server to the remote
+MAPIProxy instance.</li>
+
+</ul>
+
+<br/>
+
+
+
+<a name="modules"></a><h2> 6. Available Modules </h2>
+<a name="mod_downgrade"></a><h3> 6.1. Downgrade Module</h3>
+
+The <strong>downgrade</strong> module implements the
+EcDoConnect/EcDoRpc negotiation as described in <a
+href="#retrograde">section 4.2</a>. It ensures Outlook will not send
+compressed information or use functions other than EcDoRpc for
+EMSMDB transport. In order to use the downgrade module, edit smb.conf
+and add <i>downgrade</i> to <i>dcerpc_mapiproxy:modules</i>.
+
+\code
+	dcerpc_mapiproxy:modules = downgrade
+\endcode
+
+<br/>
+
+<a name="mod_pack"></a><h3> 6.2. Pack Module </h3>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<strong>Note that this module only works with an infrastructure using two or
+more instances of MAPIProxy as described in <a href="#overview">Figure
+1</a></strong>
+</td>
+</tr>
+</table>
+
+The <strong>pack</strong> module implements routines designed to
+manipulate and factorize MAPI content between different MAPIProxy
+instances. It also offers a developer overview on how to manipulate
+mapi requests. Last but not least, it provides data which can next be
+used by subsequent MAPIProxy modules for example to compress or
+encrypt this proxypack blob.
+
+<ul>
+
+<li>First, MAPIProxy extracts and removes specific MAPI calls from the
+request, pack them within the proxypack MAPI call data blob, prefix
+them with their real offset in the array of mapi requests and finally
+append this custom call at the end of the mapi requests array (Figure
+4).</li>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mpm_pack_pack.png" />
+</td>
+</tr>
+</table>
+<center> Figure 6. Pack process </center>
+
+<li>Final MAPIProxy hop will seek the mapi requests array looking for
+the proxypack call. If found, it unpacks MAPI data and restore these
+calls at their initial location within the mapi requests array (Figure
+6).</li>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mpm_pack_unpack.png" />
+</td>
+</tr>
+</table>
+<center> Figure 7. Unpack process </center>
+
+</ul>
+
+
+This module has two configuration options:
+<ul>
+ <li><strong>mpm_pack:opnums</strong><br/>
+ This option takes a list of MAPI calls to pack into the proxypack
+ data blob. It can take one or more MAPI opnums, each of them
+ separated with a comma.</li>
+
+ <li><strong>mpm_pack:lasthop</strong><br/>
+ This options takes either <i>true</i> or <i>false</i>.the lasthop
+ option defines whether this is a MAPIProxy directly connected to
+ Outlook/Exchange or yet another proxy inserted within the MAPIProxy
+ chain of hops. If this MAPIProxy instance is not a last hop, then it
+ will skip the pack/unpack operations and forward the request to the
+ next one.</li>
+</ul>
+
+\code
+        mpm_pack:opnums = 0x70,0x75,0x76,0x77,0xa
+        mpm_pack:lasthop = true
+\endcode
+
+In order to use the pack module, edit smb.conf and add <i>pack</i> to
+<i>dcerpc_mapiproxy:modules</i>.
+
+\code
+	dcerpc_mapiproxy:modules = downgrade,pack
+\endcode
+
+<br/>
+
+
+<a name="mod_cache"></a><h3> 6.3. Cache Module </h3>
+
+The <strong>cache</strong> module implements a cache mechanism for
+streams related to messages or attachments. This module reduces
+communication latency between MAPI clients (using <i>online</i> mode)
+and Exchange. When configured with online mode, MAPI clients retrieve
+data from Exchange each time they access a message and don't have any
+offline storage mechanisms enabled - data are downloaded and stored
+within a <i>temporary files</i> folder. This module also offers a
+preliminary synchronization mechanism which can be used to transfer
+files between different MAPIProxy instances and use different
+protocols than MAPI for data transfer (such as rsync or wget).
+
+The cache module is designed to cover different cases:
+
+<h4>Scenario 1: Replay attachments</h4>
+
+This scenario only requires a single MAPIProxy instance and requires a
+single configuration option:
+\code
+	mpm_cache:path = /tmp/cache
+\endcode
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mpm_cache_case_one.png" />
+</td>
+</tr>
+</table>
+<center> Figure 8. Replay stream scenario </center>
+
+<ul>
+
+ <li style="text-align:justify;"><strong>1. Outlook reads a stream for the first time</strong>:<br/>
+ MAPIProxy monitors the Outlook-Exchange traffic and store the
+ attachment on the local filesystem. </li>
+
+ <li style="text-align:justify;"><strong>2. Outlook requests this stream again</strong>:<br/>
+ MAPIProxy looks over its cache, find the requested stream and
+directly communicate with Outlook without forwarding requests to the
+remote server.</li>
+
+</ul><br/>
+
+<h4>Scenario 2: Read stream ahead</h4>
+
+This scenario requires two MAPIProxy instances and requires different
+configuration options for local and remote MAPIProxy:
+
+<ul>
+<li><strong>local MAPIProxy smb.conf sample</strong>:<br/>
+\code
+	mpm_cache:path = /tmp/cache
+	mpm_cache:ahead = false
+	mpm_cache:sync = true
+	mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy at 192.168.102.2:__FILE__  __FILE__
+\endcode
+</li>
+
+<li><strong>remote MAPIProxy smb.conf sample</strong>:<br/>
+\code
+	mpm_cache:path = /tmp/cache
+	mpm_cache:ahead = true
+	mpm_cache:sync = false
+\endcode
+</li>
+
+</ul>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mpm_cache_case_two.png" />
+</td>
+</tr>
+</table>
+<center> Figure 9. Read ahead scenario with synchronization mechanism </center>
+
+<ul>
+
+<li style="text-align:justify;"><strong>This scenario uses 2 MAPIProxy instances</strong>. We call
+<i>remote MAPIProxy</i>, the MAPIProxy instance connected to the
+Exchange server network and <i>local MAPIProxy</i> the instance
+connected to the MAPI clients network.</li>
+
+<li style="text-align:justify;"><strong>1. Outlook wants to read an attachment for the first
+time</strong>:<br/> The remote MAPIProxy monitors the first ReadStream
+request and read the full stream ahead on its own and stores it on its
+local filesystem.</li>
+
+<li style="text-align:justify;"><strong>2. remote MAPIProxy replies to local MAPIProxy and local
+MAPIProxy runs the synchronization mechanism.</strong> The current
+implementation provides a fork/execve/waitpid process which allows to
+run any command with parameters. When local MAPIProxy finishes to
+store the file locally through the synchronization mechanism, it marks
+the stream as being cached.</li>
+
+<li style="text-align:justify;"><strong>3. local MAPIProxy plays the attachment back to the client
+from cache</strong>.</li>
+
+</ul>
+
+
+The module monitors OpenMessage, OpenAttach, OpenStream, ReadStream
+and Release MAPI calls and stores streams on the local filesystem with
+indexation in a TDB database. Note that the module doesn't yet provide
+semantics needed to remove entries from the TDB database.
+
+
+This module has different configuration options and modes:
+<ul>
+ <li style="text-align:justify;"><strong>mpm_cache:path</strong><br/>
+ This option takes the full path to an existing folder on the
+ filesystem. This folder will be the storage root path for the cache
+ module and will hold the TDB store, a folder hierarchy and stream
+ files.
+
+\code
+	mpm_cache:path = /tmp/cache
+\endcode
+</li>
+
+<li style="text-align:justify;"><strong>mpm_cache:ahead</strong><br/>
+This option takes a boolean value (true or false) and defines whether
+the ahead mechanism should be enabled or not. This mode should only be
+enabled on the remote MAPIProxy instance. It can be enabled on local
+MAPIProxy instance, however there won't be any benefit but Outlook
+unexpectedly falling in some time out mode and close the connection.
+
+\code
+	mpm_cache:ahead = true
+\endcode
+</li>
+
+<li style="text-align:justify;"><strong>mpm_cache:sync</strong><br/>
+This option takes a boolean value (true or false) and defines whether
+the synchronization mechanism should be enabled or not. This mode only
+makes sense on the local MAPIProxy instance and
+<strong>mpm_cache:sync_cmd</strong> must also be configured.
+
+\code
+	mpm_cache:sync = true
+\endcode
+</li>
+
+<li
+style="text-align:justify;"><strong>mpm_cache:sync_cmd</strong><br/>
+This option takes the command line to execute for the synchronization
+process. A preliminary substitution variable mechanism is available
+but should be improved over time. For the moment, the cache module
+only provides <strong>__FILE__</strong> which will be substituted by
+the full path to the cached file. The synchronization process
+currently assumes local and remote MAPIProxy instances have the same
+storage path (<i>mpm_cache:path</i>).
+
+\code
+	mpm_cache:sync_cmd = /usr/bin/rsync -z mapiproxy at 192.168.102.2:__FILE__  __FILE__
+\endcode
+
+</li>
+
+</ul>
+
+In order to use the cache module, edit smb.conf and add <i>cache</i>
+to <i>dcerpc_mapiproxy:modules</i>.
+
+\code
+	dcerpc_mapiproxy:modules = downgrade,cache
+\endcode
+<br/>
+
+<h4>Notes</h4>
+
+<ul>
+<li style="text-align:justify;">While the cache module implements a
+preliminary <i>session</i> mechanism (multiple clients support), this
+mode is currently only implemented up to 50%. Multiple clients will
+work for files already cached, but will cause unexpected behaviors
+while synchronizing a remote file at the same moment from different
+session. This bug should be fixed when the streaming and lock
+mechanism will be implemented.</li>
+
+<li style="text-align:justify;">The synchronization mechanism is yet
+experimental and we have deliberately changed the storage path
+permissions from 0700 to 0777 for trivial setup. File permissions will
+become parametric smb.conf options in the future.</li>
+
+</ul>
+
+<br/>
+
+
+<a name="server_mode"></a><h2>7. Server Mode</h2>
+
+<a name="server_conf"></a><h3>7.1. 5-Minute Configuration</h3>
+
+This 5-Minute configuration will help you set up a preliminary
+OpenChange server. This configuration will be performed in three
+steps. Before running these commands, make sure you have followed
+<strong>step 1 (Provision Samba)</strong> and <strong>step 2 (Add a
+user account)</strong> in <a href="#minute">MAPIProxy 5-Minute
+configuration section</a>.
+
+<ul>
+
+<li><strong>[1] Provision OpenChange</strong>:<br/>From openchange
+root directory, run under the root account:
+\code
+# ./setup/openchange_provision
+\endcode
+
+This script will extends Samba4 Active Directory with Exchange classes
+and attributes needed to run OpenChange server. Note that this
+operation may require several minutes to complete.
+</li>
+
+<li><strong>[2] Create the Exchange user account</strong>:<br/>
+OpenChange <strong>does not create</strong> the user account the way
+Samba does. It only extends existing users from the SAM database and
+add attributes required to access OpenChange server. The underlying
+concept is that system administrators may want to give access to Samba
+shares to a specific user but do not want him to access OpenChange
+server.<strong>The user must have been created using <i>samba4 newuser
+script</i></strong> prior you run this command. Run under the root
+account:
+\code
+# ./setup/openchange_newuser --create <username>
+\endcode
+where username is the user account you want to give access to
+OpenChange server
+</li>
+
+<li><strong>[3] Configure OpenChange server options</strong>:<br/>
+OpenChange server only requires a very limited set of options to be
+added to <i>smb.conf</i> in order to run. Note that the following
+configuration also works with existing MAPIProxy configuration. This
+configuration will turn MAPIProxy into OpenChange server only and no
+remote connection to Exchange server will be made:
+
+\code
+[globals]
+        netbios name    = MAPIPROXY
+        workgroup       = OPENCHANGE
+        realm           = OPENCHANGE.LOCAL
+        server role     = domain controller
+
+	### 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 ###
+
+[netlogon]
+        path = /usr/local/samba/var/locks/sysvol/openchange.local/scripts
+        read only = no
+
+[sysvol]
+        path = /usr/local/samba/var/locks/sysvol
+        read only = no
+\endcode
+</li>
+</ul>
+
+<br/><br/>
+<a name="server_overview"></a><h3>7.2. General Overview</h3>
+
+Although <a href="#purpose">section 1.1</a> only describes MAPIProxy
+as a proxy, recent work makes it possible to turn MAPIProxy either into a
+<strong>complete and real stand-alone server</strong> or server/proxy
+hybrid.
+
+MAPIProxy behaviour is controlled through the <i>dcerpc_mapiproxy:server</i>
+parametric option. To use MAPIProxy as an independent server, set
+
+\code
+	dcerpc_mapiproxy:server = true
+\endcode
+
+<ul>
+  <li style="text-align:justify"><strong>dcerpc_mapiproxy:server = true</strong><br/>
+  When this parametric option is set to true, MAPIProxy will not initiate
+  connections to a remote server, but instead will direct client connections to
+  its own default NSPI, RFR and EMSMDB servers and work as a
+  stand-alone server.<br/>
+  </li>
+
+  <li style="text-align:justify"><strong>dcerpc_mapiproxy:server = false</strong><br/>
+  If this option is unset or set to false (default behavior),
+  MAPIProxy will work in proxy mode only and initiates a connection to
+  a remote server using the binding/credentials configuration as
+  specified in <a href="#minute">section 3.1</a> (5-Minute
+  Configuration).
+  </li>
+</ul>
+<br/>
+
+In addition to the server mode described above, MAPIProxy provides an
+additional set of configuration options which makes possible to
+override and customize MAPIProxy behavior. The server mode has been
+designed to supply a modular mechanism somewhat similar to the modules
+one described in <a href="#mod_dev">section 5</a>. While MAPIProxy
+modules are stackable and can be chained, server modules only
+support a single module for a given endpoint:
+<ul>
+
+  <li style="text-align:justify">When dcerpc_mapiproxy:server is set
+  to true, MAPIProxy registers dynamic shared object stored at a
+  specific location (modules/dcerpc_mapiproxy_servers) and load server
+  modules tagged with the <strong>MAPIPROXY_DEFAULT</strong>
+  status. For each of the endpoints MAPIProxy can handle
+  (exchange_nsp, exchange_emsmdb, exchange_ds_rfr), the associated
+  default server will be loaded. These default servers are located
+  within mapiproxy/servers/modules. (Figure 10.)<br/>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="dcerpc_mapiproxy_server_true.png"/>
+</td>
+</tr>
+</table>
+<center>Figure 10. Server mode enabled</center>
+</li>
+
+  <li style="text-align:justify">When dcerpc_mapiproxy:server is set
+to false, MAPIProxy still registers server dynamic shared objects but
+does not load any of them, which means that ExchangeRPC traffic will be
+relayed to remote server.</li> 
+</ul>
+
+However there may be some cases where developers would like to run a
+custom server they have developed, or handle a limited set of
+ExchangeRPC traffic on their own for a given endpoint. This
+configuration is made possible through 3 parametric options:
+
+\code
+	dcerpc_mapiproxy:nspi_server   = nspi_server
+	dcerpc_mapiproxy:emsmdb_server = emsmdb_server
+	dcerpc_mapiproxy:rfr_server    = exchange_ds_rfr
+\endcode
+
+Each of these options specifies the server module name to be loaded
+for a given endpoint. Note that these options override the
+dcerpc_mapiproxy:server state:
+<ul>
+
+  <li style="text-align:justify">If dcerpc_mapiproxy:server is set to
+  true, specifying one or all of these options will override default
+  servers with your own custom servers. For example Figure 11 shows a
+  mapiproxy configuration where server mode is enabled but where the
+  NSPI server has been replaced with a custom one.
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="dcerpc_mapiproxy_server_true_custom_nspi.png"/>
+</td>
+</tr>
+</table>
+<center>Figure 11. Server mode enabled but custom NSPI server loaded</center>
+</li>
+
+  <li style="text-align:justify">If dcerpc_mapiproxy:server is set to
+false, specifying one or all of these options will force MAPIProxy to
+relay the associated traffic to default or custom server. For example,
+Figure 12 shows a mapiproxy configuration where NSPI traffic is
+handled by OpenChange NSPI server while EMSMDB and RFR traffic is
+relayed to the remote server.
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="dcerpc_mapiproxy_server_false_nspi.png"/>
+</td>
+</tr>
+</table>
+<center>Figure 12. Server mode disabled but NSPI server loaded</center>
+</li> </ul>
+
+<br/>
+
+<a name="faq"></a><h2>8. Frequently Asked Questions</h2>
+<a name="notcompleted"></a><h3>8.1. The action could not be completed</h3>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_error_001.png"/>
+</td>
+</tr>
+</table>
+<center>Figure 13. Outlook error: The action could not be completed</center>
+
+If you have followed the <a href="#minute">5-Minute Configuration</a>
+instructions and the above error message box (Figure 13) is displayed
+each time you click the <i>Check Name</i> button, then you need to:
+<ul>
+<li>Click on <strong>More Settings</strong></li>
+<li>Open the security Tab</li>
+<li>Tick the <strong>Always prompt for username and password</strong>
+checkbox in the User Configuration section (Figure 14)</li>
+</ul>
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_error_001_fix.png" />
+</td>
+</tr>
+</table>
+<center>Figure 14. Resolution: Always prompt for username and password</center>
+
+Next time you click on <i>Check Name</i>, Outlook will prompt for
+username and password. A similar credentials dialog will be displayed
+each time Outlook is launched.
+
+<br/>
+
+<a name="cantopen"></a><h3>8.2. Profile creation goes fine, but Outlook can't open your default e-mail folders</h3>
+
+The profile was properly created using the mail applet from the
+configuration panel (or using Outlook wizard). However when I launch
+Outlook, I keep having the following error message:
+
+<table style="clear:both; margin: 0.5em auto; width:80%; text-align: center; background-color:#ffffff; border:2px solid #e0e0e0; padding:5px;">
+<tr style="border:none;">
+<td style="border:none;">
+<img src="mapiproxy_error_002.png"/>
+</td>
+</tr>
+</table>
+<center>Figure 15. Outlook error: Unable to Open your default e-mail folders</center>
+
+This probably means Outlook is unable to lookup the resolved name of
+your MAPIProxy/samba4 server. You can either:
+<ul>
+  <li>1. Make your Windows workstation points to a domain name server
+  able to resolve MAPIProxy fully qualified name.</li>
+
+  <li>2. Open \code C:\WINDOWS\system32\etc\drivers\hosts \endcode file and
+  add an entry for mapiproxy. For example if I have
+  mapiproxy.openchange.local pointing at 192.168.102.2, then hosts
+  file should hold the following line:
+  \code
+  192.168.102.2 mapiproxy.openchange.local mapiproxy
+  \endcode
+  </li>
+</ul>
+
+<br/>
+
+<a name="dc"></a><h3>8.3. Does MAPIProxy need to be domain controller?</h3>
+
+No it doesn't. MAPIProxy works fine as a member server of a Windows
+domain. However, since delegated credentials and forwarded kerberos
+credentials don't yet work, you'll need to force samba to rely on the
+local SAM database. To force this behavior, add to smb.conf within the
+global section:
+
+\code
+	server role               = member server
+	aux_methods:member server = sam
+\endcode
+
+<br/>
+
+<a name="gnutls"></a><h3>8.4. Generating Samba's private keys takes infinite time</h3>
+
+For some configuration, the private keys generation process at Samba
+startup can be very long. In case private keys are not generated
+within a couple of minutes, it is suggested to recompile Samba with
+gnutls disabled as in the example below:
+
+\code
+	$ ./configure.developer --enable-debug --disable-gnutls
+	$ gmake idl_full
+	$ gmake
+	$ sudo gmake install
+\endcode
+
+<br/>
+
+<a name="gmake"></a><h3>8.5. On Ubuntu <i>make samba-git</i> exits with <i>gmake: not found</i></h3>
+
+On Ubuntu, I have the following output while trying to install samba4 from OpenChange sources:
+
+\code
+	To build Samba, run /usr/bin/make
+	Step2: Compile Samba4 (IDL)
+	./script/installsamba4.sh: 332: gmake: not found
+	Step3: Compile Samba4 (Source)
+	./script/installsamba4.sh: 332: gmake: not found
+	Error in Step3 (error code 127)
+\endcode
+
+gmake is make on Ubuntu. Creating the following symbolic link will fix
+the issue:
+
+\code
+	$ sudo ln -s /usr/bin/make /usr/bin/gmake
+\endcode
+
+*/

Added: trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_false_nspi.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_false_nspi.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_false_nspi.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,116 @@
+‰PNG
+
+   
+IHDR  X     Ùíüg   sBITÛáOà   	pHYs        êe¤    IDATxœíÝw\S×ûð'–!ˆ²Ä­àÖ¨¨¸q (â®ý"ŠÅªTk­£íÐV­«Ö…q!Š *â¸Ø(È’=d¯@BB ÷÷Çý~ó£€€zŸ÷¾âåäÜ—OÎIî¹,Š¢ !„b*9ÒB!’°~™X,Ö‚H§h‘Ï(ê'·yóf‹•žž^ïKL>,µ16é ¨½¨­­•——oûýfee©¨¨4Û¬íã½ï? áFŽyæÌ}}ý÷L‡údpDøåïÕ«—ŠŠÊªU«d“’’Ə¯¤¤¤¥¥åëë›””dmm­¤¤¤§§·oß> `±XÆ
+³°°°¶¶¦ÿ;|øðAƒ)**Ν;·ªªª^õv*{ºššÚŽ;fÏž­¨¨hccSSS û÷ï×ÕÕe³Ù&&&ÞÞލößµkW—F¿T/^bbâ¸qã”””´µµW¯^-‘HNœ8!''túôi999“:Š¢ŒçÍ›ÿZmÞ¼YSS“ÃátïÞ===½áѨ»G6›­¯¯/•JE"‘††ÆÊ•+éãÙôl9‹%‰‚‚‚ŒŒŒ:Tï@É´$3Bè£PèKaiiÙ¹sçððð#GŽ Àüùó)Š2dˆ––Öƒ^½zõúõë!C†DFFîÚµ <x  ZZZOž<INN¦(
+ :wîFwòÇÔë¡ÞN K—.QQQƒ
+€3gÎlß¾ (ŠzüøqdddBB—Ëíܹs£ýË¢6ü½QoȐ!tƒcÇŽÀÞ½{)Šrpp044TWWß°aÃëׯàÔ©SÏŸ?€[·nQ•••U\\L§UVVvttLLL¼uëVaaaãQwÿüó Ü»wÏËË BBBèãÙô”Qm Þ¡ËÊÊ [[Û¬¬¬F}XZ’!ô1°~9Ølö¬Y³(Š¢ÇRôŸQ6›=sæ̺mäååUUU•••à×_ ;;;Y ¨ÛÉÒ¥KëõP ̝;—¢¨ùóç@MMÍÕ«WàÒ¥KEíÛ·ÏÔÔT]]ÍfÓ¯ºö_·Öû½QÍfÏž=»^ƒøøx àp8tµ?~üˆ#Ö¯_o``PSSS/íÞ½{ÍÍ͇ž””ÔðhÔÝcmm­±±ñ²eËlmmû÷ïßÂ(ó¦Fý½7z è/µ$3Bècà{„_Ž¾}û†„„DDD„„„È6ZZZ>}úôÑ£G;vd±X–––¹¹¹ìСC||üرc·mÛÆápêöF÷Y¯‡¾}ûÖÛ/ý·›&{“Œ¢( ضm[ß¾}:´eË–˜˜˜Fûob×ôFY<KKË/^„‡‡GDD €………T*uqqéÑ£Gii©««ë¹sçÖ¬Ycgg—ðÍ7ßÐa²³³UTT´µµÀÄÄäæÍ›………£G¾zõjãQwrrrŽŽŽ{öì©®®Þ³g,C³Ö¯_¿z[D"Qã?¹w(Z3#„>éJŒ>™ÐÐÐ=z())9::ÂÿÆqqqcÆŒQTTìСÕ+Wèw˜”••é†¬%
+ FŒ1dȇcgg'
+ëõPo§²§Ó#BŠ¢èáÅ‹)ŠÚ´i“ŠŠJŸ>}Əÿ«Žõú‡:#Âz_ªÛ?ý½XYYq8MMMggg±X¼cÇ…ðððëׯÀÙ³gkjjŒ ))©^BŠ¢&Ož¬ªªÊf³‡šœœÜðhÔkŸ••%''§¨¨(›\mö ʼ׈°ÑE©%™BƒEáõ¨‹5þüK—.µ}ÿŸd×b±xæÌ™"‘èñãÇÓBˆ9ðS£èý(Õ±qãFÒqêSRRJHHÍd"„P³ð=Bô/ÍÎÄÆÆÊkjj~Âþ?ÉäÎp „ÞN"„b4œE!ÄhXB1Â/Óg´dsûÚþ~˜/õûBè}á‡eÐá¢ÛïÒ„Mkƒ%¼BG„_\t»ÙE·Y,ÖСC---UTTd+V×[Õº‰„õÔ{"4¹$wk/á]¯«zGæÖ­[
+O HKK0`@Ý£Ñ菬áA“l...ônv5ð†ý4<€žµ:‚ó£OÝnvÑmz‘‘‘ƒ
+ÒÖÖ¦7Ö[Õº‰„õÔ{"Õä’Ü­½„wîêY›º?ÊFÆ»~dõšYXXèéé………>|˜>>ͮްŸ†°Ñs ¡Ö†…ðˁ‹nSÍ-º-Këàà {XoUë&ÖSï‰MÞÖ^»aWõŽLÓ¡Ñ£Ñ菬a³†'[³«7ì§álô@¨µá{„_\t»ÙE·eiY,–l§õVµn:a]õžøÃ?4qx[{	ïz]YYYÕ;2Ðàdhôh4ú#kجáÉÖ’ÕÀëõÓð ¶üà#ô)‘®Äè“ÁE·›]t»aZªÁªÖM$¬§Þ©æ–änÕ%¼ëuµdÉ’zG¦áÉÐèÑhbùïºÍè“MYYyùòå °hÑ¢fWoØOÃØè9€PkÃBˆþå]ˆÛ ÿO²k‘H4iÒ$++«À—!66666¶¬¬Œ~3oÏž=Ÿ¤[<øˆüÔ(z?L^t»ïm)55uܸqÚÚÚ;wîtuu]»vm½x¬Ðg×E<¤ijjêèèÓƘü½¿/<Vè3‚…!„£áÔ(B!FÃBˆBˆÑ°"„b4,„!„
+!B!FÃBˆBˆÑ°"„b4,„!„
+!B!FÃBˆBˆÑ°"„b4,„!„
+!B!FÃBˆBˆÑ°"„b4,„!„
+!B!FÃBˆBˆÑ°"„b4,„!„Y…ðîÝ»\.7>>þÕ«W\.7((¨  €ËåzzzÀ¨Q£öíÛ ööö7n€o¿ývÉ’% ðÛo¿M˜0 x<—Ëåóù·nÝâr¹IIIQQQ\.÷Ñ£G¹¹¹\.×ËË ¸\î ÀÎÎnÓ¦M àââ²lÙ2 عsçäÉ“àäÉ“\.W ܸqƒËå&''‡‡‡s¹Ü'Ožäääp¹\ooïÚÚZ.—{øða °µµÝ²e 8;;;::€›››
+ ;vŒËåŠD¢ëׯs¹Ü´´´.—ûüùóÌÌL.—ëëë+‘H¸\î‘#G `ÆŒ?ýô 899999ÀO?ý4cÆ 8rä—Ë•H$¾¾¾\.733óùóç\.7$$$--Ëå^¿~]$q¹ÜcÇŽ€›› 8:::;;À–-[lmmàðáÃ\.·¶¶ÖÛÛ›Ëåæää<yò„Ë冇‡'''s¹Ü7n.—{òäI ˜<yòΝ;`Ù²e... °iÓ&;;; 8pà —Ë ///.—›››ûèÑ#.—•””ÄåroݺÅçó¹\.Ç€	&üöÛo °dÉ’o¿ý 6nÜhoo ûöí5j xzzr¹Ü‚‚‚   .—ûêÕ«øøx.—{÷îݲ²2.—{æÌ °¶¶Þ½{7 ,\¸pݺu °~ýúùóçÀž={ÆŒ çÏŸçr¹ÅÅÅ\.766666–Ëås¹ÜóçÏÀ˜1cöìÙ óçÏ_¿~= ¬[·náÂ… °{÷nkkk 8sæ—Ë-++Ãsµ
+ÎU„hlÒÚNJJÊÔ©S;ëDÄ%ÕÔÔðÂØäôJ©<_ LLÏ
+ŽŒ©ÓßæGÆ•–+¨GÆä–TVòƒ#c2róË+Á‘1o2søá³—q¯SÒùax\’¨ªŠ/¾z“Z*®å„	iYÁ‘1|05;782¦¸œŸ_“[X\UU“™WPVQùÿ]E¿ŽKͤ»ªäóù᫤ÔÂJ1_ LHÏzËS²sƒ#cJÊ+²òƒ#còŠJjjjèT¥üÊàȘ”ì\¾@ø4:6.5ƒ/†½N,+-å„/SrJ+øa|j¦VT¬,UIyEfnApdL~q) GÆdæ””WGƤfçòÂ'Q±ñ©™|046¡¨ €/¾LJÕ,,å„q©jÑÿŸª”_™‘›OwÅf³ƒ#c²òé®Rþ×UBz_ IÈ}›Ã£’Õ:tà„q©™JÚ¯ùá›ÌœàȘ²ŠÊ̼ÿ¦RŠ‚#c²ó‹ŠËù²TÁ‘1	iY|0$&>+3ƒ/F%$+)+óÂ×)érêÚ²®Ê+tªÂÒ²*‰482&;¿°¨´<82&ým^…@“˜žÅ_¼ŠOOMç„‘ñoØl6}VH•Ôÿ¿«
+Aú[º«ò–|pdLN~QaiypdLZN*)#›/¾x—”œFw |0&9M,¯È“2²é³"-'î
+ØŠÁ‘1o‹Kÿ›*¿¼âÿO°ç/ãâ’Óù!ž«­w®~»~ã‘ý{³²²
+
+	ÿmB¤±(Š"¡¹¬ûnìø‰‘΂",*<ìÉ£'ŽÖÔÔ$Æ B Á‘1¤# „Ú«AýIG@ä1è=ÂŒŒŒy3¦Üñ÷#!Dލ«Wæ͘’››K:"A…PQQ±G¯ÞšZZ¤ƒ „ÈÓÒÖîÑ«7‡Ã!‘‡S£!æ©QŒ¾}ûví
+ÇÇA¤ƒ „Ⱥwwí
+ÇÂÂBÒAy*„R©T ¨¬©©!!D^MD ¨”J¥¤ƒ òpj!Ä\85Š€Q#‚‚‚ß~Þú‚t„y!ÏžüöóÖ’’ÒAy*„B¡ðyðãÜœÒABä½ÍÎ~üX$‘‚ÈéQ„sáÔ(FKJJN=‹µ!1/£O=ÂçóIAä1¨–––žu?žK:Bˆ¼¸˜Wgݏc!DÀ¨©Q©Tzïi(‡ÃQPP !D˜D"©®®ž2z8‹Å"Æ ¡@ xx?'+‹t„yÙ™ï…BÒAy*„»wüB:Bˆ¼ÐçÏvïø¹´´”tDƒ¦F«««/^ó×ÑÕí ·CˆéÊËÊŠ‹
+ÙÍÄ÷JƒF„µµµ¥%%b±˜t„y"QUiI	.±†€Q…ðíÛ·ß}³"øaé !òÜÿè6 6é m§K—.»÷63ïN:Bˆ¼Ñ㬻ëè萂ÈcЈPAAÁØÌL½CÒABäihh›™±Ù waP!ÌÌÌ\8kúÝ[7HA‘wóúÕ…³¦çåå‘‚È“wss#¡ÈËË‹(–åÀÁÚ;’΂"LQQÑÌÜ|ÚäI‡tDƒ.Ÿ (êQøK‹%'Ç q0B¨QR©”¢¨qC‚ÈcPIHMMµ6ðšé !ò¼==¬‡
+ÌÎÎ&‘Ç B¨©©¹`é²î={“‚"¯gŸ>–.SWW'‘Ç ©QÀû"„þ
+ïGˆ€Q#ÂŒŒŒ¹6“nù]#!DžŸ¯Ï\›I¹¹¹¤ƒ òT•””úö·èˆ×Ï"„ tttûö·ÀŒ"À©Q„“áÔ(FÂœœ›é3–|5vüDÒYÚ£Ÿ6®/)."}iŒLL7ý¼ƒtŠFÞ½íëu1ðþ=]]]ÒYaZ^ˆ¢(‰D"­­%¤JOyÃçóÍÍÍIA_ŽøøxE…vúGF*•J$æŒP4"œmÒÒ93xõêUÒAЗcôèÑb±ø¯ã<ÒAÞ	§F0êÃ2ùùù;·þöâ9é !ò^<
+Þ¹õÇ’’ÒAyítÖ¢5TUU…‡<<l8é !òòÞ¾
+y.‰Hiï|}Oòù|Ò)>„¢¢b·n݆
+³i¶%ƒ
+¡‰‰‰_À#Ò)BíÂìyógÏ›¯¯¯O:H»væ̾ššš.]ºòÞ¤R©··×¢E[Ò˜A…°¤¤äÄ‘C£¬Æöµ°$!DXLtÔó§ÁíÕÐÐ ¥:{ö¯êêê>¿uÉ¥RéÉ“Çõô:ôì9´%íôaii©Ï=1!Žt„yq±1<÷ŠŠ
+ÒAÚ©³gÿ‹ÅŸoÔÖVæpZ:ÒcЈÐÌÌìÞÓPÒABäÍ]°h–½ƒé íÑÙ³‰D¢’òÞ> 
+£F„÷oùgf¤“‚"/#-õþ-¡PH:H»sîÜþÏ·
+º»ŸÐÒRz¯*Œ*„………{~ÛJ:E555¤S Ô^„‡¼ØóÛÎÒÒRÒAÚ—sçö…ÂÏ·
+jj***¾÷´ƒ¦F»vízÎûš¶NGÒAÈP×ÐpZ<Êô³íç+«¨Žƒa63m‡­§§G:H;rþü¡P8hÐ ÒAÞÛÇTA`Ôˆ°¦¦¦° ¿Š©3!ŠŠŠÓgÙ=¸ßaæÔ‹çNÀqÐÑÑÙ¾};ý¸W¯^ôƒÀÀÀ#FŒ3fèСÿüó tîÜyܸq¸ÿ> ´ñšmÕÕÕ3f̨ý …ôÚÛòrR©ÔÖÖ¶ººšt/“P ,,Èÿ°Så‹tþü@ð9WA¥«‚À¨annî†Õή›6ÏqhÑ•%_Û¹óÎóÜËJKŽÜáoñ׎ï5:TWW÷÷÷ÿþûïëÞÔ{Íš5< _VÓ³Ljjj>LOOŸ7oÞ¤I“>,ªT*•“ké«´º/^¼8sæLyyùÛo»"''7cÆGGGÒY¾@‚Žìßë`;ÍÐАtòJJŠâââ´´´>|H:Ë{ËÌÌÐÐPTTüðrÆ BØ¥K—=‡ÿ11íF:1ŠŠŠKïû *øü÷-‡òòòNNNGýá‡d555ïÝ»7kÖ¬:hiiɶ›˜˜”••5ìä÷ß÷ññÑÐа²²úú믝«ªª(Š:~üx¿~ý ÀÌÌlòäɯ^½:tè˜1cæΝ+‘Hàëëûí·ß¾«ñ£GèÏ_¾|ùøñ㠐ššZ·óŠŠŠŸþùîÝ»>>>7oÞ<{ölRR’“““T*åp8rrrE¹¸¸<~üxÅŠêêêçÏŸÏÏÏwssspp ÃwëÖmÊ”)tƒuëÖÅÄÄ8::*))õïß?   ))©ÞNéuÕíA ÈÅΝ;é¯ÚØؼ|ù²ººúÌ™3½{÷ž>}úòå˱¶†1ã'˜˜™éà
+J @"‘véÖ͘t‘‘‘ö1Uµè¶D"¹ìG[»£ZMÛ(/+ó<Û.Ö®­­õ»â-‹éŸ;‹Å¢(ªƒ†Æâ¯o^½2hР&Ý677ýúõˆ#ž?>`À€„„ HOOßµkWpp°ššÚßÿ=lØ0ssóäääèèè5kÖÓÿ•ubffª££#•J§M›¶{÷¥-_¾<(( tuuƒ‚‚ú÷ï»eË?????¿   „„„&ËúïÙ³gbb" L:µ^û?ÿü399ùåË—AAAªªª&Lpss³²²’
+(uuu#""´µµ‡¥¬¬\TT4~üøW¯^ѝ×m`mm½{÷îáLJ††NŸ>½°°°áNëú=TWWË@GGÇßßĈ!!![¶l	€=z$%%}’Ÿ~ÛkÏ‹nóùåe¥¥ógÚ°Ù¼K~~®Ï±Ï´Þ¸qGCƒÍb±~ÉÉi›©iïf{`А™™¹dŽ-‘©Ñ
+>ÿâ¹3m¼Ó&ÈκòËË/œá)¶àVÝŠŠŠK–,qww—m111¡G`‘‘‘ŽŽŽÑÑÑ•••ãƍ“J¥û÷ïoØÃéÓ§7nÜ(‹—.]ëêêJo—}Š]MM.lýúõ+,,,((8wîܶmÛf̘ÑDã†vîââb``ð×_©ªª@JJŠ•• ȦU;tè`ddD?¾råÊñãÇååå‹Šþÿu @ZZÚðáÃ`Ø°a***î´žº=Ô=666  ¤¤4bÄ >|xFFF£ßúTnû]?²ïج,œE*„ººº¶üd1€ØÇ‚×ý°yÖÜy¤öNKŒsùÏÒºÃAM-í¥ŽN¶sç9-´oI«V­²²²’]‰‘””Ô£G èÒ¥ý¹ú=Âw=}Ø°acÇŽ½{÷>tèPïÞ½@"‘Ð
+ê¾½·xñâ#GŽdgg0 ÙÆ4ssóììlCCÆí×®]»{÷î£GÚÚÚêêêvëÖíéÓ§£F’
+È꾢ܾ}ûË—/E"QÝB[ï%§±±qXXØСCÃÃÃé²×hȺêöP÷P¤¤¤ €H$
+
+
+6lXxx8]/srrLMMßu0ÑÇ<lø†-?՝ÏGŒÅ B¨®®>mæ,yrÓ r,ñI˜sî'(Š¢K †¦][ÞƒªªªÝÁƒéÿþþûï			G"‘8p Ù§Ï;W(ŠÅâÕ«WÏž=ÛÅÅE(ÊËˏ;ÖÍÍ­^ãE‹uíÚõ·ß~€ãǏ7ݘ6oÞ¼›7o:;;×konnÎáp¾ùæ›^½z}ýõ×þþþGŽqrr EEÅû÷ï×ûlŽ½½ý¸q㬦¦ö®ïåСCË—/WVVîÓ§½^eC6<ô
+
+3gÎlØ°A,Ÿ>} nÞ¼){‡}ZfæݍMLUðR"Ĩ÷SRRÌÍ͉Lfgf.²›ñݦ-vÚx×u%ƽ^ùÕ¢º£Àº%ð˸1ouuõœ9süüüZþ¡Ó&‘HèOè„……mØ°áñãÇÙa½÷S¥RéìÙ³½½½ßë•J»Òžß#ôò8wdÿÞ,œ€¿G¨¢¢Íbq(Jú	û¯ª¦¥%˜˜´Ê¡Æ÷߃¦¦æ¢eŽ=z5P¾T§OÕÒÖ^üõò÷~F8Ž¿¿Ûì+$$äǤ(J"‘=z´ÞWKJJæÌ™#ûï¤I“¶nÝú^ýËÉÉùùù}‚ ¨1½ûö[´ÌQ½Í?:×þÕÖR,–XEEéö©¤¤ž’ò)+ë§Å BرcÇUk]I§ ¦¨ `ð°;ÿÜÇá|™%°í=úÉ“'ïúª¶¶öû^’Uw8ˆZ›ÅÀAá=˜0je™ôôôÙ“Çßò»F:::Í[´« B´ëW¼gOŸ››K:"A…PYYyàà!:ºHA‘§ÛIoàà!_ê{è½0hjTOOoû®?I§@µ#­ÆŒ´£­­M:"A#ÂœœœU_/ypt„ywn­úzIAAé ˆ<ÿ«±Ø"„jH^ž­¡¡ûaÏ•JkËÊ>×*„ÇÎxNj&N6qê´NðCM©­­))ùò?OÄ ©Ñüü|·ÍCŸ?#!DÞ³àÇn›7–””‚ÈcP!¬ªªzYTøyÕB­ª° ÿed¤X,&‘Ç ©Q“«wI§h×rss?÷%ÖP»RRRBß룚5wÞ¬¹óºtéB:"A…°¸¸øèÁýVÖÖý,ÎÒN…„„Ô]¡7dÈÒ÷22âYðc‹CûqqÄ BXVVvñÜi½.±6jóÎß««qš}b**ítD˜÷úâ¹Óþ¶a=µµ >åZ£íƒ
+¡™™Yàóp‚·ajçúôkü·}‘æ-Z2Çaé íŽX\õæM"§wê~/55Ü¡³`PU¨¨¨¸éwÍbÀ@3ó „KM~ûêå°~=›¸å$3ÉË×öêeN:E›bЧFÿÚõktd8é !ò"BCþÚõkYYé ˆ<ŒŒ.\½¡¥…K"„`šíì‘cÆvîÜ™tDƒF„‰$'+SPYI:Bˆ¼ÊÊŠœ¬ÌššÒAy*„¹¹¹?¬]ý4ø!é !òþ°vuQQé ˆ<MvéÒeß‘ãF&&¤ƒ „È7a’™ywÒAy²ÙlÝNzÊ**¤ƒ „ÈSVQÖí¤'//O:"A…0++ë«y³îÜ"!DÞí~_Í›ŸŸO:"AS£ººº·mïg‰ËÊ „`Èð·m×ÒÒ"‘Ǥ3|ÊÊÊrrM
+pÕÕÕ'MÆVPh³H¡vËØÔÌÀ°«
+¾W‚ Ø_̪
+‰‰‰=zôh¢AjjêäÑÃ]7mžã°°ÍR!„Ú§+—<ìß›••ehhH:"Œ
+ Æ
+›4ié$.""âΝ;Í6ÓÒÒZ긢Wï¾m	!ÔÎõéשã
+uuuÒAyl 9r䯿þJ:ɇ;zôhK
+¡¶¶öŠÕkÚ B¨ýë?``ÿñÖõ©ÑôôtÛ‰cý¯ù’‚"ïš·—íıoß¾%‘Ç B¨¢¢2tÄH½ÎxCj„tÖ×:b¤’ƒîº‡Þ…A—OtêÔé§_w‘NjFŒ²1ÊJ[WáGL*„ÙÙÙ+–.\ôÕ×Ö“¦ÎҮ͞dmdjJ?výa³™y÷™ÆLž6c͆ àøáþ×|o>€ˆÐ“G±ªÅbÛÙ¼cGmFwÈVMM͘ñ/e±XôFŠ¢„ÁV~3zœµ,€Ï¥ö7›óä‘CQá–.‹ñÄ›q    IDATŽ[¸ì?Á‚¶îü­5Ž	úòÜ»uÓû¢ÇãA:u"Æ BÈb±8Ž®¨Ôe•C'xu·¨©©§¥$SÅb±ãã444éíþÜuèÄ)-íŽ PÁç_ö8×h3Y‡‰ä¯]¿^¾pnþ’e²e¥¥ß._V·^¹èY¯J¥Ò†‰>¸çyÕ N9|Þç Œ±žðIú’ɳå9‹Å"‘Ç Bh``päÔYÒ)>Wý,ľŠ–cÉõé׿ /Þ¨¦®úüÙèqÖªªjê:¼«™Œ‚‚‚‹ë×UNó—,“m*Uë\ÌzóšoaAÁÚ•ŽÃGŽZüõòù¶6CGŒLy“d3Ã6ð’bGço¬'M9~ø`A^þÚ•Ž ÷6‡~™ž~í^PVFÆ¿l§¤[AaÿÑM/³€kÂä©&OÕÕÕ%‘Ç B˜ŸŸÿÓÆõ3ìæ9št–v­J(¤ë
+ üºw‡ 0aÊÔë>Þ 0sÎ܇÷é¯nÿíÓî§O)«¨|·iË»šÕ¥Þ¡ƒX$’íE"‘¤&¿qÛõ§¬ÁôÙs<NŸ’
+I…Á‡fæÝÅb±íÜyåee뜗[Ošâ¼fÝÀ{t³%sle `ß®_V®^k1pP£ãH„hO?¼sÃïÊåK;v$Æ B(‰âbcFŽK:H{×pj ŒMÍ23Ò¤R©i7sÙÆÎúúßoý ’âwïøù]Íꪬ¨PRV®»—ìÌÌ_ÚÌ=æ]aÌÌ»À£Àû~W¼åäåËËÊšÎÿ6;Ûbà  À*ˆšPRTS]]M:H{Q]-©ª‘Nñ!jjj?²–1¨_¹ÝȵÐÔ³¤ÒÚº[²22º@GÚÚÚw5“©©©9zð¯I6ÓënTïС²¢¢îŠ¢dååþûž.ïØ?§/ùTWW/s˜ÓtN}CØ—Qý-âˆ5aæû™sì»tÁë©þ+4ôU@ÀsÒ)>DYYéر}>¦Ââââ#û÷Ž?±?Þ€¢Iu§F\ÖXH?ž8Õ¦^Ë󼓙éil…ÚššµßoÚûÛÎF›Ñ²Xr5ɘñã/•m¤(JTUõë†ºí‡õÃZîè1vdÇMœ´v¥cÏÞ}š½£äú·þ±Ó
+ 8
+ýƒï¢ÆEG†?}ôÐâïC¸¸Ë(‘ԐNñ!ÂÂ"?² ¸ººîß¿ÿãÓ°X¬ùóç_ºt©Þã–pssëׯŸ½½ýì÷èÑ£...Í.º’’bnnNdÑíìÌÌEv3¾Û´¥î_v„A^瘰èvxxxppðªU«”••›h–ŸŸëãs¬[7ã6ö	ݸqGCƒÝ耝œ¶™šön¶‡Öz±œ••õÏ?ÿ´¼ýŽ;|||Z)­[·nâíæa)BÃâ¥â¿ì* C†¹xñ¢©©éþýû…B!é8íÔG¤¤¤ñãÇ+))iiiùúþk
+Ï®]»º¸¸Ðm¬­­•””ôôôöíÛ ,kèС–––***²- àååÕª×ô”——_õöJM~Óz»@}.’“¯z{UVV’Òê¶oßžŸŸ¿~ýz,‡ú¨B¸xñâèèè;wî<~ü¸W¯^ïjóæÍ›çÏŸ÷ÝwßÿýÇ ;;ûÌ™3½{÷þý÷ß ++ lmmé­¤¨¨èàŸ»^FE´Þ.BŸ‹È°Ðƒî*kîCÈ_€éÓ§< ŠŠŠ°6ê£>,mcc3nܸ¦ÛPeee%•JàéÓ§ 0jÔ¨š››GFF =;¡¬¬ÜªÓFFF¯ßÔÔÔj½]¼‹ìʹ²ÒÒ¶ß;B¨¡Ñc­-’——/,,$¥Õ­_¿~ñâÅô籋‹‹×¯_¿k׮͛7;;;«4÷é3&ø¨BhiiùôéÓGuìØñ]³š–––¹¹¹ìСC||üرc·mÛÆf³á3¢4…ÂÂÂÜÜÜþ4sÿþý›Y­­­e±XÐæ‹*ÕÖÔ À±ÃŽ>ÐÆ»F5Á™t€¶Äb±(Š¢Ç$………ëׯÿå—_|}}›Ì0ÁGÂóçϯZµjÊ”)ŠŠŠ§OŸn´Í…¾ù曥K—²X,‹iÓ¦5Ú쫯¾:sæÌСC³³³?,ŒD"i¶Í/P#´º šºú¢¯þCdסz^EG½x¼iÓ¦:ÎÒêÊÊÊöíÛG—@ “““J¥½{÷vss3¦ñµ,å£
+aïÞ½=z$ûoÝë e{öìT÷Y²/]ºtIv}…»»»»»ûÇ„IHHhúò‰ªªªç<»ëvÒû˜}˜µ+‚Ê%ŽNm¿k„PCùy¹9YY«¾^¢¨¨H:K«[µj]éسgO777{{{¼Ê–Æ êååå545™pÒ#„š¥¨¨¤¡©É„J™™ÉãýwÑD,bбÈÊÊúÏû€»·IA‘w÷æÿ,°ÏÏÏ'¤ÕýþûOŸ>^^^±±±XëaЈ°S§N?nßÙ·¿é !ò†qGªwØ©¥Eàcäm)33344ÔËËGM`P!TUU;a‡Ã!!Dž¡‘q§Î]š^xì •J#""ðþÃMcЄ´´4›1ÜW[w!7„ÐgÁ×ë¢ÍîÛ·oIi]&&&X›Å B¨¥¥µl…s¯>ýHA‘××ÂbÙ
+g&\;šÅ ©Qmmíå«V“NjúYèg1 !FÓÒÒ¦[¾qõ
+é !ò|/_œn=ú‹ŸE-Á B¨ªª:j̸.¤ƒ „È3045fœ’’é ˆ<MvêÔiËŽ_I§@µÃGŽ>r”¶¶6é ˆ<³³³—/r¼w‡t„y÷nù/_äÀ„êQ³TåääTUÕ8
+x!BØlUU5¼Æ£¦Fõõõä‘NjÆOž2~ò]]]ÒAyz5”——·uƒë‹§Á¤ƒ „È{òèÁÖ
+®ÅÅŤƒ òTÅbñ›¤¼G<B JKJÞ$%´ä>¦è‹Ç€ÄÄDÙ}?G-ifll|ù~R! 0ÓnîL»¹;w&‘Ç€Û·oß¾ýåßœ¨¨¨èÐÞ?ÆM˜d1pé,!¢ÂÂõÿçoMMMÒYaìçÏŸ“Îði5Ý ¼¼ÜçâC##,„¡¤„xŸ‹öÿ¹!b1‚t†6Ò­[·Ç¯H§@µó—|5ÉW†††¤ƒ òôa™òòroOä¤DÒABä%ÆÇy{zTVV’‚ÈcP!,**:¼ïÏWÑ‘¤ƒ „È‹Ž?¼ïϲ²2ÒAyº ÞØØØÛÿ®ºÞu!3ì掛0©K—.¤ƒ ò4"‹ÅI	ñx!B ÊJŠ“â«««IAä1¨æååmýW–A <yôpë÷¸²`ÔÔ(½Ö¨¡a3WY „˜`üä)=ûôÁµF0jDHß}‚­ @:Bˆ<¼û’aÐI@ߏ0è>®²†Âû¢ÿÇ ©ÑN:mÝù[ï¾ýHA‘7|ähM--¼C=FBUUU®Õ%%%ÒABäéhëtÄ?55š––6ÃÚÊÿš/é !ò®^öšamõöí[ÒAy*„ÚÚÚË¿YݧŸé !òúYX.ÿfu‡¸ÂbÒÔ¨––Ö2'gÒ)BíB_˾–X0jD˜––f3†ëçëC:Bˆ¼+^mÆpqj£
+¡ššÚØ	“»’‚"¯«‘ñØ	“”••IAä1hjTWW÷Çí;I§@µø#‡qGjii‘‚ÈcP!ÌÊÊúzþÜ¥ŽN¦ØÎÒ~ÍždmdjZYQ1oÑ›™³d[ @¯s—­;k´ŒÏ¥ö7»—“GEE„/Xº,>66:"lá²ÿ?¢;G¨mÜñ÷»tþì³'Ázzz¤³ ÂTåååµ´µ9ŠŠ¤ƒ´kÊ**‡Nð„BÁÊ%é"GoiºÌ•‹žu¡T*mt	«÷<¯úÀÉ#‡Ïû\€1ÖZãÛAè]”””´´µq‰5Œ*„úúúûž$âó •š{ï¤a››×|
+Ö®t>r”Ÿ¯ÏÐ#SÞ$ÙÌ°
+¼{§¤¤ØÑùëIS àøáƒyùkW:@ÞÛúAfzúµ{AYü²’Rl…ýGOà)ÔzÆMœ<nâd\t£
+a^^ޏ߭±3o¤ÕÒYÚ¯*¡pÍŠÿ$'%îؽW¶…®Uã&Lš3a£mhÓgÏñ8}Š>^:vŽÃ3óîb±Øvî¼ò²²uÎËéBè¼fÝÀ{t³%sle `ß®_V®^k1pл†’}*Á‚nú]½~ÅGGG‡tDƒ
+auuuFjjeŸtvMYEåðÉÓ1/£<Ïð†qGÂ;¦Fëµi´3óî ð(ð¾ßo9yùò²²f÷þ6;Ûbà  À*ˆZŸ_ž‘šZSSC:"A…ÐÈÈèâõ›¤S|ú[
+«ÒSSL̺½WŠ¢èòròôÞ±N_ò©®®^æ0§ÙýêƼŒêo9G„¨µMŸe7}–]çΝIAä1èoMQQс?v½ŒŒ äó0ÓnŽ¯×Å÷m3|ä¨Öº\½|I¶eÜÄIkW:ž<rHYE¥Ù®ÿq뱃V;.[ï²R*•~Xr„Z"2,ôÀ»ÊZ0Q¾x,ÙKø/^jjj=Ö~¿ÉÎaAÛï}í
+G ò”çå¶ß5B¨¡ËÎ=¸?==ÝÐАtòòós}|ŽuëfL:ȇ¸q㎆›Åb5ü’“Ó6SÓÞÍöÀ ¡™™ÙƒÐ("U!ÔÞ8,þêAhª`XXéíƒ
+aYYÙ¥ógß$&‚"/1îõ¥óg+**Hiu%%%C‡õ÷÷gÎüßûbP!,..þçÀ¾˜—Q¤ƒ „È‹ŽŒøçÀ¾òòrÒAZÝ”)SfÎœÉÀrÈbµ¨Æ1èS£ÆÆÆWnßWSS'!Džíûñ“§téÒ…t¶°}ûö©S§FDDÌœ9sРA;vì˜>}z½7ÕÒÒ2ŠŠ
+I%ü@CC£ÞFŠ¢D"¶‘Q÷–ôÀ B(‰^ǼêÞ£§Šé,!ŠŠ
+SÞ$ٌńPL™2eøðá¡¡¡EEGG7Z»w79r,Ùœ&$$45õ_—P%‘(nØ°³…Wa1¨æççÿüÃ×M›çt%S‹
+ŽìßÛ|;„PëKŒ‹ŽÏNNTWgÄ,‘¡¡aHH Ð&Õ+‡ PS#ÉÉyC8削
+ÑÐøÿZFWAW×-½éƒ
+¡ÁÞ9}RJKJ¼<ΑÚ;B¨¡'NŽ@]###·mÛÖ»wo5µæ/óý,PTWs\]·¼Ç€‡A…Åb)((ÈýoÅ“6và¸;‘ý"„UR\TŸÿÕ<;‡C:K[ظqãþýûéÇrrrR©tôèÑnnn&L €üü\¢é>
+Š‚êj…uëÜ
+MÞë‰*„ÙÙÙ+—.tÝ´yŽÃ¶ß;.†P»x÷Αý{§ÏbÂ¥„ùùùG ‹EQÔÈ‘#e%ð‹AWÁµkݺv5yßç2¨êééýüÛîž}ú’‚"oĨÑut´µµIi{öì‰D 0jÔ¨/¯ EDÂ^»v»‘‘É<A…PYYyÈpnKV¼D}ñôºèkhj)))‘Òêèá`݉Ð/X,¿nÝv##Ó{:ƒ
+azzºíı¤¦FBíÊuŸËGöïÍÊúò§F=zäçç×t	TTTªªªMNþ,ß)TQQ[¿þ—.]>üƒZt»´´ôǟ܆Žàâì(B(.6&24dï®_rùjƒ
+! GƐŽ€jG¬õ'‘Ç 2¦¦¦N5ìúoÒABäù\¼0yÔ°œœÒAy*„êêꓦÍ026!!Dž‰™Ù¤i3TðÓs§FBL†S£5"ÌÊÊújÞìû·o’‚"ïöë_Í›ŸŸO:"A…ÍfëvÒSQU%!Dž²ŠŠn'=yy2k.¢v§FBÌ…S£5"ÌÍÍݸÆåÙãG¤ƒ „È{¸qKQQé ˆ<B‰D’›“]YYI:Bˆ¼Êʊܜ욚ÒAy85Šb.œEÀ¨aaaá¾ß‰Ž'!D^xè‹}¿ÿRVVF:"A…°¢¢â֍ëéi©¤ƒ „ÈKKN¾uãº@  ‘‡S£!æ©QŒ–••yžå%ÆÇ‘‚"/þu¬çY^EEé ˆ<Ââââc‡¼ŽyI:Bˆ¼WQ‘Ç(//'‘Ç ©ÑÚÚZÿ Ç*ªjL¸'5B¨i¢ª*¡P0cü\\1hDXUU^TP@:Bˆ¼‚ü¼¨ˆp±XL:"A…0??ÇæB_<%!DÞó'Á;6ÿPRRB:"AS£"‘è¬×•ÎúúÚuHgAV\T˜Ÿ›ûŸ…ó8é,ˆ0B¡†TsrrV}½äaà}ÒABäܹ½êë%ø¡À& íèéé¹íÚÓ£WoÒABäq­ÆèvÒÓÖÖ&‘Ç B¨¬¬l9hªªé !ò:uÒSUUUTT$‘Ç ©Ñôôt»)nݸF:Bˆ¼ëW¼í¦LÈÍÍ%‘'ïææF:C‘““㋪ÒQG—t„aòòò]ŒfØLÅA!bÐ個n#„þ
+ÝFÀ¨©ÑÔÔÔ	Ü!×|.“‚"ÏÛÓcwHNNé ˆ<Buuõ鶳MLÍHA‘gjn>Ýv¶ªª*é ˆ<œE1N"`Ôˆ033s±ÝÌ{·n’‚"ï–ßµÅv3óòòHAä1¨*((t5RSÃëB ¦¦nÐÕˆÍfеÔè]pj!Ä\85Š€Q#ÂÜÜÜ
+«Ÿ<z@:Bˆ¼‡÷7¬v.**"‘Ç BXSSSX/ªª"!D^•PXX_[[K:"§FBÌ…S£5",,,Üó뎨ð0ÒABä…½x¾ç×¥¥¥¤ƒ òT+++ïß¹•™‘N:Bˆ¼Ìô´ûwn	…BÒAy85Šb.œEÀ¨aiiéyÞÉĸפƒ „È‹‹9Ï;YQQA:"A…°¤¤ää‘ïc_‘‚"/&:êä‘Ãåå夃 ò45Z[[{ëáSe¼ýBH,W	…Ó­GËÉ1h<€Å 3 ªª*ìųü<¼!5BòÞ愽x&‰HAä1¨æççÿ²msxÈsÒABä½xúä—m›KJJHAä1hjT,Ÿ÷¾Ú©s-mmÒYB„•æçå0‡ÃáÎ‚cЈ¢¨êêj©WTB´VZ]]Íœ‘ jƒ
+aNNÎêåː‚"/ðޝÕË—’‚Ècн¸:wîüËž¿Ì{ô$!DÞÈ1c;ëëwìØ‘tDƒ
+¡¢¢bŸ~ýÕÔÔIA‘×QGGII	ß DÀ¨©ÑŒŒŒ¹6“nû_'!DÞ
+ß+sm&åæâõTäÝÜÜHgh#rrr•Õµ
+騣C:Bˆ06ÛÈÄtúÔ)¸ÂbÐ個n#„þ
+ÝFÀ¨©Ñ”””qC\½|‰t„y—/œ7t at vv6é ˆ<B
+
+
+»yóÍÌ»“‚"ϼG/»yóÕÔÔHAäáÔ(Bˆ¹pj£F„™™™gM¿{óé !òü¯ù.œ5=//tDƒ
+!‡Ã163Sï A:Bˆ<
+MMc33ÒAyº|BMMMNY-äùScÓ
+>ßóÜiíŽ9Ι“Ç8Ž^ç.îÿü-ªªêjlâåqîmvV·î=nù]{Õ§_ÿÇAî<$2,ôƵ+ý,¤¥$_ñò465+//»xîLG]6›}Æý¸¢’b'½Î'Žª®w52¾xîLÞÛœnÝ{ø_ó}Ý»oÿ‡÷?´48"4Äÿš¯Å€ÉI‰¾—/švëVRR|éüYÝNXrrgÝO())éèv:ùÏᚉaW#ϳ¼‚ü<3óî7|}âcczõí÷àþݧZòÜÿúUËAƒ“â}/_23ï^RTxÉãl§Î‚s§N(«¨hwÔq?úwmm­A×®Îð
+òͺ™_¿â׫OßÀ{wž?¶00ôù³›~W’÷úª·—yž…ù^ç:wéR[[{žwRUMMSKÛýèß%Õ7ìêÁs/.*4íf~ÍÛëMbBÏÞ}ïÞ~ñ4¸ÿ€!ÏžÜò»6pÈи˜W×|.wïÕ+?7×ëÂùÎúú5ÉùÓîjê꧎ }Ãs§N”––˜˜uó½|1åÍ›½zß¿}3ôù³þ–ž?y|ûÆõÁÆǾŠ¾æs¹gï>osr.{ž×74‹ÄgNuÐÐPSWçÿ‡Åbu108{ò8¿¼ÜØÔìŠ×ÅôÔ”î={Ý»åò¢Ÿ…å³ÇîÞô4tXLtÔõ+Þ½úôÍÉÊô¾èaØÕHTUåq攆¦¦ŠŠ*ïÄQyyùÎúú¼ãÿTVV›˜ú\¼ž–Ú½g¯;þ~‘á¡}û[>}üðþ훃†{áçëÓ»_¿ÌôtŸKº•Îò4µ´””•NŸ8Æf³;wÑ?uìH•PhdlrÙó|VF†yž·ü®½ŒŒèÓß"øaPàÝÛ‡Ž÷»êÓ·¿EzZªÏ%O<W[ï\d3}âÔi½º™þË„ÈcЈ ÒR’é_†‚‚|ž{FzšP(ðà¹ÇÅÆ €Çi÷ÐçÏ àš·WÐý» pï–ÿ
+_ xüèÒù3 åÁs¯‹S“ßxðÜKKŠóór=xîY™é‚ÊJž{|l, xðÜÃC^ €ïå‹îÀ½›þ7¯]€§zyœ€èÈpž{µD’ò&Ƀç^VZšŸ›ëÁsÏÎ̬àó=xî‰	qu»ºréâ£À  ¸ãïwÓï <yôð²çy ˆóà¹×ÔÔ¼ILð๗—•½ÍÉñ๿ÍÎâóË=xîI	ñÒÚZž{dX( x{z?€Û7®ß¾q ‚z{z @dX¨Ï]Z[›”ïÁsçóËßfgyðÜßæä”—•yðÜß$&ÔÔÔxðÜ#Ãà à²çù'ÀM¿kwüý àQ`À•K <ä…Ï â<xî|~vf¦Ï=?7·¬´Ôƒçžò&©Z"ñà¹GG†€—ǹ§tW×®Þ»é îû^þWWñ±±<wAeeVfºÏ=?/·´¤Øƒçžšü¦Z,öà¹ÇDGÀ¥ógž?€¾>÷nù@Ðý»×¼½  ôù3Óî ãÁs
+éi<÷‚‚üâ¢Bž{ZJ²H$òà¹Ç¾Œ€Kçμx ~¾Þwo@àÝ;×½/@ÈÓ'žgOÀ똗<wQUUFZšϽ¨  ¨ Àƒçž‘–&ªªò๿Žy	 žgO‡<} ×½/Þ½ woûùzÀ‹'Á—Ν€Ø—Ñ<w‘H„çjœ«јõa™šššêêj%%% ‰DŠŠŠrrrUUU
+
+
+
+
+
+B¡Ífs8œªª*999EEE±XLQ”’’RuuuMMŠŠŠD"‘H$ÊÊʵµµvÅápØlvîèûÒ]ÕÖÖ*++7슢(±XÜò®Äb±T*•u¥¢¢"ûe]±X,‘H$ëŠþNÛ¦+ÙA£»RVV–J¥õº’———ÿªª*yyy‡Óò®dÇ¿^W²ƒ&‰X,ý£¬×•ìø·^W­q‚á¹ú	»jû?A¨}bV!D!„êaÖÔ(B!TB„BŒ†…!„£a!D!ÄhXB1B„BŒ†…!„£a!D!ÄhXB1›t „BŸXRRÒÖ­[}||V®\Éb±èÇoáRb¹¹¹ß}÷———D"a³Û®Lxzzòx< HKK[½zõœ9sÚ`¿¸ÄB}¢££X·’õë×/66öƒŸÞÚòòò
+
+ß¼ycjj
+ ÞÞÞ!!!{÷îmƒ]ãÔ(jS/_¾œ7o‹Å6lXÝíûöíc±X«V­âóù²kÖ¬3fŒì¿IIIôs¿þúk++«¨¨¨zÛ£¢¢mÓJêîZ ´ä)ÑÑÑ,«¦¦¦õR!T}ÖÅÆÆnݺUAAaÆ
+)))ýúõ[ºt)}*¾~ýzÖ¬Y®®®ööö?ýô“ì‰çÏŸŸ>}º¡¡!Ç€Ý»w/Y²díÚµ“&Mzúô) ¤¥¥
+2„Åb>}ºnK 4h££ãÚµkY,Öš5k  **jöìÙk×®1cF\\\ݐb±¸¶¶633“þ¯ÝÖ­[éÇ
+Ÿ%Ûïßÿ=zôh‹¥££sìØ1 عsg=‚ƒƒ›}â¸qãþ»o
+¡¶EW&ccã‡Ò[ª««G]ïl
+…ôù_﹉„¢(×·o߆ÛßÕ¦U¿zw­Ñ¡CŸióçÏŸ2eŠì÷ë—_~5 ¶)  IDAT±±±yóæÍwß}Go‘J¥=zô¸}û6EQb±ØÖÖVöt???Š¢.^¼¨§§GQÔùóçkkk)Šº{÷n÷îÝëîˆnyáºeMM¾¾~@@ EQ‡¢÷.•J»uëFQÔ•+WFŽY/ó¦M›8ΤI“þúë¯äädY¼FŸEï÷æÍ›ô.455³²²(Šòóó;{ölŸHÃBˆÚ}8p`Ú´iô–³gÏ<x°^!<}ú´———µµµìוúwyþü¹‚‚BÃ퍶IMM<x0 >|xìرÈÈÈpppX³fͪU«V®\YQQ±eË6›½~ýúäää¾}ûšššš™™
+><222''gìرӦM‰D~;‰D¶7mÚ4ƒS§NQµuëV{{{WW×™3gîÝ»×ÞÞ V®\yéÒ%º‡]»v-^¼xÍš5'N|òäIÝ´õºŠµµµ]·nÝܹs·mÛFQTddä¬Y³Ö¬Y3}úôׯ_êŸúŒÕýEHII™2e
+½½¦¦fôèÑC†©¬¬¤·¼yó dÿ­ûtzcDDýëy÷îÝyóæ999ÙÛÛ³X¬º-+**ê¶LJJ’==$$„ÞHïèÛo¿]·n“““••UÃØoß¾=yòäœ9s8ί¿þÚijê&¤(ÊÙÙyûöíE-]º´ªªªåO¤°¢¶GŸ…åå庺º±±±E999Ñë6›9s¦X,¾xñbÇŽeå§îïöΝ;ÇŽÛp{Óm藁<ÏÒÒòòåËô—~þùçeË–Q
+^,{{{Ë^E.[¶¬Þ_ŠwíºîKcúW1??Ÿ¢¨œœœ½{÷6¶ðUv×í;¾FLÖÄ܃«««žžÞ«W¯èÿ6QëžØ'**J¶å]-©ÿB@@5(„åååôù|~Ý=òùüÛ·oÓ¿Eyzzª¨¨4ñ¬zß`dd¤AZZÚúõëë~_Í>‘¢(|‘¡¢¢âââ²gÏžÛ·oO:µÞWcbbºwïÎápììì àÊ•+u¿ºzõêeË–¥¤¤xzz¾«ÿwµ;v,ýïË—/eû2eŠ¯¯/ lÞ¼¹¢¢báÂ…¿üò ØÙÙegg‡……¥¥¥uêÔIUUµ%ßšµµ5 ôêÕ+??ßÈÈhܸq#FŒøñÇ“““7lØа}§N,X°bÅŠ“'O&''¿««”””¤¤$+++ àp8ׯ_OIIIII9{ö¬««ëíÛ·ååå[1–¦¦& \¿~½ÿþû÷ï_´h}ânݺõèу~ÏO$Í›7¯Ñ§‚êêjmmm ÈÈÈhz_fffúúú/^¼ €ððpzc·nݺuëF¿{—••µxñâºOIII±±±¡Ç” Àf³õõõ›}–ÌÀõõõ,X°|ùò–ìî_Zúê¡ODör¬°°PCCÃÁÁ¡¶¶¶ÞˆðÛo¿upppvvvvvîß¿£#¿Fûla›”” ½B|ö왺º:ý¸Þ‹å?þøcñâÅßÿ}jjjÓßN£é6111»wï633³··¯¯å¯²¾loúõ5b²¤¤¤ùó瀋‹Ëêÿ€˜˜˜Ü¼y3  @KKkâĉqqqÔÿfÝ]]]—.]úäÉ“ÒÒRúéß}÷ìñæÍ›·mÛ6xðà5kÖÐEeóæÍïjIQT@@À Aƒœ·nÝ*''G‹ŠŠš<yòÚµk.\Xïw*//ÏÞÞÞÒÒÒÉÉiÅŠ3f̈ˆˆx׳dûrqq)--¥›¹»»=ºnŸ-|"BÔÖêþ‰ÿ駟Ν;Gý»…ÂÙ³gËÚÇÇdzX¬ÄÄDêÓBŠ¢,,,|||èÇnnn_}õEQ×®];uꔧ§g¿~ýè·Š‹‹544è¯6ûí4|œ˜˜øÓO?Ñ-ƒ‚‚:tè@~],_¹r…¢¨´´4 ÈÈÈ ÷ÞD!¤§FïÞ½KQTUU•½½==5êïïOQTffæÌ™3[þS@¨µÒóœ>>>ýû÷'§)XQ›’½P]»v­lcaa!½qõêÕÅÅųfÍ5jTBBýÕ'NhhhXYY]ºtIöR.//¯aŸ...QQQ¶iø20==]öa'''>Ÿÿ®ËK–,	
+
+júÛqqqÉÎÎnøÒxÙ²e'Nttttuu6mš———X,:tèòåË<HwÒòWÙõ^¶SM¾¾Fˆ¬C‡ÍŸ?õêÕãǏ'§)xA=Bï”’’bjjêàààããC:B¨µàk½Óœ9súôé³råJÒAB­G„!„
+/Ÿ@!ÄhXB1B„BŒ†…!„£a!D!ÄhÿÅ=Ýhy    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,111 @@
+‰PNG
+
+   
+IHDR     û   Ë™U¶   sBITÛáOà   	pHYs        êe¤    IDATxœíÝwXÉû ð7!t"ÅH‘ŽÔÐAT°qŠ]T<¥è)bå<»¢gC
+r"Š‚O=£ ]P@Šˆ]iFB	„–òûcï—oÔSQbÖù<÷ÜvgwÞ
+ËëÌ–ŸÏAq@u ˆèQGñ1!88XÔQ|st:}óæÍ¢Žâ»†ò%¸\noVWQQ±aƏ—鵐>·¢O/O§ÓCBBzX¾¡„õãºuë–ªªªŽŽNAA¶¤¤¤ÄÁÁAJJJSS“Á`ÙØØHIIÑh´²²2  Æ
+ÓÒÒÚ²e@pqqÑÒÒRSSKNNî¾¹p]؆úúúûöíëß¿¿¾¾þëׯ`Ë–-d2YJJjĈ
+
+
+Xá.{ÖÒÒÚºuë{W	‡”ŸŸO¡P$%%---óóó÷íÛ'''÷üùó¹sçêéé±X¬U«V©ªªr8œêêj"‘xòäIá¶ÛÊ•+åääÈdò²eË  ËáW4aÂ''' HKK#ÿ®>ñ7²gÏlCŒðW)øнºùQ™˜˜P©ÔP(ìL°²²200ÈÏÏOOOojj²²²²··/++suuuttäóù  ¯¯_TTTYY	 ‚ÍMLLºo.\ Ðh´¬¬,áÛ¶mãóùiii>ÌÌÌ$‘HXá.{€•+W~h• $
+…‚­µ°°àñx®®®FFFD"1--Ïç?~ü ®^½)++ÛÔÔTQQÑÐЀ)''óàÁƒ””ìp„_¸¢óçÏ„ׯ_/Z´HWW—Çã}ü»|òÿÖå7²`Á ¨¨¨¨¨¨èòUûнºJX?.		‰   >Ÿ¿xñb,a‘H¤E‹	
+H$IIIyyyIII‰Äçó`É’%ØZ lŽ­í²¹0 X¶lY—ÁÁÁ|>Ë–-
+
+
+ °yóæ÷îYø/¶û*AH$©ËÚ¿ÿþ œ‘¸¸¸L›6môèÑÓ§Oïä¶mÛ
+¤¬¬¼víÚî‡/\Q[[›’’ÒîÝ»UUU7nÜøŸß•ÀÓë²våÊ•‚6D—¯zåÊ•Gð=t¯îAúÆ
+8äûehh˜™™YZZš‘‘-177§Óé÷ïßoii¡P(fff[·níèè(//ÇÊHJJ
+ö ØÜÐаûæd2Y¸:		‰.ø|> lß¾}êÔ©îîîóæÍãÿÿ=ë.{Ö}• ¤Áƒ§§§ckMLL:::~ûí7[[Û;wî\ºtiÒ¤I àïïÏãñ.\¸  oÞ¼!“ÉŠŠŠ `bb’œœ|ãƍàààmÛ¶u9üåË—*’––ž6mÚöíÛëëë}|| à?¿+Á7,üc[[›ðRRR P\\¬ªª*¼¹¢¢byyyRR’ ä{«û kX?®ƒVVVŽ3FII	[«¬¬lgg7mÚ´¶¶¶'N‰Ä	&TWWw߃’’Òرc«««8Ð}óOcþüùçÏŸOLL”““ûО?R©°cÇŽq¹\+++.—ûÇlܸ±¢¢âÊ•+Ë–-[°`Amm- Lž<YVV–L&=„®ŽÀþýûÍÌÌV¯^]ÃúøáÏ™3§¾¾ÞÑÑÑÀÀà?<ø·.k'Ož¬¥¥E¡PFŒ!¼|éÒ¥×®];vì˜`É'V‡C¢nâ!â
+þ¿{Ò›{îy¥l6›F£-\¸°';ADµ°oBFHzzº¨Ãù99¹æææß~ûMԁ _‚ÀGOº#"&PA±‚ b%,AÄJX‚ˆ
+”°(a!"6PÂBDl „… ˆØ@	A±‚ b%,AÄJX‚ˆ
+”°(a!"6PÂBDl „… ˆØÀñL³
+
+
+ž^“"Lµ›÷óÏñgÎè˜XLöšpóvªº®áHW—â²GÊêZvT«šºIÊÙÞ¶G¨zW?Üe¨Y¹¨´lÌ(÷þZºôäÛ'ü¤onu:áÌŒiSiCÜÂ÷…/˜`ë2rýúõ7n´°wZ¼øPD„ÅæçÙ³Ï^¸8h°ùÄŸ~JIÏTÓ1>lèçÏûP·¥RÞ56·ñ%†8ÚuH5Œ®Ãd•úå•Œí¡¦cp~s’×x#Šõ‰¸SÞÓ§Ù±;,,pÑ"ë¡Ã׬^²%ÄÜÎ)páÂ#‘Q†–4Ÿ™3/$^Ö66?nlFvî€Az.ÎNO^¾’S`G³b6·6wr‡:9p$¤^¾©9ÜU¡¯jN~ç˜ÑõŒ®^Oš<qÂ`ªÝ±˜ã3½gØ»yìرsé’ Ú·ßV­Ú¶m»™­ãÂŽþñ‡uæôi^»®ih2nô¨;÷òúkéu°^Q)ÕGÅÞ†ÚÀnolëæìÈ—’{ZþÚc„[ŸþêY¹÷~7FÓÐ$ñÏ+S&O4³qˆŠþÃgæL‡£~ÿý÷•+VP]~
+Þjbm?ßßïø‰“zf”éS¦ü•tCÃ`ð÷‘wŠúiê8ÛÙ¾ª®•#;ØZ³Ú¹LÛe¨QV¡ìÙËQ#‡+©i¦eÝï9VÛØì¥ĩS&YÚ‰8rdî{7-![~[µŠâ8lŲå{öîL³ó›7ïä©Óº¦–S'MLº™<PßhÔˆá÷KªÔ¶·¦V2ê@JÎÑΆÍá×Ô7º
+B’W,yôd´ÇȾƒRÒÒ'üä©gJI8w~úÔÉVŽÃ<àçkë:rㆍëÖ®µtºlÉ’}ûSm…O¶[©ijº†#]]J=VVײµ¢ÔÔ7rˆ’Îvm<Bå;æp—¡Ò}T
+<>Ù,¨q§ãgLŸJâ¶7<ü—ùóm\F¬_·®ËÉ6gö¬ó/i›yyz¦ff©ê¸
+òðéÁÉÖÊ#q´ï$H¾®®áæ"«Ü/¿ðŸ“í¯ôI^Œ(Ö±'ã¼gL³u¹{÷nÁɶeës[§E¿üu4ÚÀ’6ÛÛûÒå?µŒL;&ãŽàd{-«ÜßÎÚª¾¥­¹ƒ;ÔɁK’~ù¦êŸ“-¯Àsìh
+}ã+]Ÿ<ÑË„f,&Fp²-[º„6ÄuÕ¯«vlßajãðËüù‹Ñïr²åå÷×Òâ`÷òMUK'¿¬´¢¢"žV||ü¾½{FyþdemÓÀdªkh›˜2ëÞ
+ÒÕÓ74b¼}k4ØD[G·¶¦ÚÜÒJ]}`Ý»w–Tš²ŠJSc#ÕÚVN^®•Í¦ÙÚIJJvvvÚ88ò¸< °stje·JIIÙ:8²XMd²•µMcC}ßþýÍ,(õṍšÆ&¦uïÞéêëë¾}[k<ØTkÎÛš
+UU]YWG¡Z+*)³šš¨6¶²rrm­­ÖvöÇÖÞ‘Ãá{'g6»EJJÚÆށÕÔÔG±…fÝØÐÐÀ SËzf†–¶Ñ`“ºw]}]}Fm±©™–ö ·µ5VV¨Õ3™V4E%¥f‹jc++#ÛÖÖfmç@$¸\®­ƒV‘£sKK‹ŒŒ´µ«©QQIÙ’Jk¨¯ ªfjnÁdÖiji®{ÇÐ70ÔÑÓ[[kbn®¡¥Íx[K¡ÒúöïßP_oemCîÓ§¥¹™fc+--ÓÞÞfcgO y\®­ƒSgG‘H´wÂb5ÉÊÊÑlíš””•-¬¨
+
+
+ªªj&fæõÌ:­AƒŒŒë}##]½·µ5&æ55Þ1–Tjß~ýê­h6drŸ––fš­´´tG{» ðx<[§ööv‘dçäÌjj’•—£ÙØ555*«ôµ X5Ô׫©ljƬ«¤««ohÄx[kh4x®îÛê3
+EM}`Ý;…JSéÛ¯©±jm#¯ Àni¡ÙØIJJvvtØØ;ðù<>ŸoçèÔÚÚ*))iëàÄb5)`ç@cCß~ýÌ-)ÿ:Ùt°ŠÞŒlªªš:³î…flVÖ¶òòòÿ:Ùìø< Ø;9·²[$¥¤mYMMä>}¬hÂ'[½º††±‰i]Ý;]=}=CìÐÔÖ~[[ciE ¦V_WG¡Ò•UXMMTkᓍôÿ'['@°wÒÒÜ,--8Ù)TëÆƆ~ý±“©¡¥…lzú†ºúokjLÌÌ4µ´µµjÿªõL&…fý¿“MV¶­­fkO$¹\®­£cgG'v´°XÒ²2Övö¬¦Æ>JJ–TZCC}ÿ.'ƒ¡oh¤£§ÿ¶¶ÆÄÌâ`خܜ;3fÌÀóÉ	‰Wlœ°IåSŠmÍMlllð|
+KRRRVhæ(AÄ”´´ŒŒŒàû¢ûõë×—ø²[šE‚ =²o×ö
+6 ¾gÍa0—o$L5Œ ˆ8zõò…½¥©¡¡!ž[XÍÍÍ5U•<Oԁ Ò#̺:ƒøîÞ¾}{ãoÁ­ìQ‚ HüqøàîÝ»ß]Âæææ¿S³¨©‰xÎË‚{̺wŽ³àù/¹¢¢"'+ƒÃéu ‚ôȃ¢¢üü|Àw—ðΝ;{wnkkmu ‚ôÈÙS'Ž=
+øîr8œÛwïKKKQÇ‚ È—ëèhBµ––Æs«¤¤$þDLGG‡¨A¤Gnþ}=11ðÝ%,))9w¢½½Mԁ Ò#·’®_¾|ðÝ%€Œ‚Q‡€ ÈW0”fønaeggïÝñ;ºèŽ âîì©“QQQ€ï„UYY™›ÅápD‚ =RZ\TPP ¨Kˆ ˆXÀ—0%%e㪕­l¶¨A¤G¢#†††¾VKKKmM5zùAÄ]C=óÝ»w€º„‚ˆüw	¯_¿0¯¥Ö€ â-|×öuëÖ¾–¤¤¤¼¼<z-AĝŒŒŒœœ .!‚ bÿ]ÂK—.ùLñjf±D‚ =²eÝê    ÀóüWýû÷7³°Ds|!ˆ¸Ó30466 Ô%DD,à¿KxúôiÏáÃXMM¢AYµ$pÎœ9€ï.¡±±±§×$I))Q‚ H8
+s¡6|w	ù|~z~1š ø|>ŽÑÈ·ð]ýáðx¼¡4"‘ˆçÖñãÇýüü®¥¤÷QTu,"v&.öÈþpQGˆ
+CCÃcg.Š:Šÿ	òŸ«¯«“˜˜ˆç„egg·xE°Œ¬¬¨ù.„°°0QGˆóçÏ×ÕÕ‰:Š™4c&ÕÄð}
+K__äè±$’¤¨ù^¬X±BÔ! bàÑ£G©©©¢Žâ_l­Ìßw	¼<†7³Ð]Bok–Í›7ðÝÂ6lØú­ÛeeåD‚ =òsÀ/ÖfƀŠŠ‘±zÒAÄœ†––®®.à;a]¾|yîôɨKˆ ânûÆuË–-|w	Gv(RN^Aԁ Ò#+~µ³0|·°‚„„„¨£@¤§$ˆDìoÏ	+))iù vK³¨é
+-ÍÍhôz¯„íÚ´ià;aM˜0áÓgåÈ¢¤7ÈÊÉ-™ï{öÔɶ¶¶/Ø\MMmûöíØg++«””GGÇaÆ9889r[®­­íêêJ¥R“““±b_+økmmõööþÜ­z-¼ÿäííýe¿D`õæ­{öì|'¬ÆÆÆŠWå?H»ƒH$ŽŸ45"<lÚ¸Q_¶úöí{þüyÁø÷ÁÁÁ×®]KOOÏÉÉ™1c¶PEE%55õÊ•+6lø² ?ýw!\2..ÎËËëËjüxzzÆÇÇ‹:
+ñV[S]YY	øNX©©©!kkeÿ(“PŒ=f ¦fCC}DxØÔqŸ•¶$%%çÍ›‰ýH&“SRRX, (++—ÔÒÒbuĵ¼¼|øðá®®®¿ÿþ;öã¨Q£†êìì\RR sçՐÈÌÌ€¼¼¼€€€îÅ%…›T—/_vwwïR8%%ÅÇÇ /^|ñâŇ:;;6»— \.×ßßßÜÜüÈ‘#ÑÑÑnnnæææ/^Ô"X t:ÝÔÔÔÇÇÇÂÂâ½ñw!¼y—c·°°ðññ133»}û6VØÃÃ#11ñÈ{<¼wï^À÷h
+---72îôí×ÿ»zïü›¢_ÿë÷
+k €@ ðù|E%¥Ùóü'L™–x.!òÀ¾4p¬¬¬îܹãè蘓“ãààpùòå;w¦§§“ÉäC‡ÙÚÚbe
+KJJ–.]š’’‚ýˆm~êÔ)###;;;>ŸO Ə¿sçNSSÓW¯^ÐéôfddÔÖÖÆÇÇ:thåÊ•žžžááá]Š VR___F+((è¾ÏeË–q8œæææØØXww÷Ý»w[YYñx<ì×­©©™››«¨¨èää”››+++Ëd2=<<òòòº¬-..vss‹‹‹ãñxUUUÝëêòu	o¾jÕ*ác×ÐÐÈÍÍåñxóæÍÃú΂CøŠ¿èojþüù©©©ßÕËÏõL¦3Õ¼oß¾x~¬áÕ«Wé)É?Mš,%%Ý;52ëÞý¶,¨wêú ¾¤¤$‡ÃÁþjjlŒ‹‹‰6·¤üç–²²²³gÏŽŽŽ ¬µUTTäçç‡ý‘3™LWWW>ŸÞuà//¯-[¶DDDÌš5ËÃã´´tÑ¢EتŽŽ èׯŸ¾¾¾¾¾þòåË;;;333wïÞíïïߥ˜ d÷ðºï3((ÈÀÀ ¬¬ ª««±‹V‚œúöí«¡¡-ILLŒŠŠ"£ûZ hhhÐÔÔ %%¥÷ÖÕ…ðæ]Ž]QQÛ“ÉüÏïùDEyÄ6–§§'žVNNÎþÝ;ÝÇŒíµ„ÕÙÙùøa©™%e€ªZïÔ؏Ç{ùì™àG¬Õ¯ÿ€O`gáÂ…C†éìì|üø±±±1 ¨©©	ÚàØ5¬÷nH"‘BCCÛÛÛíìì<<<LMM÷ï߯§§  ”G†âììL$»ƒ÷
+䦦Æd2»^±bEttôêÕ«/_¾¬¦¦V\\lii)ha„æwÛ¶m[^^›Í¦Ñh‚oF¸
+%%¥ªª*×ØØ ï
+L˜ðæ]Ž½±±±²²’Çã	ºÒËnÈ;ª@Wç	ëçŸÖ1¥ôþˆ£ÓfÎvsÕË•b.ž‰OK¾	 D"‘Çãéèéû-ââv&.öS6———Ÿ:uêBCCKJJddd8ΧJsíÚµƒ¶µµaו8ØÜÜL$]\\BBB%gÎœI¥Rsrr>^LØ„	nÞ¼Ù¥°ººº­­­¿¿MMMTTTxxx@@€””FÛ·o_—=xyy¹¸¸XZZ’Éï¿e¼fÍš‘#GR©T¬…õ‰½÷ØUTTV­ZuÿþýƒbètºXß4øì?3„jø¾†•ŸŸ¿ÿp”_€ŒŒLïÔX[S=uܨ»E’°::Ú§ŽUÏd€ž!–ª°¶@ÂÉ㿆õ=c³Ù~~~			ß®
+.—+!!ñúõë3fdgg÷dW—ö0ÞÞÞ111²â3.Ûwx
+ëjâEÊ`ÃY³fá¹…UVVvé\ÂŸŸ{-a‰ÖÕKë™L}C#ß_	RÈÉÉ}Ól ›6mb0ØÃ>Â'L˜ ø1$$ÄÅÅå³vþ­ƒÿ¤Þ¢W¾xŠó„5{öìA¦ÿ}±::Ús³³¶íÙ‡§TÕk\]]ÓÒÒÞ»JQQñ³F³ëÒ¼B¾Š=QøŸæ+++k÷¶-m­­¢¤7ð¸¼ÐC]‡£l…àOÂÉãØsxnaUWWßÏ»ËápDHo at C×#8ö¸ì!t´¾Ö”)STõŒE‚ =µyÇnüw	“““×­\Æþa^ÍA¼Š:¸oçΝ€ï„ÕÚÚZÏdâ÷±
+ùQ°šš°gzñÜ%ôôôT8HÔQ ÒSÁë6â¿KxíÚµ@ß9‚!SS{¶o]³f
+à;aÉÊÊ*)« »ü"îÈä>}ú ¾»„#FŒR ê(¾#¢YYY¢¡«AË°.!žÖ…–¯\yôd‚Â^yýqÈ+
+týúuQ‚ˆlÀïÇæ5¿ëë>|Ï	K]]jmKB©ŒŸ4eü¤)¢ŽA¾±‰©¹‘à»…åììü«lQG HOyÏ™‡ÿ»„§NãâÄjB3?#ˆx^üˬY³ ß-,“IÓ¼{ ?A¾.—á#)&F€ï„E¥RçÎÿERRRԁ Ò#cÆ{á¿K;ÂÁº©±Aԁ Ò#KçûN:ðݲ··_üwAÄÝÔ™³©¦Æ€ï„¥££ã2b$‰„º„"Þ¬¬m­Ì ß]³gÏNãÞÌBw	D¼­[¹ÔßßðÝÂruuÝ´}—¬œ¼¨A¤Gæ-Xhcn ¤þýû‹:˜/4nܸØØ؏PTTÔÖÑýqæ©G¼RUˆMFKz÷««¨Cú<§OŸnú¯'BÿüóO??¿k)éŸ8ï1‚ ߧ›7èëê$&&’ `ìر¿þú«¨Cú<ÿYfôèÑ{•“Wè…x¾slvKa~¾¨£@ĉúÀºú¢ŽâK‚³³4|_Ãâóù<®XÎuüÕÕVW¯^¶XÔQ âÄkêô«×‰:Šðø|.—øNX7nÜ^üê
+DEE
+:TÔQ bÀÝÝ]Ô!üË¡=¡ÿëâ•——Q^QŒlø‡–––‰‰‰¨£@ÄÀ÷öBÛÚ-Û,MßÏa1™ÌçOŸrŒ‰TÇ*+*ÊËËß	+==ý÷
+kZ[Ù¢A9¹ÿ~À÷5,ooï¾Zº¨Kˆ ânGø'+sÀwëùóç·’®s8¢A¹—›ƒ=É„ç„u÷îÝC{ÃÚZ[E‚ =réLüñãÇá+&,,üáSÐéôÍ›7­º˜7o^ê½BôL‚ˆ»ƒÄ^¼x¾E«¢¢bÆ
+ŸX˜N§‡„„|õ0ùùùÑÚÚÚ¾Ñþ¿7I×®ðxèAY‡®&^<}ú4ô$a•””888HIIijj2Ár--­­[·@QQ‘””F+++ 0tèP---mmmì&åž={°å=;œ÷{üøñÕÄKßbçß¡–––™^ž×¯\æ '9|ÉL½M§Ó¡'	kÎœ9uuu999			222Ý̝;—D"+**úùùa›››***âãã`Á‚ PQQñÅa|ĬY³®¥¤“ûü(w	š8©­½mgÈFï	ã>7mikk»ºººººŽ1 ÔÕÕW¯^­Z½zµºº: ¤¤¤8::6ÌÁÁáÈ‘#*¦­­íææ6lØ°Å‹···ïßÆÆûw²´¶¶z{{îVVVVß"˜oG8à.Á{{{ã¦{±ûàḸ8èIÂzðà‡‡F:t(ù}S+?xð   ÀÆÆ&++ëÞ½{ØBWWWggg ¨¯¯  ÐÔÔüâ0>"33sgÈÆ碻””´o  ¼­­ùÜ´¥¢¢’ššššššœœ ªªªwïÞÅVݽ{WUU ‚ƒƒ¯]»–žžž““3cÆŒSQQ¹}ûvzzºŽŽÎ¶mÛ„÷Ÿ‘‘ö¹Çõéý\á’qqq^^^Ÿ[žxzzbÍ8uüØ¡C‡ 'Ïa™››Óéôû÷ï·´´P(”îÌÌÌ$$$¶nÝÚÑсu @BBë òù| ’’€ââbKKË/ŽäCjkkõfÿ¨½­
+ Zš›ë™Ì^«TØ·ÑQ
+õ Àx[»3dãñ¨#ó,4üÙoäØÛÛçääðù|lŽ{2™œ’’2zôh2™¬¬¬ü¡bAAAC†Ù²e‹`	›Í–—ÿ×xŠååå¾¾¾<oäÈ‘³gÏ^°`›Íæñx‘‘‘ÖÖÖ­­­˜>}ú!Còòò¢¢¢Ö­[÷¡’gÏžÅö|ùòåS§N•———d0Ǐ‹‹[¼x±›››‰‰I@@€„„FÛ·o p¹\ÿœœœÀÀ@‰Ï`0BBB&OžŒíÖÂÂ;äÀÀ@}}ýeË–Y[[–””t©Ë¢ˑvÙÞÞþÞ½{YYYK—.9r¤àY¿~½ Æ.Åôôô‚‚‚¨T*öJ0†Ëåúøø:tÈÍÍÍÃÃÃ×××××÷sõß¡ÏžJòÿÿ944”ÿù
+mmmI$’ººúÛ·o`åÊ•XÂ>ÚØؐH¤~ýú­ZµJx•àC^^ž–– |níÖÖցøùFãz®¢" \¿~ýCߧ–––‹‹‹‹‹ËÌ™3ù|>…B),,\ºté’%KŠŠŠ(
+ŸÏùòå‚LLLìììîÞ½û¡bØÿ1VVVÂû711Y·n]{{» @\\\nn.ŸÏçñx?ýôSii)ŸÏ///wwwçóùêêêÏž=ãóùYYY|>ÅŠ)))))@¥Rù|~÷’K—.
+üùçŸù|þÈ‘#ïß¿Ïçó¹\.¶•††Æ›7oX,–……›ÍæóùuuuÖÖÖ‚Ý
+puu­¨¨xõꕺºú{ëÖ}-¶«––ìFþB„?Ée    IDATkìRÌÍÍíÕ«W‚ª1Äâ>|¸ð—ðttt¼¦NOÏ/þ~þÃûò…Btàÿ[LÂ(Š 'ø¡2ÖÖÖ¯_¿þ² ˆD¢´´ôG
+p¹ÜÎÎNII)èÅ4ÒÙÑ1PSkŽ_@ïUùoǏFÖVWa#			7lø1ãÖ/ÿÈVX—Mx	…Byðà ¿:::‘‘‘ PTTäçç———÷Þbííí$©ËþŸ?îííÝ¢ //¯-[¶DDDÌš5«´´tÑ¢EØòŽŽ èׯŸ¾¾> 899-_¾¼³³333s÷îÝþþþ*ÙE÷}`wª««±ë>Äÿ–¶oß¾ØÈ–D"1111**Š@ ßS.ÐÐЀ]ÍPRRzo]D°+===ì—ËþB<<<>T¬¾¾^[[[P5FQQ‹‡)¢þ·sdxº‘þºuëÄõÕ))©ñãÇ_ºté#e®_¿¾vÃƝûué†|SAóäååG{Žïµ…åfgUW¾ "‘Èç󇸺͛¿PÏÀðåóg_°·¹sç
+ÿøøñcccc PSSü“Ó½˜ÀáÇnjÓe¡²²òÓ§O?’H¤ÐÐÐööv;;;SSÓýû÷ëéé@gg'å >|xHHˆ³³3‘HüxIŒšš“Éì^rÅŠÑÑÑ«W¯¾|ù²ššv9‚Çãa{n#oÛ¶-//ÍfÓh4ÁBáJJJUUU<¯±± º×%¬ûZÁ®„÷)ü…`	ë½Å”••±[UXÕ˜ÆÆÆÊÊJ‡uØ–àp µ•Íf³ßïŽ;–¬¦%ê(zÕ±ÈÀqŽ¥ªOܐÉdºººbŸ¯]»†}˜={¶p™ÐÐÐ’’‡#|í¼K1&“éææÆår-,,öîÝ+¼>ŸßÚÚºcÇAák×®<x°­­ÍÇÇgòäɁÍÍÍD"ÑÅÅ¥Ëz3gΤR©999 pàÀ”ÄL˜0áæÍ›]Jª««ÛÚÚúûû×ÔÔDEE…‡‡`OÞ`×°„yyy¹¸¸XZZ¾÷ž ¬Y³fäÈ‘T*kæ|<ªO‰¹ËòÞ˜µk׎5ÊÊÊJEEE°PEEeÕªU÷ïß?xð  ÐétÜÜvX±z6ó3 BCCÅnˆd'''55µ·°®^½ºzíº=Qò
+½7J2ÖÂÚ¹ïP¯Õ(›µjIà°á#æÍÿ¥KªzùüÙÏÓ&]¿~½{“¯Øl¶ŸŸ_BB·«‚ËåJHH¼~ýzÆŒÙÙÙß®¢/ãíí#ûE	ëêêZÙÚ?#Žîþ=d°^hh(ž[Xòòòý¨ˆßé…ð¯îéãG'Î]ÒÑÓu ß99¹oš­  ##cÓ¦M{þ¹‹ÆÆÆ	&~		qqqù¦ñtñ­¿7))«ôë×ðÝ%>|¸¤’¸NböfÏóu?WW×´´´­UTTìrùbAX—Ï£5œ?~úOcšY,Q‚ Hl\µ{+Ï-,
+
+
+{'gÁuAÄ”™%ÅÂØ ð°œœœVȼÿþ‚ bdúì9øïž<yrÔP‡¦¦Æÿ.Š ÈwlÅÂùØ«ìxnaYXXLŸ=GZú=#I "FFŒceb¸OX3öÅÞ¯FD|¹;„út	=œíX¨Kˆ bnù/؈Fxna9::.ÿm­Ì=é‹KóæÍ“““uˆxó捕­½¨£øŸé³¦šâ½K¨¥¥å4Ô…Dú¾&Ý	rE¯©ÓE"6(6vV4QGñ?æŠ
+Åð°Î;çççw-%MœÓ¯ÿïç½0ù\~]¡¯«“˜˜H€S§Nu¸êû÷äÉ55µ—qssÛ²+LV®÷Æ–Aä[ð[¸ØÆ|0 lmm@0„±¸ÐÓÓ300øx2™¬6P£ûHI‚ˆ—¾ýúa3„G
+Å™+W®ÌG]B¡[7ÿ¯KˆWcÆŒ9p4FN¾÷ÃBä[XöÛZ;À÷sX§­íG™ãAp¬£½›ãÏ	ëæÍ›«–²[šE‚ =rxßžßÿðýXäI“$ûôU ÿ(3?#^­ÿ}‡#ÅðÝÂb0e¥%Ü^œHAoáÕËØdKxNX;6ohme‹:Az$îX46ž»„3gÎì?È u	DÜíÚáL5|·°ž>}ú÷ÕËݧ´DD¼ÜÉLONN|'¬{÷îEØ׎žl@1wùüÙ“'O¾»„¾¾¾†V¶¢Žâ{±~ù⪪*QGˆ!ÃGú.X$ê(þsÓÏ	ëîÝ»‡öý%PF’åååd2ÙÙÙYԁ b !!¡¡¾^ÔQüOâ¹3Ï‹óçΝ‹ç„õüùó]õñ
+@	ãææ†ÝjA£Óé¢á_r³3™5•8OXÞÞÞšÆ梎AžÚ¹ïþ§ùJOO߶q]+=‡… âíä±£û÷ï|_ê««{ò¨ŒÇã‰:Azäuy¹‰øNX'Nì7è?ùCäû·~ëvüw	étú¯A‹ØìQ‚ HD„‡mݺ𝰸\nggŸ/ê8éNg'öÊ
+ž»„cÆŒQPÕu½§³£CMsàÑÒUkðß%¼råJÀì-Í?Ê ~Yi{¶o­­©u ò•íÙøNXd2YCKëÇ™5g˜ÛˆûùyÞÆ¡´…àLUUlZ?<ÿ1»¹¹mÞ±[ö‡™œH$Î
+XÀápþ¼xþsÓ–¶¶¶««+•J‹‹^âêêºsçÎ÷ €””GGÇaÆ9889rä«Qkk«··÷çneeeõÕ#éIëׯ2dHRR’ðBooﶶ¶¯nùýˆµ°ð|
+ëìÙ³K—-?~æ‚™,êXzÉpÑ1‘‡+ßTp8œ«‰ÿú3qÜ„‰³}ýUÕÔ?¾¡ŠŠJjjjKK‹“““`ÉG
+ @ppðÍ›7ûöí õ}õŒÇã}bSW¸d\\œ——קlõÝâñxýõ×ýû÷…—‰DOOÏøøx___Æ&FÖÿºÜHO7::Ï	kРAC\\I¤Þ>Æ'm]¿¦—+PVéû¦â5 ðx<'H[œO*šÅb}ü½Ë.ÈdrJJÊèÑ£Éd²²²2 ”——/X°€Ífóx¼ÈÈHkkëÖÖÖLŸ>}Ȑ!yyyQQQëÖ­ûPɳgÏbû¿|ùò©S§ºì“Á`?~<..nñâÅnnn&&&4mß¾} ÀårýýýsrrI$R||<ƒÁ		™<y2 XXXØÛÛck.\H§Ó—-[fmm]XXXRRÒ=~áÃOII	
+
+¢R©\.;X___7räÈõë×wù®°Ã9qℼ¼¼««ëñãÇǏ/8@___”°>‘%•fil >®oûg”ôr;C6>yTÖË•
+c³[ªÞ¼üH$y<ž‰¹“ñvêÔ©zùY[[[WW·¨¨(!!a̘1Ø=== X·n»»{÷ P^^¾sçÎôôt2™|èÐ![[ÛñãÇïܹÓÔÔôÕ«Wt:}àÀúúúÙÙÙñññ‡Z¹r¥§§gxxø‡J
+¢¢ÑhÝ÷¹lÙ2‡ÓÜÜëîî¾{÷n+++AÓLSS377WQQÑÉÉ)77WVV–ÉdzxxäååuY[\\ìææÇãñªªªº×%ü-
+><66 °Â§N222²³³ãóù¡ËW*8++«ÂÂBá%ÂG׃_õ7¤««kek¿bõ:Qò?ø^æĉóç/¸tãVŸ>Š½VéêM[z­®÷Z8wvMUÇ“àr¹f–¿_i¶v³'z~d+•´´´¬¬¬={ö`ù¨{—°K ÐÑщŒŒ€¢¢"??¿¼¼¼ÒÒÒE‹þD©££ úõë‡ý‰:99-_¾¼³³333s÷îÝþþþ*ÙE÷}”••@uu5vEIБìÛ·¯††¶$111**Š@ 0Œîk ¡¡ASS ”””Þ[—°úúzmmmAa//¯-[¶DDDÌš5ËÃãKáî‡ó¡DþÓÒ~º:çΝÃs¢P(>~þÒÒ?ÐØ2y¹wJKŠ±Ï¦–Xªúô͝7nÜøâŬmõŸ?~lll jjjXSÝÔÔtÿþýØZìI?áKWÇ		qvv&‰/‰QSSc2™ÝK®X±"::zõêÕ—/_VSS+..¶´´´°„;Û¶mËËËc³Ù4
+[Ò¥)¤¤¤TUUÅãñß¿0ee劊
+ À
+“H¤ÐÐÐööv;;»î	«ûá/a0XÞD>ÅhÏñV&F€ï–™™ÙïÙR?Ò³”1QG ÀÒŠêû™©JÀÏÏïèѣ؝Áÿ,ZRR"##Ãáp àÀÍÍÍD"ÑÅÅ%$$DxÛ™3gR©Ôœœœÿ,‰™0aÂÍ›7»”TWW·µµõ÷÷¯©©‰ŠŠ
+’’\ÃæåååââbiiIþÀ—5kÖŒ9’J¥b¦GµvíÚQ£FYYY©¨¨ Àµk×<ØÖÖ&¸ñéètº¸ßOèMnPÍß×°bbbüüü®¥¤÷QTu,½!/÷Ή?ŽÎ›¿ð½©jöDÏñãÇ‹× ~l6ÛÏÏ/!!áÛUÁår%$$^¿~=cÆŒìììoWQÞÞÞ111²²²½VãgùÞ®aúÎÑ×ÕILLÄsËÉÉ)xÝF™ïõœøêTúö;}\ÔQ|Mrrrß4[@FFƦM›Æž={º¬jllœ0a‚àǐ—íç³
+À·>.œñþyÍÔðÝ%8p µ=‰$)ê@z‰ž¡¨C?®®®iiiï]¥¨¨(|Ûáã>«0ò¹›˜Qp?Uý…¼'Œkf5‰:AzdÓêà…¾[X#FŒø}w¸¬œ¼¨A¤G/±57|·°deeûöë÷ã¼üŒ x¥¨¨„½Jç?æk×®-œçÓÒÌu ‚ôHض-«W¯|w	Ǎq센òæ3‚àÕŠ5ëí-Mß-¬ööö¦¦F4k‚ˆ;vK‹Å|·°nݺµfù’k)é’?ƃ£ÿ©¨¨èÀ¢ŽMMß×½õÈáøptòäÉÒÊýÈ}DÈ÷"#####CÔQ ÈgÛ¸}—#Åðݪ­­-¾_ ®>ø#½Nø!ÇÏ%~_ÃB¾:¢„„¨CøŸçOž(J444ðœ°233C·næ6Í% ’’?ÊÿþœŽ=–£«ãîîŽç—ŸÛÛÛ“ïä)ÉÝWCDŒ°Ù-ÎVæ
+
+
+x¾KøèÑ£?/žï>‚ â%3õö7 ߏ5Ü¿?&2¢½ÍM‚ âíjâEl|<w	Acº#ò-àæçÜÜ܃{BÑìo"î.ž‰‰‰|'¬—/_Þ¾y£]ÃB1—77++P—A±€ÿ.aZZÚÖõkZÙlQ‚ HÄ|?é^__ÿòù3ôò3‚ˆ»ªÊ7}d¥ u	øï&%%­X´ ¥¥Eԁ Ò#÷„nÞ¼ð°Ð9‚3¨Kˆ ˆÀ—ðòå˾ÞS[š›E‚ =²}ÓúåË—¾–²²²®¾š5Aĝ†¦–¶¶6 .!‚ bÿ]Â3gÎL=‚õN ÈçZ»b©¯¯/àûÁQ]]]7÷Qh¸QwÖvö–ƒ
+u	øïÆÆƺÙQ›šE‚ =0oÊ”)€ï.!•Jõ[¸XZZFԁ Ò#?Mœlebøî¢I(~ˆI(NŸ>=Îmu	DÌýºx¡ H`¯â’¼¼¼¼JÿÁ&fßÓ”‚|.ee•	žcõôôðÜÂRUUµ°¢Jð|A~úFF&&&€ï»„/^œ=i|3=8Š âmËÚß/^ø¾èþúõëøKÚ9:£YÚD¬•Þ·1lgg‡ç–´´tŸ>Šèågwròò
+
+
+€ï.á_ýè÷sK3Kԁ Ò#{wü¾nÝ:Àw—ðíÛ·‰ß46Ew	D¼½|ñÜÞÂÄØØÏ-,6›ýŽÁ@³æ ˆ¸kl¨¯¯¯|w	SRRÖÿº¼•&¡@ñ}èÀ®]» ß]B‹õ×íõèº;‚ˆµwoß:Z™©©©áù/¹²²2ÿn.‡Ó)ê@鑲‡ŠŠŠ ß]Âììì°m[ÚZ[E‚ =rædldd$à»KØÙÙ™’›/++‡Fk@±ÖÖÖ6„j.++‹çViiéùøS¢A¹}óÆÕ«Wß]¢¢¢¸c´··‰:Az$éÚ•. ¾»„€ÆtG¼Àÿ˜î999ûví@ÝDܝ‹‹ŽŽ|'¬W¯^e¥§r8Q‚ Hß/¸{÷. .!‚ bÿ]ÂÛ·oo^ók+›-ê@é‘c‘aaa€ïi¾X,VeEzùAÄ£¶¶¦ .!‚ bÿ]¿ÿþ{é¿–4Z‚ˆ·ý¡;6lØ øNXRRÒèµw$II)))À÷¼„úúú¯ªk‹ï˜YR._8÷ôQ™±‰iÂÉØÚê*=Ãc‘­l¶ö C{ÃH$’²ŠJä}dEEIâØáˆjê--Í'£ÒÓ«©ªŠ=>ØÜüÉ£GçOÇQmíòïæ^M¼hcr+=å…ftíÊý¼{f–‰çÎ<úÄh°Iü‰˜·okõô
+þ8|¨­­MS[;bo˜”´t%Ũû•”BÌ‘Ãj²šX'ÿ8ªk`PõæM‰ã¦––ž?emïp/'ûúŸ‰Öv©·è™©·-©´ëW.ß/05·¸x6¡üÅsCãÁ§Ž«{ÇÐÕ78q ³³c ¦VÄÞ0i2¹Ïуû•TTø<~LäauMÍƆ†¸cÑz†F¯_9kF±zø øBüiÇœ¬Œ¤«W¬íìSè7²3Ò-­¨ý™ø ¸ÐÄÌâBÂéWå/
+ÇÅD×3™:zú‘öq¹\5õ‡Ã÷ÈÊÉÉÉÉG: Ò¯‡Ã9uDCK«žYw*æcãWå/Ïœ<aaE}PTx1!ÞÎÉ9;=~ý/š­Ý­¤ë¹Ù™êÕKÊ”63?wú䛊×FÆ'¢£šéêÙ¿ P=²o¯œ‚¼ŒŒLtÄÁ¾ýûwvtčÔ4èãíéãÇ›¼|öôì©“–4낼Äsgì2RS’oüMµ±¥_ÿë^ÎsŠÕŸÏ?.{8ØÔìL܉ªÊJ}C£˜¨ÃÍͬA:ºáaD	¢Jß~‘ûÃÈd’¤ä±Ã‡ú«ª¶¶²ODG
+ÒÕ«­©ŽlföôÉ£s§â¨6¶÷î^¹xÞÖÁ1=%9õÖM+k›]-¸—kfI¹|þìÓǏŒMLN¯­®Ö30<v$¢­µUkÎ¡=»%¥¤”””£ì룤D$‰PUWoifü㨎¾~uUe|ìqs‹'eÏŸ>E³³¿—sçZâ%{‡Ô䛩)ªõßWÿ,*È7µ°¼t.áųgFƒMNÇƼ{ûVWß :â`GG»†¦VÄÞ0)irÅ£÷+*+@Läa5
+¦¦Æ¸?¢õßT¼N8kfI){P‚¹Ù™×¯þimgû捬ô´N¶Âû¦æÏÄÿs²ÅüÁ¬{§£§ôÐ~‡£>PãpøYYy…£‡(÷íËãqG¨©ÕPÏŒ;ö‡¾‘QEyù™“'Ì­¬J‹‹/$œ¶utº“™q㯫4[»dzRNfº…õÚåK¥ÅE&fæçãOU¼*702>yìhCC½Ž®^ä}<oâÔé>3¦¾[X PRxÿîl (¸w÷~~ äfg––@fêíg@Êͤ×å/;:;’éIÕ••-Í-Éô¤wïÞ60™Éô$VSÓÛÚÚdzR[kë›×¯’éI<ïåógiÉ7àQéƒìô4¬¢{9w  ÿ^nQA> ÜÉÌ(+)€ŒÛÉ/ž>áóùÉô¤×¯Ê;Ú;’éIÕÕUÍ,V2=‰YWWϬÃ*ª©®J¦'µ··UüE/ž=MOI€²ÒÙé P|¿ /7 òrîß/ €;ie¥  =ùÖ‹gOy<^2=©âõ«¶¶ÖdzRmM5‹Õ”LOª¯«c¾{—LOjifau´·W”—'Ó“ àù“'©É ððAINV æçåßÍ€{9wJ
+ï@VzÚ㇥ –rëåóg\.7™žô¦â5VÑÛšš¦ÆÆdzR}=óƒ‘LOjii©®|“LOêììxõòEÊÍ$ xúäQFj
+ ”–çde@aA~Á½»XEŠ
+ 3=õqÙC H½u³üÅs‡“LOªzó¦•ÝšLOb¼­mh¨O¦'564`±Ù-U•o’éI\çÕË—·oÒàÉ£²¬´T (-)º› …y÷
+óîÀÝì¬Ò’" ÈJK}ò¨ nߤ¿zù’‹UTù†ÍnI¦'½c0’éI
+
+õŒ·µÉô¤VvkÕ›7Éô$‡Sþâyê­› ð¸ìafz* <(*Ä΁‚{wò '럓-#5åé“GØÉöêå‹ÎN¶7--ÿTT_ÏL¦'556¾­©I¦'µµµ¾©xLOâr¹/Ÿ?KK¹ –fu9Ùîææç@NVÆÃ% ‘šüüÉ H¦'U”—w´·'Ó“jª«ZšYÉô$æ»wõuuÉô$«©¶¦«è_'[ò-ìd»“‘öÏÉ–s òrs°“-;#ýŸ“-%YødkooÃ*b55%Ó“ê™u̺ºdzR3‹UýÏÉÖñúUy2=‰Ïç¿xú$ãv2 ”•”ÜÉÌ €¢‚üü{ÿ:Ù²ÓÓ•> €´ä›/Ÿ?üEãü¢;‚ x‚ó‚ x‚‚ b%,AÄJX‚ˆ
+”°(a!"6PÂBDl „… ˆØ@	A±‚ b%,ä먬¬ôññ!C‡^)%%µtéRÁ*•ºÿ~ÁL&ÓÇLJD"-^¼8  ÀÕÕµ¨¨H°påÊ•ï-ðÕã®ñSÊ?{öLFF櫇ü>‚|%OŸ>•””ÔÐÐÈÎÎÆ–p8wwwyyyA™¢¢"SSS*•ÚeCiiiìó¹sçlmm»,|oo¿ –¯[ùZPùšˆDâòåËwíÚ…ýxáÂ///áqqqgÎœ)+++)yÿ`°&&&Ïž={ï*A’’{{{™ýû÷»¹¹@QQÑĉ—/_>cÆƒ «W¯–ˆ½~ýº±±qPP¡¡¡»»{mmmjjª±±ñ©S§ºï¿µµÛùž={ôôôvïÞ-XµtéÒ¹sçNŸ>ýÈ‘#Û·oçp8‹/ŽÇÖîܹóçŸ^ºté¸qã222>´“/^LŸ>}ùòåS¦L	€L™2eÉ’%'N|òäÉ'|Í?0QgL?°FGSS“ŠŠJYYŸÏ÷õõ}úô© …ÕÙÙ9cÆ>Ÿ?}úô+VtÙû¼gÏž±cÇò?ÜÂÂ
+<}ú”@ ܾ}›ÏçGGGóù|“{÷îñùüãǏϚ5+¼páÂààุ¸¿ÿþ›ÏçÇÄÄ`455ýòË/ïû@ JKKSSSµ´´°µ•••¡­­­±±1,,¬{+!!û™™I¥Rß»>ŸO£ÑÒÒÒ°oc̘1|>ßÜܼ´´”Ïçÿý÷ßîîî_òÕÿ0ð<	"d2yáÂ…¡¡¡3fÌððð^uãÆ
+www ðñññóóÛµk‰ôÏÈáp~ùå—¶¶6		‰˜˜˜î»íR€Åb‰Dìz™¿¿MMÍ“'Oh4 ØÚÚ®^½Ûj×®]
+¥¥¥åðáà 0}úôÕ«W3ŒK—.Íœ9ó#GA$MMMŸ>}Z__-0` …B6lX```PPÐëׯ»l¢ªªêííM&“›››±Fb÷ÔÖÖ:;; ‰Dº~ýzMMÍǏ=
+ mmmD"êô|JXÈ×·dÉ##£æææ„„„—/_
+–'$$H¤»wïr¹Üææ椤$OOOl‰DŠŒŒüÈ>»`±X$IBBû‘ÿaݬ­­SSSÛÛÛ¥¥¥åää¦OŸ[\\¼`Á‚W ÂÿŒ#‘HyyyW®\Ù¾}ûùóçÃÃÅ˳X¬qãÆ={öìÊ•+ïÝ	öÐmÜî°°0¬pssóG¢BP:G¾¾,Y²ÄÓÓSP  ¡¡AVV6666222::záÂ…'NœøZ5ª««@^^Þˆ#°åGŽY¾|ùСC7mÚ„-Y°`ÁŽ;lmm?·Š7oÞlÛ¶mâĉÑÑÑ÷îÝ“””Äf;wî ´µµµ··÷íÛ „stjjj
+%;; :::¦L™¢¦¦fbb’‘‘ UUUO£º†…|uuu³gÏ–øí·ß›ššfÏž-))¹xñâqãÆyxxÔ××óùüööv///iié°°0Á†Õb€(  IDAT£ËÞV¬XñÞ‚%MMMØ’ÂÂB//¯eË–M›6­¶¶–ÏçïÝ»×ØØøþýûaaa6lÀJ:;;ca¼7þ+V`Îœ9³iÓ&IIÉÐÐP>ŸÿîÝ;77·ÀÀÀI“&ÅÆÆr¹Ü¡C‡ÎŸ?ǎضoßîàà4wî\III è¾>ŸÿôéÓiÓ¦-_¾|Îœ9Ø5¸’’’±cÇ.]ºtÎœ9oÞ¼ùê¿<AC$#?òòr•µk×:tHÔ± _]ÃB~ S¦LÑÕÕýý÷ßEò…PA±.º#"6PÂBDl „… ˆØ@	A±‚ bãÿ ³U¸ýÕƨ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true_custom_nspi.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true_custom_nspi.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/dcerpc_mapiproxy_server_true_custom_nspi.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,100 @@
+‰PNG
+
+   
+IHDR    
+   ³ ”¾   sBITÛáOà   	pHYs        êe¤    IDATxœíÝg@Ùð“–bE¤wD6t]W\]}ÖX ;+*k[º®Š½°ˆbEÁDAT)†^"E¤ƒ"½CÊû0»yy X¢Œç÷)Lnæþg‡{'™ŸÏ„ê
+èd@$svv¦Ñhd§hFsvv&;Å7¼sçN²StvX°Ðgãr¹Ù]~~þ¶mÛÚoÓa‘>·£Ooìââ"bw”‡ë;õèÑ#%%%uuõøøxb	›Í:t¨„„D¿~ýJKK“’’,!!annž–– 4mÔ¨Qªªª»ví¢Ñh£GVUUUVV~üøqÛ—÷E¼PEEESSóèÑ£½zõÒÔÔÌËË€]»vÉÊÊJHHŒ7®²²’hÜjͪªª»wï~ïS‘âââLMMÅÅÅMLLâââŽ=*--ýêÕ«E‹
+0 ¦¦fÆ
+JJJ§¸¸˜N§_ºtI0v[¿~½´´´¬¬¬““‘¹Õæwdkk;|øp 
+
+¥Ñhaaaíï«O|G:D¼ ¼«‰‚m»ûŽðÑwI__àÀ)))¦¦¦Ä¯™™™––V\\ܳgϪ««ÍÌÌ,--ÓÒÒ¬­­‡
+Æçó@SS3))©°° /×××oûrá¾ ÀÜÜ<""BøÁž={ø|~hhè‹/ÂÃÃ†››Ѹ՚`ýúõzJÉØØØÔÔ”xÖØؘÇãY[[ëèèÐéôÐÐP>ŸŸžž wïÞ=uê”””Tuuu~~~ee%ŸÏ—––>wî\JJJHH‘¹ÕæwtãÆ
+–——·råJ
+
+
+×þ¾ì‡îÿ¯Õ;²lÙ2 ÈÏÏÏÏÏoµ«›O<hÛÝ÷ÖwJLLÌÑÑ‘Ïç¯^½š(XcåÊ•‚C\\¼{÷îâââƒÏçÀo¿ýF< ‚—϶z¹0 prrjõÀÙÙ™ÏçïÚµKEEEFF vîÜùÞ5ÿŶ}J‰Á`´z600 ¬¬¬IF=kÖ¬I“&ýç?ÿN¸gÏžþýû+((lٲ彛/ÜQcc£¼¼ü”””¶oßþÑ}%ùÿZ=»~ýzÁ ¢Õ®^¿~=‡Ã쇶Ý}?ßx ‡:)mmíðððÔÔÔ°°0b‰‘‘QpppBBB]]©©©¡¡¡˜˜ØîÝ»›››srrˆ6âââ‚5^®­­Ýöå²²²Â݉‰‰µzÀçó௿þš9sæ„	/^Ìÿ÷ëVkÖö)A$==½gÏžÏêëë777oܸÑÂÂâùóç7oÞœ>}: 888ØÛÛóx<___ (((•••““Ó××üøñƒœ÷ìÙ ­6íÚµ‚Žºuë6kÖ¬¿þú«¢¢bÁ‚m·ÝW‚=,üccc£ð œœ¬¤¤$ür99¹œœœ   AË÷v÷ÀcXß©'NþøãòòòÄ’.(((2dÖ¬Y/^¤Ó鶶¶ÅÅÅm× //?yòäâââãǏ·}ù'ÆXºté7nݺ%--ý¡5·Ó©°³gÏr¹\333.—ëéé¹}ûöüü|''§eË–½yó f̘!%%%++;iÒ$::vìØ1CCÃM›6	Žaµ¿ùL&³¢¢bØ°aZZZm,òÿZ=;cÆUUUSSÓqãÆ	/_³fM@@ÀÙ³gK>±;j"{ˆ‡º$øwzÒ‘k½Óúúzssó+Vˆ²D"a¡¯ORȳgÏÈŽó?ÒÒÒµµµ7n$;úB4>~Ó!ÔEà!Ôe`ÁBuX°¾wx.áë´Á:LÇïüúl\.WðuªŸŸßê[]mup$§kÇge&e?ª#÷ GXß)<—Pø\B6räHUUU555ÁW1[`ØN0a­^ÕÎnd0ßâœÄíí¶›ßö…­vBÇïöÛà÷°¾Wx.¡ð¹„ `ffFüÁÁømN0l'˜°V¯jg7;vì[œ“ø¡½ÝvóÛ¾°ÕNèø=Ð~{>žKøÝÂs	Û&äñx‚`ü6'¶LX«Wµ³¿Ñ9‰íìímþ‡vBÇî<†õÂs	Aè\B"ñრFÛÛ	&ÐêUíìÆotNb;{»Õæ·Õj'tüøèNÀcXß)<—>pF í	†íôþ¡Wuü9‰íhµùÕñ{à£íqJˆ¾|ç~»Mî0"žJÙö Ž°Ð×÷]KØi7¶­V›ÿµ’wäÀs	B]Ž°B],„P—!Ôe`ÁBuX°B],„P—!Ôe`ÁBuX°B],„P—!Ôe`ÁBuX°B],„P—!Ôe`ÁBuX°B],„P—!ÔeP¼`íÛ·ïàÁƒ °eË–Ó§OÀªU«®]»Æçó™Lf```UU“ÉŒˆˆÈÏÏg2™l6;%%…ÉdæååEFF2™ÌÊÊÊ   &“Éãñ®_¿¾råJ 8sæÌæÍ›àСC{÷î€;v¸¹¹ÀÚµk½¼¼ `É’%þþþõõõL&óéÓ§%%%L&3>>>##ƒÉdfeeÅÄÄ0™ÌÒÒÒǏ3™Ì¦¦¦[·n988 ÀÅ‹ׯ_ Ǐ'îQþçŸ=z 6lØpîÜ9 X¾|¹¯¯/‡Ãa2™>,++c2™QQQ¯_¿f2™iiiIIIL&³°°0,,ŒÉdÖÖÖ,Z´ ¼½½ûí7 8uêÔÖ­[ÀÕÕÕÕÕ þøã pttôññ€…Þ»w¯¦¦†Éd†……0™Ìäää/^0™Ìœœ‹Åd2ËË˃ƒƒ™L&‡Ã¹qãÆŠ+ àìÙ³Ä-Ž9BÜØÎÅÅåĉ °nÝ:ânéööö·oßnlld2™!!!oß¾e2™±±±™™™L&3333..ŽÉd¾yóæÉ“'L&³¡¡áΝ;vvv àååµnÝ: 8yòäΝ;௿þ:|ø0 lÚ´ÉÓÓ V®\yãÆ
+.—Ëd2<xPQQÁd2Ÿ?ž››Ëd2SSSÙl6“É,((g2™ÕÕÕ÷ïßg2™ põêUâF³§OŸÞ²e 8p`ÿþý °mÛ6www X³fÍ•+W `ñâÅwïÞ­­­e2™Ïž=+**b2™‰‰‰/_¾d2™ÙÙÙÑÑÑL&óÝ»w>d2™---~~~Ë–-€óçÏÿþûï pìØ1âÎc»ví"n¥åìì|á XºtéÍ›7›››™Læ£GÞ½{Çd2cbb^½zÅd2ÓÓÓ˜Lfqqqhh(“ɬ««»{÷î’%K àòåËÄM·þþûïíÛ·w¹?
+Á_4•o¤zâÄ	—]“~žjÏgE¾-ÓÌŽdEÓ¥º÷ÑҏdE©iëq»ÉD²¢Yª–VD²¢"â’h4Z$+*,.©0?/’—›ÉŠ
+‹g‡GÇEFE‡Å³#¢ã²³2ÃâÙѱÍMMañìVtoee“aìVTÔ
+Í"£¢{ª¨uSìÉŠÒ1ø®®9’e—Ô]F&’—TQQNt”’”øÏúcâ‰1qÉ		DG•eañ숨˜î22ƒâÙQÑå5õÚfÏ£¤äUD²¢4ôëÉŠ2µ´ê¥¤D¬¿¹©)’Ÿœ•IlHDlBÄsVX<;"&žEôSXP@< „ų#£bòJÞX`EñÅ%ûéE²¢újhѺËG²¢Ì-
+Ë«#YQ᱉qq¢£’âb¢£XAþØ„ˆöXlæË—DþúúzâbfñìȨèºf®†ÑÀHV”‚²J÷Þ*‘¬(m#ÓŠ&n$+Ê|x¢œ¼<±þêª*bG¥¥¦D²¢ÂãÙÿv—C¼¥oßë—””²ˆgG°¢KÊ+uÍ-#XQ2r½5t"YQýušÄ$#YQÆCûª”ëçr¹‘¬¨°Ø¤¼œ×‘¬¨°øäÈßñˆ˜¸HVtX<;<*6/ç5±~G<èÓWÅÈ’ÉŠn¡1ÔôM"ž³”Ô4ÄåzF²¢ôÌ•T×G²¢†Ä&JJJ½+-%vTb\Â?ïHL|Ä¿¥¥°‰7¢¦ºšX¿œ¼üÀxvdTLUC“¦É V”lÞr}Õ"YQš&5\z$+jà°Š=zF²¢Âbê#YQáqÉ/Ó¿QÄ;ó))"ÖÏïžW®mß°>(ð¾……•ïšâyÑkÅšudA}¹’¢"¿kÞûv»¨««S¹`@X<›ì¡¯`¤¹1PûÖþýûÇZš“!$’”äÄуM###@Œ8TIIâââiY#S3²ƒ „¾FWìÑóçÉ?þðÃTžÖ××?~+¯ @v„Зãp8µ55“F
+§ò”ðøñã¿LKv
+„H^¾H™:~tLLPûk
+?ýôSmì!‘¨ôSÛâò§––Pû »²²²Ž¾Ù)B"‘’–ÖÕ7‘‘j¬³gÏ.™ý+Ù)B"ÉÊx¹pÖôÄÄD ö”pÖ¬Yy²S „DÒ_}ÀëëëµGXbbbd§@‰„N§‹‹KÐét vÁòññY·r)Ù)B"yå´Ü>55 ¨ü=¬’’’{!ÏtôôÉ‚úr
+
+y¹9³mêÞ½;•GXåååyyd§@‰¤©©)?/·¡¡¨=%ô÷÷ß½uÙ)B"ÉÏËqÙ¼!##¨=%¬©©yݳwo²ƒ „¾\KKKeEù”±£$$$¨<ÂJOO}ò˜ì!‘TWU†>~TVVÔž>zôèä!W²S „DR\Txüàþׯ_µ§„\.÷Y\2ƒAå/Ç"Dy|>ŸËåZ[˜Ñh4*°ÂÃÃ/œ>Ev
+„HÞ¾)9çñw~~>P{J˜pÇï:Ù)B")/+»ã{½¤¤¨=%¼¦;BTAýkºøÓ…ì!‘æçíßµ#++¨]°
+
+
+ØI	d§@‰¤¾¾ž˜PSS8%Du	ÔŸúúúnY·†ì!‘ä¾ÎÞ´Ö1--
+¨]°šššêêjÉN	Ç««­år¹€SB„P—@L	©ü-ðK—.¹:ì~Þ‹ì äóüûäKv"Ù)P—1ÉvúøI“ÉNñW™®»w^õ¾bbbBå‚õÃ?()+“¢S(,ÈÏÈÈ?~<ÙAPàëëka5Šìÿ#.!¡¤Ü§[·n@íÖ´iÓz¨i’¢³0`À7ÈN:;>ŸO\=½óP믾Ëõ®®.Pû »»»ûÛŸÈNIzÚ‹Y?OŠ‹‹j,MMÍ¡V#ÈN‰ì?1JAA¨=%´±±‘êÙ‡ì!‘ôUé·vã– µGX‡š4rÙ)B"yÁN¶±Âb±€ÚkèСs-&;BH$={÷ž·ÈNEE¨=%´°°¨å‹‘!$’ž½zÏœ7¿oß¾@íÖáDzþ^ºóx<²# ôM¼HIž4rXTTP»`Mœ8qݦ?ÈNÑAŠ
+
+þܶ9÷uö7í…F£IKK÷/¡ÑhÎÎÎ àïﯡ¡Á`0úôésäÈâ)F§Óõõõ‰C‚Ƭ¾¾^UUõܹsÜoGn/ŸÏ744Ü»woÇt×ñúªôsþc;õº«««›±$;E駦ÆçÃÂYÓ]¶lü¦e«¡¡ÁÍÍMxɲeËtuuÓÓÓ¯]»¦­­-XøòåK:¾téR{$Îzý²öžžžsæÌ1ÃçÊÏÏ߶mÛ¿ü³6™ÇãÙÙÙíß¿¿®®î‹{ìÌdde
+±”——j,ùÓ§’¢ã,´_
+ .œ5ÝeˆoT¶´µµOž<ÙØØ(XR[[›––v÷î]yyù)S¦eddtttÆŽK\ä½Ö¯_/---++ëää IIIƒ–077OKK£Ñh£FRUUݵk—­­íðáà 44”F£………µj Âí]x{{1BJJJÐ@EEESSóèÑ£½zõÒÔÔÌËËÛ°aƒ’’‡Ã)..¦Óé—.]j•“F£9RUUUMM-''§mr6zôhUUUeeåǏ€ªªêîÝ»?k{…7Á`´ÚÞö÷MUUUPPЗ¼£^ÆË´9¶?ÅÇǵÖôéÓw¹";EÇQS×k3‰F£ñx¼'ƒ¿QÙš2eŠ¼¼ü…Kœóóó×®]kjj*<âp8			jjjZÕ©S§ÜÜÜX,–­­- ,Z´ˆÁ`$''ËÉÉÙÙÙ@QQѽ{÷–-[¶`Á‹•ŸŸýúu
+
+#F´m,Ü^ЛÍÖÒÒüXWWwãƍììl//¯;wîdgg_¾|ÙÞÞþíÛ·AAAþþþ’’’¿üòKÛ¨µµµ>>>ùùùÞÞÞm“@MMMPP²²²££ão¯`Ž;Öj{Ûß?Ä6&''¨ë.MM]cÏÁ£zzz@íO	»wﮨأ#{,ÈË»~¥õÿçõïÅ‚ˆcðO=|ò0xÌ›¯8Y ÓéëÖ­;|ø°`ÉŽ;‚‚‚~ÿý÷S§N<x Ž?~âÄ				/¯^-ã?þpqq©®®^±bŘ1cRRRh4ÚàÁƒ›››‰«ýôÓO&&& ðóÏ?ËÉÉ]»vÍÏÏoÙ²e4­mcáö2jÔ(bä"xPQQ¡££3zôh//¯êêê©S§ÊÊʶ}¡µµµ••Ѿmr 1b„¡¡áÈ‘#Oúàå>º½‚MÐÕÕݱc‡ðö@;ûGxÀK=C¡‡¢¸¸8P»`yyymݺõItÇ]ÖýÝ»··}¯÷ìÝ[B\¢Ã:Æçÿßg…|ÏçÇEG))÷é.%ùµzY¸páöíÛ?®Y³†Éd6LQQ±©©‰XÈd2·lÙÒ·o_IÉö«¯¯ÿøñã8;;ïÙ³ÇÐÐPLLl÷îÝÍÍÍ999k×®%~G [·n³fÍú믿***,X  ­Í팍‰›ÄÄÄZ= þòìííy<ž¯¯ï{£Š‰‰Uƒhß*9 „‡‡§¦¦†……	Žâ}îö
+oBÛím»ÉÂû‡ØÆö‹uו•¹r1ÓT'bøðáT.XóçÏ—SVéø~ÿ:tLÏÀ°ãû€³§Ü.yž ÆçóØ-ýù—é{wn¯(}óµz‘’’Z½zõŽ;ˆÓÓÓmll*++544ÜÝ݉…òòòÄÇ:í &>Ä1‹/ÚÛÛÛÚÚÊËË/Y²¤Uc&“yúôéaÆÓŸö̝;wË–-
+
+
+Äa¬™1c†££#NŸ4iÒǶþ=ɉí<yrccã•+W¾Åö¶ß>88X^^þÃw9´´ÝÎ]266j_q4##Ãï^ЈÑc:¬ÇÄøØß–œöò!¥`ÕTWÿú“MC}= (öèA”*	‰n à²ecEéâ|÷ïJCCƒ®®îΝ;Û)jD³#FXZZþý÷ß_ЍF[¿~=1îx|>ßÈÈhþüù›7oþ*k£Óé«Ö:ÿg>Sôµ}ÕÕUIñqË-PTT¤òëæÍ›Û:vJH®ëÞ^
+õõŠ=z.°s”ªïœ””T^^ÞG›IKKëèèlܸ „ç°ÁÁÁ£F}ù¥ì¾âªÚA£ÑRSS¿Åš;‰¼œ×¬w²jAñ)á²eËÔõÉNÑAjª«C?\³a3–ª/ <Ïø‚Øš¦PûXx‡ÑÑÓ÷¹`nnÔ>èž››£¢úÁÕ©¤®¶öµ›íZ‘‰®®¶6.&zÌÐÁ’’’Tþý
+
+:¼÷O²Stå¾}±Z!J*,È?¸g׫W¯€Ú#¬uëÖ™YY“!$#“ÀgÏ---€Úßt‰‰¹yÍ›ì!‘”½+õõ¹\\\Ô.XÏŸ?¿|þ,Ù)B")}óæò9Ï‚‚ ö”ÐÙÙÙrìD²S „Db`lò02f¨¹1P{„õðáÃcö‘!$’¢Â‚£û÷fggµVVVÖó°gd§@‰¤¦º:"ì)qÚ9•§„+V¬0²ü^.‘üQïÞ½óôô$;êì:á¹zºú727j¬Û·oŸt÷Ø±×•ì B^^žƒƒÙ)úly¹9žŸ<uò¸®®.•VUUUqqÙ):…Û]ÖoÞJv
+ÔetëÖ‰Îîjin.)*$®\D債páÂÆæd§è$%%áÃ×¥B¨3ÓÔÖ9íåcbBõO	½½½×,³#;BH$¯_eýæ°$%%¨]°$$$¤¥»“!$:.Ý]š¸H,•§„¿þú«Ò ]²S „DÒ_cÀ¾£'õõõÚ#¬3gÎ,œùž;  „ºÌô—ógØ&$$ µ–ŠŠŠ¡‰)Ù)B"‘––621%îfDå)áäÉ“e•UÉN‰ŠªÚ¦»ˆ›qPy„uìر©ãG“!$’´Ô”)cFFGGµ–™™ÙÏ¿üJv
+„H{Lñ«’’ 0ÆŽKvž/4yòd᣷5räH¾´\‡åA}½••íV¬VSS Æ“'Oôôô>zÏËÎ&44ô£™]]];øÎÏ¡¯.•´r13"âß;?ÛÙÙµ?Té„ôôô>Úfܸq%åU¦óklh¨¬¨ ;êJzôê%..Nv
+  å>*Žë7¨««µ?%ÔÓÓ=nÙ):…gOBþÜönŒ¾ç¯újj됝 @N^~Ìx›ž={µ–››N	…>}Z^^žì¨³KJJÚ³gÙ)þ'=-õÿ¦„T5uêÔF#;E'2eÊ”>}úuv?üðÙþªšúŽ¿öëèè µ¿ÖУGµþêd§@‰¤[·njêRRR@í‚uþüù¥搝!$’¬Ìt»¹³’’’€ÚÇ°æÌ™#¥Ð‹ì!‘hÐ:â~ÆÐШ=Ââr¹‡ì!‘ðù|‡C܃Êëúõë׬";BH$9¯_ýî¸âÅ‹ðF#¾}*xð)‚ƒƒwîÜùµ2´bggwÎçÆ7Z9B¨chéè]¸ægffßb„•ŸŸ¿mÛ¶OlìââòÕ3Þ¼y“™þò­¼³áñx5ÕÕd§@èëklhÈLYWW¢,6›=tèP		‰~ýú•––
+–«ªªîÞ½ ’’’,!!annž–– 4mäÈ‘ªªªjjj999 pèÐ!b¹h[ô~{w~jéìêètú?]þܶ%?/—ì,}Mù¹{¶ÿ‘™™	¢,&“YVVÆb±|||$ßw©E‹1Œääd999;»î^S[[ëãã“ŸŸïíí
+ Ë–-€üüü/ŽÑŽß~ûífÐão±æΉi¿ôaà½3l¿ l©©©Y[[[[[7 úôé³iÓ&â©M›6_7
+		6lبQ£†êîîþ¡fjjjcÆŒ5jÔêÕ«‰{É	Ö?xðà+W®|¥Íýˆ†††9s>ûK-ļ£n›|Îœ9žèëÓ30ºóð©……ˆòµ†”””¥K—š›ðÆ)))4mðàÁÍÍÍ‚û_[[[[YY@EE ÈÈÈ @¿~ý¾8F;Ølvðý€ÿÌg~‹•wBZ:ºV£­ÃŸ>yxïQÐýñ“&/tX¦ªÖÿS^«¨¨øôéSÁJJJÄõÒ  ::š¸‘³³óÇ{ôèÿ¾}ïm¦¨¨øäÉ 8xðàž={víÚ%XCCÃðáÃçÍ›÷YÛÅãñèôOúÏ*ÜÒËËkÚ´iŸÕÅL™2ÅÛÛ{É’%dUeyùàûƒôµTTT¾|„eddœ^SSÓ¶¡¡¡±±ñõëׯ_¿~àÀb¡˜˜1$J˜„„ $''qŒv<yòäÔñ#ßb֒͝e+Fãóù<ïуÀ/m,--Y,ÖóçχJ,‘••
+		!Þk…5ptt^R__ß½ûÿn¼–““3vìXkkë?ÿü“øqâĉ#GŽ´²²b³Ù `ll¼hÑ¢9sæ8::†‡‡@ll¬ƒƒC;-+¿}ûö„	Zµ		Y°` ¬^½ÚÏÏïÅ‹VVV£Frrr"^Ååríí퍌ŒÜÝÝÏœ93fÌ###???Áj
+‚ƒƒ
+,X`llüÞüÂÞ›ÙÞÞÞÔÔôôéÓ.466öôôlµO>Ô,$$ÄÐÐpþüù\.W|Á‚†††Ä °±±¹uëÖ'¾ÝYII‘û±Ã¹¹¹ ÊëÂ…C†éÕ«ñ%ÔV.^¼hoookk+//ÿ¡2?cƌ˗/›šš
+†`Ÿ¨±±ñÒ¥K×®]k¿™D·nG¶þCúvZš›ÀÑ~1‰wúfˆ‰q¹\>ŸÏãr ø~À£ û½Gyy¹µµ5 ¨¨¨³¶Ù³gŸ?žÏçÛÙÙÝ¿ .^¼¸oß¾;vÈÊÊž<y’¢·m&Э[7Á÷àˆõ¿}ûvúôéÍÍÍÄ?ªððð}ûö
+2„x÷ûí·#GŽäææ:88—••mÛ¶MSS322ÒÛÛ{Ĉ>>>sçÎm§¥ ÷’’EEÅE‹H™­å    IDATµjéïï¿zõêÚÚÚ3fL˜0ÁÍÍÍÌÌŒÇ㯪¨¨pqq‘““>|xTT”ƒƒCyy¹ÍŒ3Ú6èÑ£Gpp0Ç#ŠuÛTÂ{£í³Äª”””^¾|©  0räHIIIá}"è±U3999⟁àÿDyyùÞ½{y<ÞâÅ‹ÇŒ ½zõ*,,üœßNÊÈÄìY\òpsc¥`™šš
+¦ðïˆIø©©iLLŒðKÚ¶4hP^^ÞôÎãñ8Nçü^h«Qä\KžÇãùûùÖ××ð@LLŒËåš
+ll:ØÞU+ZM	ÀÔÔ”¸×®‰‰	±D]]ýÔ©S ””dggûÞfMMM£Õú_½z5gÎbÌ2mÚ´]»v¹¹¹Í›7ÏÆÆ&55uåÊ•Dûææf èÙ³'Qƒ†¾víÚ–––ðððØÛÛ¨e+m×éè訥¥E|
+T\\üχåÿN${ôè¡¢¢B,¹uë–‡‡FþLI¸Aee%q4ƒ¸FÛ¾ÚO"XÕ€ˆ\.·Õ>ùP³ŠŠ
+â
+œ‚ËoÈÉÉaÊËËÛî‡.­¤¨èæuÕ];ÕÕÕ»ê©9ÒÒÒK–,ñôôl§Í‰'víÞÝÁÇݝl3ÈbÈ2G§ŽìTà¾ÿíººZ  Óé<ÏÔ|ÝòUÆfƒïßû‚µ-Z´HøÇôôt]]] PVV·j&ð÷ßÿø㏭*((÷  ƒÁpuumjj2dˆÁ±cLjɶ´´€P€±cǺ¸¸XYYÑéôö[”••ËËËÛ¶\·nÝ™3g6mÚtûömeeåäädÁÁ/á¬÷ìÙ[__/| V¸¼¼|QQÇ«ªª€¶}	kû¬`UÂëlµO>ÔLAAø¨ŠèšxPXXÈãñ³õÒÒR¢Àuu••î¬s\Õ…Ö§ptt4³²&;EÇáp8ç=܉Çfƒ¥ê_+˜@@@ ñ`þüùÂm\]]Ùl¶¤¤$‡Ã9xð `y«fåååcÆŒár¹ÆÆƇ^?ŸÏohhØ»w¯ £'N466Ç•Ž?¾jÕªÚÚZ:>zôèV_Л;wîÀY,ÖG[lmm>|تeŸ>},,,ìííKJJ<<<Ž9âàà@|óæèÑ£­Ö0mÚ´Ñ£G›˜˜wÄkkóæÍãǏ8p 1Ìi?Õ§dn»O>dË–-'N433STT$–(**nØ°!!!áĉÄ’àà`j|ì g`xçásc  Àºâ%’GŒÑþ+  àïÓž›wîî°T ðëd›‘ÖcÖl áòž÷ýoïsÙ>hˆå’e+[•ªàû÷þܶ¹¨¨èû¹V}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuôeæÌ™sîÜ9âª,ŸåÁƒ“&Mê<W-ÈË»èéqâÈ!mmm*°¾«oºs8œTv²ÛÙ‹Ÿ>ª¢6iiéoZ­  ,,lÇŽ¥¥¥Ä÷Ÿ[©ªª²µµüèââ2zt‡ÙüÖ›ßaÿ÷Mw*,;;;CÈNÑAÄÄÄ~ÿc;Ù)¾/ÖÖÖ¡¡¡zVNN®ÕçèËhéè^¸ægff”¿ZÆ߾—«5|£Ó›"]Nv¶óêå_ùj
+Çãr;ã÷BŸŽ|â«…@í)áìÙ³UtÉN‰Æ Íï⊣çÏŸwÀkº#ÔÅeeüïšîT.X=zô诮Nv
+„HºIJö×@|?ƒÊS©S§*ôÓ ;BH$ªjý·ïÙGýûº¹¹Íüi"Ù)B"I‘:}Ò8âÜU*°ôôôF›@vŠNdöìÙÄejGYYÙþÏòòc&L$.ÄFå‚5nÜ8	…Þd§èzöêe1tXCsKCsë“rj…ÑMÒbè0i¡+—‘«O_Çõ444€ÚËÕÕuë¶mŸÇ’„|æCÌ-¾—/ý#ŠIMNZm¿(,,lØ°a ¸ÿ~g~Ô»wï>ÚfäÈ‘vËWv@„з£¤ÜÇ~¥#qý/†¢¢bRRÒ{/ÚÉ׃o‡™™Yy·c „¾…=~ž>ƒ¸c £Ë­>ݱcǶnÝú$º½+m"„:¹´TöÊÅ̈ˆˆáÇSùÖäÉ“«ñ3B]›J?µM;viiiµ¿‡¥¢¢bô±›/ „:9éîÝ
+ÿ¹î+•Ö™3gΚNv
+„H2ÓÓü:-!!¨ýµ†™3gŠuÿì!‘ôW°ÿØI}}} öK\\\JJšì!‘ÐÅĤ¤¥ÅÄÄ€ÚËÛÛÛi¹=Ù)B"yý*ó7‡%Äí/©<%\¸paÏ~êd§@‰DSKç´—q§^*°ªªªŠ‹¨p«n„¾gÍÍÍÅ…@í‚uûöm—-ÉNI~^ÎŽM¿gdd µ§„+W®Ô21ÿx»ï@}}ÝA—md§@]‰Ãšõ}úvŠ;ÝëêÜx0hÐ  vÁÊÌÌŒ|úˬÙd!‡Ãyôè‘¡¡a¿~ýÈ΂:»wïÞÅÅÅͳ_NvTWWE„=µ27îÓ§•ÖǏ܏K`íÚµvvvd§@q«z²SüOqQáÑý{gNBñ‚åììla=žì!‘™<z3tˆ9Pû ûóçϽÎy’!$’Ò·o.yž)(( j¬ØØØ[×®’!$’²wïü®^)..jt_»víàÑ8%D¨k302|öÜÒܨ=Â
+
+
+:ô×n²S „DRX`Ï®W¯^µVnnnBށ¡®­®¶6!6ºªª
+¨=%\¶l™Åp²St>ŸO£ÑÈNÐW¦£§ï}+ÀœòS›7oný}-Ù):ÎU¯‹÷îÜâp8dAèkÊËyýÇz§—/_µV}}}Ue%Ù):艓ïýsî´)X¶•p8œÊŠò–– vÁš?þ‰3çÉNÑqz+)ÿdûKIqÑþ];fÛNþ¬²¥¦¦fmm=pà@///á%ÖÖÖûöí{o 		6lبQ£†êîîþÕ·¨¡¡aÎœ9Ÿû*33³¯žD”.¶nÝ:bĈ   á…sæÌ!.?€>j€–¶Û¹KÆÆTŸzyy­²[HvŠ5‰=ƒÁ €woß~VÙRTT|úôixxøÁƒ…—<}útÓ¦Mïm  ÎÎÎÏž=c±X³g·w
+ÇûÄMnéåå5mÚ´O|açÄãñîÝ».8Ù…ØÀ)S¦x{{“­ËÈÎÊ\±x›ÍjtïÞ½{=;¾_vR¢û±#ß/ACS++#ø« ÊÖùÓî³,ú”×ÖÔÔHJJ~zYYِI“&ÉÊÊ*(( @NNβeËêëëy<Þ©S§Œ
+tñâÅ°°°#FÄÆÆzxxœ9sæC-®]»F¬ÿöíÛ—/_nÕ²´´ôüùó^^^«W¯3fŒ¾¾¾ƒƒƒ˜˜˜¹¹ùÑ£G€ËåÚÛÛ³X¬U«V1ooïÒÒR—3f €±±±¥¥%ñìŠ+‚ƒƒœœ
+”˜˜Èf³Û¦ÞüGGǁr¹\bc—,YÂãñƏ¿uëÖVûJ°áÝ»w·¶¶>þüÔ©Shcc³dÉ’%K–|Êûòc0Š=zˆ‹‹ Ï瓝ç
+‹gwpKæÌ|Wú¶ƒ;ÖÔÔÔP_/ø‘F£ñùüZÚÙY™žžž:ùYMMMCC#))ÉÇÇçÇ$–0  þøã	&´m  999ûöí{ö왬¬ìÉ“'-,,¦Nºoß>ƒÜÜ\‡ààà¾}û†……½yóÆÛÛûäÉ“ëׯŸ2eʘ1c>ÔRSSSÊÜÜ<>>¾mK'''‡S[[{áÂ…	&8pÀÌÌŒÇãÑét èׯ_TT”œœÜðá㢢¤¤¤ÊËËmllbcc[=›œœ<fÌ///7tèТ¢¢¶}	辰cÇ^¸p ˆÆ—/_ÖÑÑ2dÈ{?ŸlŽ™™Ybb¢ðá­á­þVˆ“ŸÏ_õÕÔÖ!;ËÿŒ47j°<<<öüµ÷Ê­»Ùé9ŸÙ]+---sl'766òy<111.—k`dl·b•Ž¾Á”1#Ûy¡¢¢bhhhDDÄ¡C‡ˆzDÌÛi  êêê§N€¤¤$;;»ØØØÔÔÔ•+WÏ677@Ïž=555555×®]ÛÒÒ~àÀ øP˶ÙÚ¶tttÔÒÒJKK€ââbâˆQ­  G***Ä’[·nyxxÐh´ÒÒÒ¶Ï@ee%qÉyyù÷ö%¬¢¢BMMMÐxÚ´i»vírss›7ožM«Æm7çCˆÚ—ñ2mÇFgÿ;·ÍÍÍ©\°ÔÕÕY%;E‡
+
+ðûæ
+ñß^ÏÀÐnŪÁ–à  ººêS^neeµ}ûöììlblõÑéé麺º  ¬¬LÕ
+Ž;F<ûÏÇ:ÿÖ‘±cǺ¸¸XYYKÚi) ¬¬\^^Þ¶åºuëÎœ9³iÓ¦Û·o+++'''›˜˜FXƒ={öÄÆÆÖ××››ÿs)ÇVC!yyù¢¢"G|/±m_ÂòóóàŸ/12®®®MMMC†i[°ÚnŽð’ÒÒR¢n¢’‘•l9”ø'Aå‚5qâDé^}ÉNÑqZZZ.=
+ Æ&vËW¥êsÙÙٝ>}šødð£
+\]]Ùl¶¤¤$‡Ã!Æ?~|ÕªUµµµt:}ôèÑ...‚Ν;wàÀ,‹ø±–¶¶¶>lÕ²OŸ>ööö%%%GŽqppÃ6mÚ´Ñ£G›˜üsßà¶6oÞ<~üøí§Ú²eËĉÍÌÌ   àĉ,ø„]û‚ƒƒ»úç	¦¯J¿õ[¶ÿE¨|ëðáÃ;vî¼ÿ4‚ì äî-¿ »w/[ѶTUWWM3²cXS}}½Ï·ë‚Ë劉‰åååÍž=;22òÛuÔÊœ9sΝ;'%%Õa=~ºÎvëE
+{í
+‡'!!–––Ta
+2dÖÜÏþ××uõUéçvîÙ)¾&iiéoZ­  ,,lÇŽ¥¥¥‡jõTUU•­­­àG—Ñ£G¿w%ŸÞRà[o•ôìÕkÖ¼}ûöjO	---èÝÈNÑq
+±$;B×cmmúÞ§äää„?vhǧ·D_ g¯ÞóÙýóQ	Ùa¾¡C‡ý8êKŽã „:)É6VCˆ£ŸTaÙØØ”Vב!$’¾*ýÖmúƒ8èNå–¦¦æÐá#ÈN‰¬ìC­F§RP¹`¹»»Ï™öÙ)B"IùbÖÏ“âââ€ÚSÂ_~ù…ÃøŽº#DIjýÕw¹"¾¢Lå–¬¬lo%e²S „DÂï­¤,!!Ôa]ºtiëÖ­O¢ÈÒYÄÄÄÈÈȐuvIIIdGø?ÙY™+3µ"†Nå‚5oÞ<Ù^}ÈNщxxxxxx¡Ï£¡©}Òó‚‘‘P{„ÕÔÔT[[KvŠNAFFÖ÷~ðÇÛ!ô/E2®%÷^\.§¶¦†¸%•–¯¯/N		t:ç¡.*/çõ¦µŽ#‡˜>œÊ'?———=‹TUëOv„ЗkjjzSR<}Òx)))*J˜ŸŸÏNÄáB][}]mrB|uu5Pûk
+þ|ÏU–B]HaA¾ëîÄ­ê©<%lll|/ó+·!„º.—[_Wg3Â’Á`Py„•pǏÌ+¬#„DW^öîŽïõ’’ ö”0<<üÂé¯wO„PGz[Rrþ´;q5}*O	ŒÛ|!„¾â6_Ta=zôèÄ!W²S „DR\TxìÀ¾×¯_µVzzú³'ÉNIue峐Çeee€SB„P—@ý)¡¿¿ÿ®?6‘!$’ü¼\—Í222€Ú«¼¼¼ /—ì!‘456äç544 N	B]õ§„>>>ëV,%;BH$¯³_9-·OMMj,ƒ!ÑM‚ì!‘Ði4qq	:8%Du	ÔŸž={vñì_ÉNIVFú™¿$&&µ–²²²®¾Ù)B"‘’’Ò50$SB„P@ý)áñãǧٌ%;BH$/_¤N?:&&¨]°LLL~üy*Ù)B"QPPüñçi½{÷jO	ù|þ³¸dâÓP„P×ÅãñF6j°öïß?nè ²S „D’’œhma	 b;wî$;Ï·"!!!!+ghlJv„З£ÓÅzöêýóäeee©<%¬««{Ýyn`‹ú§ºªr²õqqq*O	Oœ81ãÇ	d§@‰äå‹”i6c‰O	©|«úŸþ¹žKv„hú©öߺ{¯¶¶6Pû {¯^½hi“!$IIIMmmiii vÁ:wîœý¼ÿ!$’¬ÌôųMJJjO	ÿóŸÿt“S$;BH$ꚇÜ<€Ú#,4Ù)B¢üS¹`]½zõ÷Õ+ÈNIÎëWëV.{ñâPûÔœ·oßÞy¦¥£Kv„Зklh(ÈÏ›õóÝ»w§ò«´´4'ûÙ)B"ill|ý*«¾¾¨=%¼{÷îží!$’‚üÜÝ[7gffµ§„µµµ"£{ôìEv„Зkii!NÍ‘ ò+---$øÙ)B"©ª¬|ü ðÝ»w@í)áãǏÿ>zˆì!‘”ž<|0''¨=%Äø!D|>ŸÏçdB£Ñ¨üÇêù÷	²S „Dò¶¤äôÉãyyy@í)arrò½;·ÉNIyyÙ½;7ß¼yÔžÞæ!ª þm¾îß¿¿×²S „DR˜Ÿ·w綬¬, vÁ***JKM!;BH$õõõi©ìššÀ)!B¨K þ”ðƍ›Ö:’!$’Ü×Ù~[•––Ô.X§©±‘ì!‘ðøü¦¦FÔ¾/¡±±qvAÑ«Ìm]=_Ÿ+oß¾Q éuîLcC£J?Õ3nÇ%$ºÉþðÃy÷ääi4ð:wFI¹oMuÕU¯ê4‹
+
+|}®è¿LM½ã{ÝÜÂ2†õüqp ©ù ÐG1Ï#
+M‚ü_¾HÕÑÓ¿uýjQaÁ M-ï‹çjª«Uû«Ÿuw£Ñh=zö<ëîÖ]FV\\â’§GÏ^½¼/žSí¯þöí›W¼´õô_efÞº~Õdà Ä¸Ø  ÿƒ-ÂCŸD†=325{x”¨g`x÷¦oîëlMmëW.•—•õ×иxƃÃiQêÓ×óï’’RÝ»Ë\8í.¯ Èãr/Ÿ÷ì£Ò¯¢¢üÚå‹´tòr^ß¼æmhb–’œèÓwÐKVDØÓǏLš?yø >6ÆÀÈø¾ÿíÌô—Úºz~W½ß–«м|γ¾¾®ŸZÿÓnÇ†¼¼Â9¿e£Óé^gÏôVîS[SsõÒ…þꊋ
+}}.ëe¼|qûƵƒ‡ÄF±Ý73ü,äqÔóCcÓ÷°uõ
+nû^/ÈË ¥íséBuU¥Zõ³§Ü€={õ:ë~Rº»L7ÉnÏx(öìÕÜÔä}á\?ÕþïJK¯_¹¤­«—ý*ëÖu3ó¤ø¸ûþ·Í-†D>
+}bl:ðñƒÀä„x=C£»·ür²_iéè^÷ö*+}×_cÀ¥³§›ššú¨¨œq;.ÑMRFVöÂiw9yù¼§r_•ªÊÊk^54µ
+òóü®^102IKaßñ»>hÈШÈð§ƒMš?}e`dx÷NÆË4=ý›×}Š‹44µ®\8WW[£ªÖÿŒÛ	1†˜¼‚â¹Sn22²†ø¥³§{õVª¯¯÷¹x^M]ãMqñ
+ï˺ú†™é/o߸f6È">6:ø^€Ù ÁaOCXáaF&¦Á÷沈“uõ
+îøÝÈÏÍÑÔÖ¹êu±¢¢¼¿ºÆ…Ó§8\No%eÏ¿OHIIKJI]<sJ±GÏ––æ+ΪôS+{WzýÊ%MmÝÜ×Ù7¯ù™LIJ¸}ÓÜbHdس°§Í>JŒ‹Ñ74¾wçVWùÓ=vüO¶¿65j°  "ô)+" B‚ÄÇD@àÝ;©ì$ ð÷óÍÊHojlò÷ó-ÈË­ªªò÷ó-}û¦ôí[?ßꪪ‚¼\?ߦÆÆW™þ~¾|>?-…x× bbB>  VDXDèS 
+yËz Á÷ï%'& ÀÝ[~/ÓZZ8þ~¾¹¯³kkküý|KŠ‹ÊËÞùûùV”•øûù6ÔÕçd¿ò÷óår¹éi©÷n߀ä„ø‡÷  †õ<ìÉc {ú$*2 &ÆÇÀ=ÿ[i©)<.×ßÏ7;+³¡¾ÞßÏ·¨  ²²ÂßÏ·¬´ômI±¿ŸoMMu~nŽ¿ŸossSVzúÝ›¾ ÀNL|pï. ÄFG=} ‘a¡ÏÞÀ“GÁqÑQ tïnjròÿvTS“¿Ÿo~nNMuµ¿Ÿï›’â²ÒR?ßÊÊŠÂü|?߆††ì¬,?_—–ʾç6 $ÄÅ<
+ VDxxèS xò8†õ ÞKNˆ€{wn¥§½àp8þ~¾9Ù¯êjkýý|‹+ÊËýý|ËÊÞ•úûùÖÖÖæ¾Îö÷ómá´d¼L»wç& $%ÄßÿgG…†<€ˆÐ'¬ð0âOˆ€@ÿ;i©l>ŸOì¨Æ†z?ß‚üªÊŠÞñ7oüý|««ªóssýý|›šš²2Óýý| %9)(À âc¢C‚ƒ àyسÈg¡ ðôáøh ß»ËNJ€€Û~™/_¶47ûûùæåæÔÔ;ªä]i©¿ŸoEyyaA¾¿Ÿo}}ÝëÞqÎËÔÔ{þ·  ).îу@ ˆ~þÏ;þäñ¿ïøý¤øx ¸}3ýÅ.—ëïçû:ûU}}¿ŸoQaÁ?;ê]iIq±¿ŸomMMnÎk?ß–ææŒô´»·ü  %)áÁ½  ˆ‹b…>~Ôåþ4Ñ?莢Š°BT‚!Ôe`ÁBuX°B],„P—!Ôe`ÁBuX°B],„P—!Ôe`ÁB_AQQÑܹsi4ÚÈ‘#…—Ÿ:uJ\\|ÕªU‚%fffÇŽüXVV6wî\ƒ±|ùòÅ‹[[[³ÙlÁB''§÷6øêù…{ü”öYYY’’’_=ú8>B_Cff¦¸¸xß¾}###‰%gܸqÝ»w´ILLÔ××777oõÂnݺ¯_¿niiÙjá{|‹ü‚^¾ncôá}5t:ÝÉÉiÿþýď¾¾¾Ó¦MnpéÒ%Ÿ/^¤¤¼ÿÒÕúúúít¡¯¯Ÿ””dii)))yìر1cÆhkk@RRÒ/¿ü²víÚÙ³g—––þþûït:ýܹs:::Ë—/×ÔÔ7nÜ›7o=z¤««{ñâÅ÷®¿¡¡XùáÇ5448 xjõêÕL&sÖ¬Yîîî»wïæp8Ë—/¿|ù2ñìÞ½{™Læš5k&Ožú¡•deeÍœ9ÓÉÉiÚ´iëÖ­€”””_ýõ·ß~›6mZûÛŽ p„…¾bÐQ]]­¨¨˜––Æçó—,Y’™™)aµ´´Ìœ9“ÏçÏš5ËÙÙ¹Õ‰ÇGý駟øa
+233i4Ú“'Oø|¾§§'ŸÏ××׏‰‰áóùgÏž7oŸÏ_¾|ùƍ½½½ïß¿O,Ÿ;w.ŸÏ¯©©YµjÕ‡òh4ZZZÚ“'OTUU‰g
+
+h4ZccceeåÁƒÛŽ°®]»F<333{ïJø|¾™™Yhh(±7&MšÄçó
+
+
+_¼xÁçó'L˜ð%»þ{ »`"J‘••]¾|¹««ëìÙ³'L˜ üT``àĉ`Á‚K—.Ý·oŸ˜˜ñ‡Ãqrrjll€óçÏ·]m«UUUt:8^fggWRR’‘‘ann –––[¶l WWW33³ººº'N ÀìÙ³7oÞ\VVvóæÍ9sæ´¿t:]OOOLL¬¢¢‚X¢¤¤dff6bĈU«V9::7õÖ§OŸ…ÊÉÉÕÔÔ¼zõê½+)))INN¶²² ƒXRR’––æáá x—òÂ‚…¾²5kÖhkk×ÖÖúøø¼~ýZ°üêÕ«222l6›ÃáTWWÿøãÄSãèÑ£í¬³Uƒªª*ƒ!¨wü÷]ÓMFFÆÜÜ<44´¹¹YBBBZZzÖ¬YçÏŸg³ÙíoƒÁ  íW‹c0111ýõ—ŸŸß‘#G„Û×ÔÔLš4)11Q[[;++ëƍï]	F£µêîàÁƒDãÚÚÚöƒ!¬èè+ëÝ»÷š5k¦L™"(( P^^.##ãááqôèÑ“'O.[¶ìCG‘¾@Ÿ>}´µµ ::zܸq àîî¾víÚaƹ¸¸Í–/_¾wïÞAƒ}A{öì±µµõððˆ‰‰'.1NÔ¦ÆÆÆÆÆF ®Ñ­(++›ššFFF@SSÓÌ™3•••õõõà ¨¨héÒ¥_íûBò”QBYYÙüùóÅÄÄ6nÜ(XX]Ø0öÁ  $IDAT]=þ|qqñÕ«WOž<ÙÆƦ¢¢‚Ïç755M:•8&-xáªU«JKK[­mݺuïm XR]]M,‰·µµurrš9sæ›7o>¬««›@^¶mÛF4³²²"2|(ÿºuëˆW¯^ݱc‡¸¸¸««+ŸÏ÷îݘ1cV­Z5}úô.p¹Ü‘#G.]ºtïÞ½ÄvïÞmiiI˜€¶+áóù3gÎ\»víüùóŸ>}ÊçóÙlöäɓ׬Y3þü¼¼¼¯ýÎP
+^"}rrr·lÙròäI²³ /‡Ç°ÐwaÆŒøóÏ?É‚D‚#,„P—ÝB],„P—!Ôe`ÁBuX°B]Æ‹ëNÔW$ÞÏ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,261 @@
+‰PNG
+
+   
+IHDR  Û   æ   ‹¸¤   tIMEØž·f(   	pHYs  '  '”iQ   gAMA  ±üa  IDATxÚì½i°e×u¶Ç3Üé=£C73	  Ap”(R´äPJdÅr¥*U©üq¹’r)•R©Êq"§ì”[²bY¶HQQgP Š$H˜3Ðã›ßÎ´ÏÞYkíso¿nÎÅ~ÝØ_=6ï=÷Ü3½‡o{íµ¾Ås,    `@œëh9   `» 0r@@@ÀvA`䀀€€í‚ÀÈہ‘¶#lFØ.Œ°]9   `» 0r@@@ÀvA`䀀€€í‚ÀÈہ‘¶#lFØ.Œ°]9   `» 0r@@@ÀvA`䀀€€í‚ÀÈہ‘¶#lFØ.Œ°]9   `» 0r@@@ÀvA`䀀€€í‚ÀÈہ‘¶#lFØ.Œ°]9   `» 0r@@@ÀvA`䀀€€í‚ÀÈہ‘¶#lFØ.Œ°]9   `» 0r@@@ÀvA`䀀€€í‚ÀÈÛê\_À+Öÿë˜cŒÃðÈñ’ŽÞÃxÏù¹¾Ê€€€Ÿ¸Ãÿúþ®€§XÃøÆø>ȯž|ý[ǹDÖÅÿ9Úêð/l/é_㐣¹?x 耀‘x
+k,R'0)¼U¢™nŽ^p$h9‰
+9¢WÞè_àaÎ'ñ	AŸ}
+ú·¢Ýà€9Ii8£í쐝áà2Äœ.,Fþ	`‘€Ù¸B¶5ŒÕ¤XÉ´$ë˜&Š4D£µs%)âˆ5ìÌ«)R1¥éŸHïš	³ƒj®-Ü 5Ç’Å!øpA 0ò±àlX°Q†„XX&$s‚uR–J–pÔ°b°†¾"èED¯O‡)èÅôqÿÔáËš!©™¹¢äŠ®!$Õƒp8oùÂè(g¹aë#V’ÐEžÕL*Öj1!X*X2áYôY~OÄ×Ç+¶¾ÿAQá³÷üÁ—çÙ¹‚–¦ù@;ÖŽBL# àüC`äï`7`[Åã‚­
+YVº¼æ ‹ûZ)“’E1‹PÊ.ÜÇ"4q¼EO	Õþ\r-ªv>´,·¬¬˜©X'b1g­(,œ7Œ|6*ƒºxyÓ
+K _žÕ,‰ítÄJ
+åª9N¥,ÖHÁšdrº=	ý3ÿ¢f•ÃH7¨zÍY[£dš¶7#ŸFQ±¼pëïYQ³š³¼tqÄ«
+iZk&4ëôðü€RæWÕ”Äxq÷û1²²?Oôg´$Ø-nÖŒ—8–ÀÈÑÑ8Š^ضŒŒÈkj×/Åê/‡,+Jü´¦<3`4ÇqM/j!É&)&¢¡LŽp}OÐ:žšÄ‘ý3æT0
+õªsS"鎻ŠYÉò/ ›àlC¼¢Ù/­
+3¶1r›#6*8–cH¦•ë8÷æ(pl,†/jÚy¶Çæ`»£,cKI‰Xÿú45>Ž¶d%ÿ„×ö£÷~¬ãH¯èÚàjÇfïi‰qŒÖvˆ³lÁ+š‘³j}äÆ%_°šréGgÙÌ,››g² Õ\³Í1ËkäèùîÓJØE]¤Ý•šu$›“H|5kþÅüÊ™kùL5G|Í‘šÏ•<¥\j–;LÉ ªÏ
+Ôø-ÁZqˆcl¼Ù:f­fn±~ÎW6ë,¯-WI,AcBfJqп\:ñ4b=x±f!P5½­öqãLŒ²º¥1(Q‘4VÚÌåŽkÞUMììè_Ýìð“ÉçïÎß·ÌäékC2¹¢ñY¸dSŽÍvPæËÊ8×x%22ˆÄÌ°¥5·¶Q¯@õrø±†ƒò­¬ˆ"ôšH#Ç•5N$	¯kGÄž
+ÉËq¶Øc°[‰1Ùn‹	ªlö„[Mòá<ùÚIp™Oþu“Ÿ’þÕ?mdÃã'ªýkªþ.]ÂÐ2ËÙÉ1ÞÅL‹EœE*è倀s‰W#2·1`K›,«\åX`@R¶{<R:x+E!Üi»4ᨗ©¯6HǦÆÌŠÊ"{*Œyoy™Í1bUM™7J¹›‹&UÙ£šµ˜„›í„ }û±#ÈõÄ+ãÇG½åEnñ†Å/ƒÓ
+/¬!/œ¼R¹®]]ۍ¡d|µoÆ…á\Äí¤ÓáƸ¬àJ³²¨³Æ)r+ÊÒCɈÇ1Æ‘mÅ\é½"bEÎÚm&æÀ¥-Œ5wSΞ›º¹š2+
+gš˜
+d1ÑΞĽÇ[4Y	äY­¶(ëïGþD?tŸï?ø¯ø FMÚ”rU㢟¦|ŒPòðóÇ+‚‘«Êå…Yº¬”ÃB–Ö	éÊŠ£øÕ\˺ªŠl”i­j‡ÍU%q#IaýP彁@Æd䘥ÚubÞí pFiÉ]ª¹œð©W¼0ý7Ëãx8fg¦-WÞ±ˆãs1Ic¹%UþM¾Ÿ
+Þê÷#ùû†•ýêÉØ`,39:uä%®CºŠÍ¤ÁÀ( à獟‘ËÊŽs»6dy%9Ö«„ˆ#÷^…©2)ÜŽv7ZÝ 	l’˜Wæ%œ©¹ã¬Óa3=6?Ko
+óà±%œ&a\¯|©_NÕq~£75b†óÕœûX3§rDöpNR^Èð®hBÌnKÝ›D«ùÖXÇOŽi˜Ûó2Ì LÉÚ1¾ Õ<³T±ðsÅ…ÌÈpgÐqf×G<3b˜ó¬°5P,ã@Ç‘F†Ì‹ÊÔÖ:ØÄ+;¤Û‘À¹‘Æ´ŠÂ ©Ô˜‰œÆøckdR!Ðh‹G$F“9Ös2/ö?vSvÄw I¹ zPܶÂÄg¡X<(Ñ«W³°Û&ìà\KžVßð6ŐF>{:nœ4~ªüe7Iÿ0žš+̶Fÿe‰—º9Äp9ˆåHsŒ€€Ÿ.XF¶0
+¯ÝÆ°^ºQîÆ¥àRÖµ+òÂÕ¥’@»ÒúÙºuUe0!ŸlÍ¥P3³ªÝEÁ«5æZ CùznuDÊð¾#E£…¹×û·œŸaHzv3cãD(|Ì>ŽðU‰gQ’xY¢jî(LáðŠØ«ãÒa‚³œHæœ5úšo‰‡ü¤†ËÓ_¼o.U‘§š>K\ÌÔ”ä7*XQàrˆå@Ê߸`ÙÔleÓ®öëþÈÖÎéH[Œlm]¯q.*c
+¨¶Y*áB´Zq·'cÍ´躩Fíh4,$Q3èY¥±ÖO	ÎH¬ut£D‚槃Ì%[ÖFlcÀò‚u;øǬ§°\pPàa;)Šî²FFƈ²E
+­ÝŒä-7ei0@•Íh< œðæDv2 ü j>½}‹¢v[¶ÃaËf8Z`¢ˆÁø<ÉÁ	z.¥q(  àï
+&#r{b9;µš2é¨ÓkëDÕTßak;ÊÊñ¸*Ê
+¾è¨)ŽÛ˜z!€Œ@IWl㠝«ÒEZè˜{æÕ
+§ú l•rI‚,)¡(ÖQXwJsþá5[^býzÞÃ>À«‘æi-=gRü”Ñέ”"-9.$–…s]²™6ërÂN{¥ã:’É…c%gUΓ&1ƒMòêLì–07›¼þÚ„šÉò \ȸ¦€µô•2HÐ-z ã£à³a¹/ àï#ÃÝÆvy=?¶4çH4‰“^/ívpqV¡ý<ˆÖ<³uU;”Ìô 8—ÂI)u$êÚ•e]׸)R¥±rRq`IëàqYk,Îè#Ähð5Æ¡ggôÌ–öasRL±p"j'•kŸ\ªWWètŠ1cd I\"AÃ…µZ¸x˜j6b.ð~e±hx°°ÒbÄ$ùlÌÚêtö…!j^ÎYW¹®â_þÄÌ^mi¥*¦mv¶Šgäáéc p^l’¢uû
+pk4*‚§×Ö¬—œë_s@ÀŠŠ‘ueåÖúfe3;¹Üïë´ÕÞ¹ÐY\Œ»m¡%¦²U¼à'ƒR†¹;hኢ+pcÈcÎu±æJ:T͌ז™Êš
+Y[J#7Û$­T ú¼ÒÚµÚºÓæ^&ÛŠ2.¢¦:¨öøI7èÃ÷éèš{?ϺÂS
+ª—ÕÜNÑ	H¦1ˆc¤?E«‹5IWF%*ÖX²®Fvö¨[)˜Œ°§‰`g¸gð-jÝMRëÜŽžæGWô)¼¦ùPxU7­²á§£qhä8rÌ¥çú—p!â‚bäµÍj­_åÖ‹Á Óhv®=×Ó­»i(æ0*8ÈÏA†tƒùLöç¹Ž(Ø$Ɛl¡˜ÅÀnmËduÉÈÈÜÖ!¶µ Jít$v¡i>£l9àqNügK”Í\ñ•A=Øtã1¶|
+Œ,0¢ä‹ŒY[!††cVKŒ`€Èžëa
+ZÍ™)@׳4ņ͊¦š£cqJKbaA5xõ™5Óx…š0¯ÚR$Â'oˉ®vVx–)q[Ö„•­a=òÀ[¢ºR=ý~¶¸@èr”׫ýx×ñ”L"YTn ’’³ù٨זsmÞÒg|î|3gý1jg´ß!1	,tì¨ßsQb똰ƒ˜Í3g0Ä!`;Ǥ’<ŽD	©8­²,s”}ú7"W{FUÔð´ŒVlP ¹±Ñ°ÊÆNèXc𣖒ƒLW†:]%@žÕk†ËÃkÀÛD*Œ5Šb«–R;P¼(±w¤d\ç\5	8OãvKɉEÊÆPÓOÅ$ûùæ­tï‘lï—ö†1 þM‰ï7†HÓs­VøYâaäS«Åñ¥lm`„ÒíT“‘<—J³z˜Y.t§wÛ˜PÜk±DRáƸIá\U;cxe±u“&“(f©ÿ^YYºSu9ðu’bx—ÂHnWÄ.ÝÚÓó}©pNÁ]¬â«1•„òêHf^U.‰¬%W#Aý­»)ñ#IxSãÀE(1™ˆÓç;—†Â¾Úù¼æ˜íûJk»%4Qû¸°jŸ·Ê䌼‡|mKm1¸ÃVTR7Y}…!O%Œ­³þ÷ìD.Ñ!-. àgƒóž‘áòGY½²Qm
+ðb«¥ãHÙÚ˜ªê¶EšFC·¶Y`ˆ EáS)LögÛ(÷¶ZY25ÎrNáÒ¨'¾ñ6"Õ…¹‹ú¸?»òÉ–¬…j*¡Äd;É)+1s[•µR¢×“ð]XSa†ŒW¨|±(Cá8¡|â3‰ÖŠòÛà
+ŠûQ‹5Hûˆpe–±qîlÞu*EÊžm±žhDnîš{t“ò<¸Áª t=ߘJ`‘·Èý‚uâÓ}µaçÕ1›OQŒ{»gí0>@©®ØæÐÁ#m¡lÿÙøë¼Âq~32\û8skýêäÊ8+ÌÜ\k׎d&1¥oŽÊqn€‚W˦?BÝk	[¢H&1¹È#{bµªjÊUp!$VBS´ùh,½ŠÕ½‡‹5Ò¨ .–½¤Úš\í•jVÍ`7 ÜÑØg¬ai Ö*m#{
+_TR#)ƒdV“´âémò"!+†¼Œ‰qTP—¶”‘Ó%¾1²êî¨3ƒ‰Ö !F—–þà­š„ ü1Ç’2^¹¢E‰.ÉH»µpBÁh"†yðb³ÆI*NÎvðÌÞl¢ð±À©%ÏSH9 àïŠó;
+˜åfy-[^+Vû•A׶øS‡f/Ì´"Ë£á ¦à‹Ýî|¯½14£ÌäyeJ`j^W’cÎ1÷kWJr±ðJ’妟»‰¯¦¯²S>Ç€3|ì¶gÚ_ ‡EiZDT1h‘"£z<áƒb4·;q«­ðyÁ9b®™É˜Ó”SÁš’?Åš‡}£(B2£X5F¶…ã'´"(µ×Á׃»hƒÀŸŸCƒ¢Â°•œu#u˜mÂÞS?%ퟍðÔpýºEzœ‚æÖ6õį.UÈËpI±¯Lá¬ߥ„e˜´à»†ƒHw•#üpkd`„—OO­ŒV7²¢²2Jâ8I½s>Þµ ZÌÊ›T€á¨X]ÔVè$­—Xí¬µ–^ó&R,ESÝ4it.e,ÓöŠ4)ê∼š	¾Ô¹‘¦öÕ"ø¹kŠ>67Ë|\eÅ8ŠôŽÅ^«%¼!cM„u6o1CƒSìBŸ9`Ž®æe  îÆ<8Ƈà/6æÔvš±¹–´¨ãµ”®©öÙʹŠTl¸‰›’×X>·üI4Ù`¿‹¢tBóˆc>† $MFQ“:|„+–X˜ê@Ê'œÇye-_ÝÈóÒZ.¡¸3‚U‘VUÍ–6ÜL[Ì÷χN;Žb½1•e«¤•F–Šø¦šúø° <^N/8Ñ´±xŠSåY̲à˜D\’¡DŒ‹i¦¤}®1èÁ$
+‡™¹q´7n‰"Öé견E©ªÒ¹R-¹t@ïÄj
+IÍŒàÿÕéŠ;æÓ×dËð&spRÌRRá5-b÷?*æ.k¶9Âoár¢$ËfÞ˜è3Þ¸Í)ƒœ—sl0ÀxH%™(|ª.IÙkd©yY0ã–19xø€;æÛ¼Z â"籦¾$%Kj3º€€W<ÎKD6›—Ž–Vû WQÅ‘ÒZ(Ák=ÛKg{ª­›Lƒªtëýl0*@¥ÎÎu@ÆzÉYV–y‡ 4¢X(ò(ŁI2;Ò¹Œxг!RöÔT3b*Fi
+¤<$PúlšÜ<_ªÐ-™g˜C§”LSL\ØõÙ^\ûPP\V¹¼ªk¦`Ø)ðu,é†ñ@S†0¦©ð»>ií4) ÑIЏëî%K€ŠmÓ@ìíêFá§ê]ÇÒ¤¹†4Æ=wPÄńn8NFàeÔÈtÀ6QðpèÒ”çî–èŸü—p>2²µnœ×'WFƒQ%„†uiÌh\€œU¢™šGÀÎRs·­Ó–L"äU`äš›æy>ÄççÚq¬Jãò’ùV§È¹ÖÁ)üSÜó¯/Ó#áL¯ýGŒòá`øçBÒT¿.(4<!q/·-Å4oÖâmñÖq‚2:üy½ Ö~Á-QDÙCSýÂÁˆ‘¢wEHªæú"áŠbI
+¦šÂÝÄSE‰ÇdÐìõö(GzÅúR»óîúëÜR›êv«‰¡Ã€Ñ¢á¡ æmù¹Õ=ßÔ*§ÅL1+	à	ÀfП(¤Äü48ÿ¹(íÚFqru˜ÁœYê8‰Ò¥q^º,r6¸¤Æ•”
+‰8ň±ÄÜ7’£ Ÿ#LƒÆýÍašêÅ…v»åÌôÑæÂ'²!fžÖüÚßä<6ù,7,©vXÈZ;F´%-šù•=Þð2›„›Ñ«^cüÁÐÂZgD({§†í +2{âd„ŒùÕmœ%Œ5ZcÚ2&…Ž¦X
+øt™ÑÛÑùÔ=A¾&íìCd€3)ŠY51“+
+[[g¦tí6ö²Â¤i‰Gö6#àYÕ„×-õèÆ°™šÑaab’—”Ùâ0ò<
+Í­~BœgŒ\ÛTǗƃa^Y«µZœO÷ïî )#òº?4£Üe®.$Ð1®Ê¡»±BjÜT50ZšH¸õ•å͵Õ~«¥öî]h/—®¨,¨fÔ¼b\öñ
+ÒÉž…9oô¬b8Ìžs>àá¼
+ÖÔ+¤j24|°¸		{eM!ùÌ‘RÖ
+zÿeŒ–‘÷úYZ*67r¸rà寀©€ŽÈö“Œ…@Ø{úºgéWéWŠtLǸx©¼á=…†yã’1#§1Zd F˜6F,Øøµ*)	OáµqjÈOʦõK…ýÓÃm‰ÐíæÎO5†c³Ø•J¥ðà|bäÚº¢¬_>Ñ?qjssXê(êv;³½´ÛÝTöº±&QªmsTÆuåɈ!ñùÌb¯¹T Ÿ¦S®EU™Ñ +²¢ÓiÍÏ·€
+Ê=‡&;–$3§H•oP„¹	»‰LöEÆl‹ß0%g4Iruݔ͝‘­ëyšRßÈሂ’ùôf‘7¡’qfWWê"7^
+d흌¤ôÌîd„Ú\”Èã(ÀUc®O+“MÚ²ðCAE±aäkŲ3."…¦EpF yÇ®Î
+‡ÀõNSÀZR,ÛÕg8/gDÊ@Äp¢ˆ£½½ôg1(óÇ#³cV‰ÀÉ?6Î'FÝ»¼–­
+ªþØP׏M$âH+ÑNÕÆ„%NÒ1{Ìå• v-eM`K=LnC(9!	Gà”Øt6e›ëÃV³ÓÒ–Ê2;.áÈ圲&à‹4­çhßr„–áš48Þ±³F¦´6G¦§#Ëc×ÈmŸgêºîv£nÙßçuøݐ[‰^¶±aÑÖH¹8æ~cMeÙÀÂ(•jÿ,e@û6Ø’â•9í9„Ñd‹ÎpI’h:+ÑG^Ϥ˜z\:Ô¼@Öãœm¬»;Ãb¨šiŒ>÷Ò-mýhP“ímtØ08˜U–|î
++K'…›m;¢€€ç#oôócKã'ûãÜÎ#˜ÅǑж1Õ<Ò<VFéKêPÉm5¶A¹(U¤lÃ3ØÎ)ј+¸Ž¸©ìÚÊf™—33­……|ZÔ®¨\Mb‹Iˆw-‘®@vl„'›:;/K_l¸ŸÖú(Âë¨{—²¡r©¦¤l76úv47—ú|g)¦qj.ExCÖï£YŠ±’»	RÓN"eÄi…ÕwŒVá@Ôƒò5dd'é"†\…’¸)Ea”q‘çxýè}ÓÛ’•ÖrVfNcáWÔ€ªá[)ÖPÇ©’ªKà
+óš•Æ%hœÁ‹¾îºi 倀ç
+#ç¥]ßÌ_8:è
+40ü™¤*Ž‘–ˆé˜"GcId¤•TŠD-ú;…ÚÄ3öÄ­B6^ÁX9Ý,ÕÕµ©Gì*«ÞLÒ›iëH 7E…ûP{sdôòÄÊëÚ«dG4ÝD9|F³g[Ÿ¼áSã˜I;tÁ¤Ö}©l«*¥ƒÊ”;gÛm¸¿¦•ªM¨î”ìÔ)LzV‘„QD;“TG©¯(¥:gÞä­¦Ø4ÈXï:„YÉ>NbɵC¢XÆšoùp¢¶sQ‘M]f
+©ãaßIé`ó‘^—ø¶RìÈ¢oúŽ­V¼0<Š°.O×sm¡U^ühœ7Œ<ÊÊ—O–׳h2—ÄqšD\r¿œF›™ÆZD”J¡”N^¤ ƒ¤–¦k`T`€ÔœÄhN)h¸	ØJ”¥9yb¹6fÏÞ…ÙÙVK£Õ½³“xwÜÇ“-ÿùX)rJ
+®jò¾¤Ž–™€\5$ój›M21X³xˆDYè—Üí(¥˜duÈ	kÊôèñ¼?0:Ž’³/š"å¬Öh„¥Ø#‚ºf9ŠeŒ;3,ëP”B‡‘k…{Š\˜K†9ÒØNï)ÁõZP¿ã¾Òû{p¿vcïQSÁHÌ1‘®ÌUVh1»n‡FØ-°ªÜ|G„€r@ÀÄùÁÈ 1O,-ú™h}­¶¨ù$†$’"E$¢XµSE	¬ÆRÑ÷hÈύ6"yCÃ@™BR@Ã%¨¡(>Ì–ƒý²¬ô‡ gççÚs3	PÏf¿fµÄ€6aVmÎ3Iu€×¦BñŒÚ’7åR7áfKöo5iUŸ\ÑðzÞ[clÚR­´éλ¡á²:]®­©Sõ‰5³´T€PO•&\+¡4oÊXRûÂOD‰t‚ŒŠ
+Ï‹ åZ$-j<HˉÞ;	H.¹ª8Ü4fM^»šk[b<Æ Hó$f­†))箩ñ[/Ù\DŽt%;jâÿÉ1N¬ˆ~ÎF®k;UGO
+WØ‹TÅÒÔÿq\£K&òr%S7¥@… ‚±QÇ$_D)Vå	Ê»À5:ZD&ÖJ7
+òš°iX”ÀÍÂÚÚJ¿ßÍÎtvîèÂNyiAÖŽ/o}´—Ьú· È©KÆN§[`ï’ÚQ:'+"ZñÃÚhgj[UM÷SúMê±¢:i:|C¬À¶ëcvôX‡‚‘%A³fœøjCžPêE- |¶²!ßgt)¢Û-ᣔª
+kÀÜP'l‰]Y wNr®×âyQà\©ˆgáQ)£«†Æ#«æŠšµÃ1õCIqaЧкÆ[Ès׎\‡€r@ÀÃyÀÈÖºSkãåõ|}P ´ZZëôZUÙóŽ‰W¹J¦è}Ì|ZÍô›¨þCÁc))AŒy±æ$±¯¥U?‰å×’ú5áI©æ£¶ÆR’/†˜ó¼3д»wuz)lïçØtŽ}7ý8Шӥ‘©âƒ{'O8ZUÕ8<ÈIß;×doUÑD<(STy‘çÀ°33)0ÄÔ~ôi’íü‰š–ÒkðNœÌ³“¨Q,Ç>횬Žèva£ŽDr¸ÆÂ<I­`Aå—9<I×féj‹g	)G\³™6¯K»ZˆÂ°«KœŽ‘‘± Gbˆò±rÞ¤al–®¥¸Èø¾~®Õ’—ÿ|‡‡ØE@Àüíßþís}
+?eUoö«ÕU!aÎA&‘Œ£†àPD’g%•ºaò…@¿T‡)ÒS2c>¶ÐØd2ïˆFìLýòšT
+ô ¢µ8øJNJNS½°Ð²–/¯³Ò&‰îÄÄfY¹qf)BŽõô: JAÏ¡x–Z_ïHGÄäK6„lBɔŁWb°¦í´ÑWሌ·¬6µËÈ°}D|œ•µÅØ·1µÁjq&|ÏU‡AdCu(xZºƒ]\1òjtOfØ×
+_§ñ#ª‘Q|<¶¥åí–hK—;'N—jbUJwQ“#³’~åÐÁoÆQúv¬0—Ž&"hYWaF ä€€ˆó€‘Ãr”×@80én§Ñ\/%HÁ
+  ž’ÐwØç\ù¸Ese³†’¥±ðíôpÍ÷¢CæõéÃ0¿GCùšÖý¨ˆkÈ\SßhKñÜ(ÖišŽÇåÚúdu'•í&%µ_¢ÐoŠûˆÞ½öŽET:(š¬"YIÁ
+G‘VG%v†2ä(qn°FZí‘#{9—Š:ø9Ÿ}L9|E^ŽF#Î5V…PÜ3§QvSÔºØ%ÏgCóÆ2	`š ]=:Üû–°‚gYeÖ¢kð8á2My7BM]Ô®áê)×n²§'E4ZòÜ )3\QÄC…‹ð$aô’Ò…B¾€€„óÀSJYPÞ0 èµÍq­¥ÁD©…Òµõk˲ö6AU]+¦q͍òÞ¨–½ÖuñéÉŽt'mÀ%@l,M¶ OiþíM“‘úï0á[P®±3s½lœ/¯gƒQ¹s>íÆ2Õ|#Ã0+Fx)Š§®ˆ£á
+@ÉÒÂѸ*éÈB¨	_7
+L1
+¹Š"Œ (ZÊ3”5…s¢‰Vc‚©Q"_V”(âwïì…Ùö…j[+°¨ÛšÅX‡ÇesZ¾“R8\XiÐO¹—°Ù„­ßþǼq6¶Ûh¡„Œ7< Mëù.Û=ÃŽ¯ã`$
+¶“¾[á¥a”^.JÊî€',p”Á. àb»Ç‘‹²fÕ‰åñ樮¨ /Òb¦«g»	ºU.+Ab±%.Þž
+i}‰†£XBršè¯0yå^–×ee±·ˆ©…_¥‡±`
+!»Æ¼{;yÖLØ«²^]Ù6ܳk¦“ ÝÄаþ|&ä9ߊzsP4üyV5Æ
+îKþ¸kÖ©S	ÕŒHÚßw³6%ƦáJblîGm™¨4öàÖ­”º(*­e¯%ß\YßÔº‹‹ŽF‘VðÄpUN†}ýX¤¬PµÄ:r´Sê´Ñ•b\³•uŠÛNDžç*Ž“„¯o[©«`D‹[r®åZ±8±îÒ~·¢$ÉÿåT£™=&„àíéÃ<“^xAÄ]–0ðØkF‚Q@À÷Áv×Èð3¶­­)Ï™€ùuU«¬°-Wá•3Ðq9C³Úp©
+¶õb5‡O5å#5IYƒvÅ5.r°V¢÷Æbäf­*±YÀøèq³~TÙON9¿8W•åÑcÝn¼wW§­X2Ëe<¢x:“yãÄæ'øÀ‡¸phj̾£…AɯKÊ¿£1 d¾Ÿlt=æŸÁUTT <ÊÊ</‡£qdz³½Á ?òý{ga¤YZY×Q×9ÍZkj™$Êj¼‘×BÃíD&Ž•ŠxQ`«ªXb¦Í
+gK6ff×B‚Ï›Üðð…”p©6cyáöͱ}sbyL†sUãgä¾‚ö~o0Œ
+«º—P{"SÔÙš>Êk´ë±‹€€ïÁyGçeT²Â“ há,/22xóæÅÂ6‘ßúCú…;œ"c”²¸LG¯9úvbúÈ¡.®hI”a„íPÑó¾©èÃj`SáB™›h]?£À°rqŸ(›5ˆÐ8ª+;UpìT‹½ß0ÜÁ)ÙI{Ë!ŒQo…Aˆð.ƒ7¡àÆò¹Ón>> MwƒÃKYaw¨åµÁæ`×=‚GSÁe8R·Û³A~ñÞÅå`°!¸â\Ñ9)™D*:8Œ@kóð¬k%Ô»¦zkÅ2x7eÖMðö(«ï;Ph¼Ÿ×Xôà\0,eSàHcW~¿H	—šh̸0Ô+ ÆB>Ë`²8ãp åsý—°í°½™ò€éÐi3CÛ ë€0¦4ÿÍgÆyâ£3[a¢V7ƒ’Ä”6Z¾ÃðÍàe“zÐpXL0ð¶Æøã‰ÙYŸÉ@îš^S  TD|ï¨Û¤’+<RÆ4P×x$¥ ́àË°–5ùkDìpQÞ‰‚7yË‚$<ú³M“šQùS{SùΔ§ð®y4¬Ö×7Á©ð=\*m0çYôz=`èþ°Ü»³×;l Dæò”žm­€·8¾ÀC‚o£]»%2+õmA¤âØ©Ä`F^«Ùp›AvZk?RÐ:#Û›^Cçy¼áC£jæg+ÝLYµ[…Ö5h2æe2šlXŒêEÎÂöfdîm|«¢݆’íèÑMBø‰<pYz!
+* Ùزªœ/ÁÃ<aY“Ý€+R5á¤v‹ib 
+1²€Þ•±p"ŒH³‰ØÆ=îkJȺ“à¨H€Î[²QÌ%$Wf„y•ç˜ÆŒÓÒÈJΧ| 1îƒÑ>èáš1Ë|‰õ°)´ÀýB"öV¦FAZcð¦BÖç:¬c’ÿä¸Va ¦Ûí £³rÇ\81ËGp2S;FØUbs‡æ˜X"Œá3-«€TØÃx£ÙÞó$Q
+åÆã"Ib¥¸àà|D	`ê…®ÒÝ0yŠR”Ÿ	9µ’☘ADŒÉ•ÅL8‚×8VÁÕÂU™p¶7#—å¥e
+ê]ã©F‰Y%
+L.OP(¢(E7³ušõ†a¥V
+çïÆàÚF¬ŸŠûÜdl‚â¦”Z`á\…,!R©”ÖŒ©k¨wmcäs5µ/ªI+([ËNƒ™yM$rã#ÒùþO¢1Âg¬Ñ•ž”«²d$|É·OiJ´ip™~PÆ;Ùq¼qN«Ž8(à2Ÿ±ívTVV³Ý\'4°+Ü Àx–c	G–ä:†ýK å678íÀ²“HÁkQS¾²uV˜™vJÆÿ¬¦ð­UŠ¼°Àæȼ5Õ¶X³lsÁ°¥25É‘§³ÊEd6Ô¬hžŸÆZÈP1°۝‘¹äÇåpTyMUÌ«[
+ïÊšª*|q¥Áù”2ŠË6
+ñ¼Æ¤?¤Ù¦!ˆwŬiy$¶OuÀpÎê‘U½[zQJJIöôÃkcïÚCÂ~QŽ1 $8Îj˜æwRì/U–¨)ìÍóz1ñ§§lGúÒ”(hïRâ&Ž²Éôˆ"™eõ`8¬A¯Ò
+#èbWS@„B 8à›¦)Ðu^˜v¢±…㽃þÐæ>‚‚™$­®6L>X;%5Ïö§ƒ¦6F©ÍaÖiDZ–Y	*
+•¦À!ãHaâ²u½{Mz†ºpáJS4ÍVp£@wS¸æ8y2™™°۝‘‰@#•ÍK”µ˜ËIŒóR$B`Ì–û6΋FÌkpHL¶ö*˜"­UY6z™\ŠüJUéhŸãxm}½\cåCÕÙ΀„¬LI	vÞR?r¼š2t…÷ŒÉ|O&TÖpxiëzœÁ8ÀÚ-‰sö¦~›ûæ ‚HŠb!ÜÇ[ɈûØ6ò¨mVùÐ\Tcð-{D”gf<.ðøNLRýšòDc(-$c‹Ñ—Ä^p£¿¿W¾¾É*Œ9ð­V¤º=ô…0¢ƒF8€Á[?áÈ«b8*çÓ¢…&'|\ÏÄ0:Œ­BKeÌrÃᆞ
+ÒÉ 9R"/ëHã¯~G…ñaq̃†Çk*|àØ”6¨ä€€	¶uöÛ¤>MÀ„7f±£ü	©(¸¢D%aˆ4xèÊFÚ;¸S2f$cHU’ÿ
+Ìñq¹	ÿ–×c®‰û(Ÿc«^ý’¨Æ´3Î)§C#@ÍÑJS^1®Øù:fänæëú¸ï–$p¨ÀˆsÛª`Ü.Îi“ýœ:zLìí½è6T0"ÉGÎrÌCð6IÞ›L—ôÈÛûÌl¤ý(+€h·=”rbŽW\æYÔØå׬۸8i‡£cÐNá`aêO~îo‡£<Žù_|ËíÖ*©VP겨¥Ð­8ÚžìXlsÔ垝ÂBG¿­–:µVÆ»¢™]ß@*£«§ÁÐ˙찭9nØJÅòX²\p43ÒÂÚzœ›nk[ÿü<±­5²x6˜­÷GEFÈdW/‘£“D¶Z83/«
+QStÕ{>DØZ	8¡•ÆÀ¤Ô.Ìä1ìrÈ	òŠ÷	¾žoà°ÞÁˆØ pæ¾?)U'×uÓp	­ˆ1›‹­}}Ñ@93éˆJW®”Ë¼âíX´INúÆ£t‡ë1ßÛÚã˜P»ÆÔ;Q>ƒó"˜†.HcqS£QŠ‰×UMÁQ˜I&¸*á‘iÌíSãï
+¶Öuõ‘O>øè“/<ûÂ)àå·Ý}¤,e6I¼“ Ü…‡Œõ2F»ªÀ$AÛëh_h(Uc[á×4ÇY
+·–hV¸¦|Æûunðé¦1Ø#ʱæ^0´ã°ùV;–!é" Àã<ˆâµÂÜ6f”Æä5®ú[^a S˜„²I#Ùk§i„öÀhÅ¿6/*US0tceHçÌU¦ÊË"	ªíu¦^Ø×öŒwd#:¥LKéUMùÒ1?hèS9ø²¡P4|¡¢e=xh;y:Üì“í8kw[ÃQv|)++6ßBëaN^?µ7|ð6Èί¼aL]8ÑI£öQFùvbj‘¤,…±Hböˆäš3¿—0ðPž6ƒ!j<Êa~€¹:®+EºÛ‰}ò6–BOà‡¸ƒáЮmdKë¥ê¥ZmÒ4œx8Æç $>/G®Ê–ªZTÄ+ËWû8ùèø–¬Þ¶_ ´¯°‡l3ú>ÖXàHѲFy}®ÿĶ΃	#(ÐHËVª;íˆZÜ£¤UI,ç4Å&à¿ì(®‘ƒ²hN‚B–‘©ª¢ÈqÁ
+óvõ ÑŒ)-Ö¡åÁ\aâö!Ó5ã}¤ðut‚<%0W©–®"c¶HkàPÙUsÛØ9Eç+‚AÁnMãÎLgcmóÅ—ËýÍv¤êE0•fø?j¥Ð‡
+¦÷è^Îp0àñHc(Ù›ZÀm´;:Ë¢µ<gLYWMòéðºýò% (”%ìƒÐpž›^7Å:ìçn
+b±É4/æÿ•E]äYÒšbž¤xSÃÝW
+´þ(‘n"àè&Êœ˜Ç©ÌÇn}ä:|<)M4ô«**¦mS¦“•ºé3‹ÝTÐÀsu'UÎFh%f`еyIú=ˆ9LŸAÛ€ˆy4ßKA8
+á`Ú>.1€zLa²·«¦™ –qÞ£BiAn>ÎÔdsüŽO5
+–ªª2eeÇ9Ý£¥’aü¬(²VmÓVû‡Ýž±(ŽL†F‘K†4U¯AÑ•˜™ŸÙ\Û|þ…åƒw´ŒEôGÄ\h²á[hS Gcb¸ZÉ0©ObsÓs­ë%‹c>7߁KÛÜÌ…ÃÆÔŽ_¼2D0£¤¨* õ²víVŒ©&¥™›I8¦cg×_qف=‹ Ww/.84‡Ãˆ`ãÃA=‹ár¯xœF®|¢»t^¢32rjæ˸ØGA	ð¬pã˜Í$ìTó‘)ÜÄáöå–i êaˆD÷d hJÌ(+?˜œ'ŒÌH‡&‰n·¢¼,6û.ÓÇ
+¤¶£F? ¼äincZy9V¡
+}­È°¤›Áü‹J­
+0Æ&‰tš(\6dµ/øÃFtè»6UŒL©¿¢öÎœ˜zçó4€Ó
+,ì¶ØSk¯-Q'¨cU˜’3Ö”ZÀɇø.Ò¢7ÛÝX>ýÌ©«¯ØÕŽ‘µW6°<ûöP“rm˜à—%P¹…Ñ”>#<Ì©»ÑHòvKîÙÝúŽJæ4%VS­!>­ûáª
+j
+ Ïb_éÂÓ榨”]íÞ}÷«Ñ_4qíN&Ù›T^ÇIŒáQ²d›‹ñ¸–àÆBD´?®Ñ^¯²”6BÖtpËý‘K4‡ûg0&qTáÓ,*ǨÌ[Fi*³¶¼ñëàè(‡™é¦çÍŸb@À߶õÊÞÙ×*…–Ò[!£‘Ö,‹Ùk1c¢F'"º¶ðžëd”ÜZ‘þÅ°EM±	‹Å× 5uUã‘1ÆÚŽÓTÃ$ÝY…fë ²5íðšQŠ—/D¯"*šÆä\¥#o¦FiЖ:`;ÌžX%ã4¿¶
+—×d6®Ö7F;çZŽùÆF{jÊÌõÉX(É-É2¸g
+¹R±ø4ÂMá‹8­VÂÈ*	n³é"å;¸R{l,MôK‚äh‘¶`´Ù¨Œ'QžUðÜbt|Æ~Þ g‹²Œ4ë´“Ùd>ÖB(<¯öGÅ VS‰‡TØ‚£óÝMò½ÏÊF¦3,¼Æ»×rÊÈ>Sùçc©ä¯0a}/  ±ÝÝ8Ïüg¼´š¯ndƒjWR¨Va»OwäIàBÕH-‹¢´ÆbݦSøÒ2Á¤T‹•'H6 ¶h÷B¼0£4öˆs at .ÃZcúA[P.SÁ´{葧^:v
+¸)Ž¢7ßy£µæùOŠleµ'ß·{~×ÎÙk®8Ði¥ÀË'VÖáÓ—-oôÇI¬/½xçÕ—_´saf°9è¶ôÁý=¸©AÅN,eÀûiã+Ãï>wbiuó¥——¨¸¥óE»ço>rhÿ¾IL.ôÃÊqÄVÖûø'†p—fÿÞÅk¯ºô؉ՕÕÍã§Öà÷ì\€s]²WcK) ïÙÙv™•0wètÕú³/?µCË®3¿pÏ­Eኼì´ÔÂBú•û¿ôío>™åUš¦ï~ß;aà{æéN]>yâäž}»wïÛqùáK/¾h'(ä±qŠR§aô1…ûÒçîá™gà1å…»çÞ;/»âàñ£ÇN?¹¾¼|äúǯ>”è&Š1Æ€{yieyùر¥þêJ‘á÷íܳgÇî=‹gµI}ù¥“úà_WUÿ¾õ¶ëÞø¦[ýkøÕüé‡>õÒ‹'ýÛ+¯ºôÞ·½îÏÿì3Ó-oºûÖWßzÝYGƒ¯`Æ$cívú_çÜ\ï\ÿuœ?Q‹)ºm˜'èãë0`m=SJµ;iÚJ9QÀfãÌdp6NÖÂLEÀv#Rë$A½Ô“e@²¢•
+ÇFcû\V
+Gnל줂E<Š„©U‘ÛÍaIYd
+jÜs/žxèÛO1¬ŸÆ õw¾ûò‰S«[Ç5`’#×\ú?p÷wž>öá=xrycëõ/Ìuï¾óºwßóªaV]Î.Ú‘v53‹É©å|e5ÿ«Ï~ý+}çÔÊf]Û³nü¯>÷õ÷¾ëu0`×*æªÒecsìXÿ³÷?
+ÏÁùË_{biµ_ùœgB¤ÕÕW\|ïoÙ¹87ÎrxVÝNTŠÁ°|èѧŸ{q	ö9°oÇ=w^ç°:QÀóÿöÃO~þ30r}ùÅcËK+ë›ÓÁ×ÎÝ;ÞóÞõÖ{o·•4º*’yâñï~é_ö»]rف/ßÿµ/}á+Cx¬Îý³ÿå7¯ºör;ÉïÆüãOÂYú›ƒÒ»åûŽôì\÷ž{îø•ø¶n·=ݾcçü`0þÂç¿êß~ëá'/¹dïe÷Ãë/Ýÿÿï?~4§‡ _þM’h8ò¯î÷;ÃÜ|ËÕÞjÊã=þя|Á¿¾ñ¦«Ò49×׈ó)jÁˆ"-;mí[Lc at UG)~‰¢¤ /Vv8ªNΩ¢äUá4—í$êvâ4â¦Ìóñ¤G†ó.o”l+`¹þÈGUmòT۪Ĕ»¹9Ñ‚1€J³«mæûÎó@Á»}þÅ“ƒaö½×yriã+ßxú¯=ÙÿžO=Ÿzöøγ—_ºD(—²…‰}l\™ÿðÇŸûÔ}ß„¯Àű^˜ëÍδ±úÓžñ‹O>}ô²‹wïZœ«©¼Û»´´þÅ¿ýŽ1Íp1ÖžAå ²O.­?ûü‰Ý;çf»¶6Z	`·û¿öÄÆæöéuÓÛn8¨Ñ?êuR©Üƒ÷íÅç2zF«+ky–Ÿu£á葇ÛÜ\䪜B7uiafòͯ~óÅç_òûœ8zò‘‡/ŠÂ¿}í7:|	•ö±“'WþÅïþÁg?õåÑh|Ö؃Å/£ì±GŸyö™—¯;r¸ÓiùíJÉC‡<üð“ëë}x;ŒúýÑkn¿aiiõÿü—´¼¼îÿ<~é}o~×»_/z½ö}_øšçú²2w¿ù6áñ7õgþ̳Ͼìß¾ç=wßxÓ•çúO;  qþidFÿEÍÏÆ	™.6Fõú¯Ñ˜ 8&ŸI+
+:M^Ô΢²²Ì†eYTT5!¹u’úÖ¡£¹Q8[s›÷G<«¢±]˜©óÒ€œŸQ3{¢Sëð5¾ÙÏ…<#‰;Žô‡öî\œ*yüÉ—–V7ýöµõ£Ô½Ë.ÞuÉþðú‘'^ZZÁO@?uß÷ÝtE¤":b31îÙ£÷õ;”âÌnºîà{ßuÇÜlW+½¾1|ü;/~èã÷gy1矾ï¡ë¯¹D0a,z
+Òq§ùÙΞ]óíV²¶1<¹´6!™žXZûÔºh}v<gg»=1ìôyVUÙJTBÏe^sFŽpG¸hÏE{‹²8úÂÑS'NaÖFQ~ê÷]qåÁë^uc¹lŸÌ–PÃÒ©åï÷ËÃ(û‡?ôé¯~åÛÓƒ¸dßž}»adzñÅÏ?w4Ç’yû•¯|û?ÿ§¿üŸþçhÝü•î?°û×ÿÛwýîïü/‡A_ä0<·ç&ÜzÍ5ßÿþ·úììï½âÊKúúãt%k?öìwÝìw*ú»/ú× ©A>Ÿë¿è€€ç%#ûc©ó\‰\85¢j´ÊrWÚpJ­eœè¹Vf÷ãQ5dRq-•jÇuã€lulæûÕ9Œ+GTȌьÕ~9ÈënK
+2S˜jÇl¼o^ÍtÔ‰¬œ^	\ïýòëßtç‘$Žáˆ_þÛÇÿïßÿË)ýÕ÷¼ö­o¼a¦Û&ú⃏ÿËÛ|züäÚòÚæ¥íγjc³sò»Ïùïý:î¾ó†Cï‚k¬,Û»{nq~æ>óèwž‡/;±6ænJNôV
+µ5sìʃûÞûöÛfgº\j8ѳ/øðÇ¿œ=÷Ò‰¯~ãÉ×ß~í¨*€É£$šF!(±Ïg:ã*hã·<Ìèã·ÞÿªÛ_£ã´?¯.­~꣟~à‹_&gógú«+®¾Ü(ôqsöûü¦öíßsåÕ‡¾øÚëûƒ>òí§þú“Md#m%ø÷¾þM·¥ºÚšò3Ÿzàÿù7â9÷3Ÿ~àšk¾ííwNøº;oþÆCO|üc÷1
+ÿþ¿ÿó¢(ýGIýƒ_½w~afúöî7¿v¦¶2õ׿þØ”‘[:E³À¡Ë wŸë¿è€€ç%#{ø¾yó³I¤ÅòzÁW.Ëm¤1ãMÀÜÛ	2Z«`®\•ÜiÅŒIzbq­‘¹Z%£1¹®cDX:}\˜vK–VԌ:‘¸h§nm)gxõ‡ï}ãMi¢5¾{Õ
+/¾hdz/4J·Þxù/Ü{kDy0ˆÜrãAËÏ<ŸfYyjyõÊÃ{óq¹Ñoyã‘7¾æŠŽo.­7\}‰à&ï/ŸZ}æùß}æØó/5Ç\Ûns³­ª°Y–×[Ø0 ¼çm·íÝ5Í'`šéÞ;^}õ_}æk¾þð›>}ÛM‡qér8nuZœ7CLbê­‚žšuYäÕV–ë;ïzû»ß0ÄÃXãÒNë噧ž9yü|úÒGŸyòé+o8RQúß™z½æu·üÒ¯¾÷ðá=¦r³]¬bþô§F~‡{ßq×›ßúºHëÍ©íL'yû;ïúÖ·žüüç0^¼üя|áõoxõ4à zù~àí=öŒ×ÅÃáxz®·ÜsÇíwܸõìGn¸baaveO<þ,œÔ¦Ÿzòùñ¸‰Ã€¬î>×Ë
+΃*êvõ‚·[z¶—ìÛÕ^œfRÙ‰¥­pGQ€Ø³X;Ââ(Ju,tD~jÖRSQ,=Ʋ:ƒk_ó3­¹n¬¥e6®Ü(é$Ç.Ôý~Õï×//U/­Ú«“¥jØ
+ýê›.WZUè½NŒ<ýôæ#‡Ð/Ôb®.Q¯›\z`Çô⍱ÀÕIÊ¢VT.M{ûì¼ý†s=ý'ý›ÿý÷>ôÏÿÿò»ÿêÃô¡/üí7žŽšx4)SlcÕjaô|4>áݵػþê‹0­k-ù¼¹ë¯¾xn¶ãwXYë÷#4€¦XíÖÇØëµ%¦3SW`oþ0â$¾ëM·¢›ºEÍ¥fæænºõ–éõ<úè3­X#»3‚Ø‹s¿ù›ïÞ½{èÞ7J\ß=ñØ3~‡$‰ßx÷­ÔjûÒæ΀sßþŽ»¢¨iX
+zÖLj§Ø»wç?ù~yë¢ಃû©§ñ
+={o¸±	¿ôâñgžÆ ·×Ë“ˆÎÊÁ8·85òq,•âÀ	´ZÙ(‡Y=,Êڐ‹¦À¹B‘'N¦e)ï—ŽÖmÎEJ-Ä	šÛk¬3EVæ(ëVÚmu!Ù¸¨–ÖÐ@ÃNB¬I]´wS†ÜYãP1±˜ÀO\´ó‹Éê+ªíéO=8u;ò)k1ºo?ñü‡?þà#ß9Z™lõàÜ(ËŠ¼Œ’h~®½²Þš~²o÷üâ|dìh8Æ<aWsg;CoØ­,«ÍÁxçŽL
+.ËiÔ¡Q\Sµ±³‡5M³¿B,a„‹LiJYVhµÌ#73;3=ï±cKZ
+ã˜;#—òðU‡Ü¿6´…a­mêbÅŽ¿|:b07×Ã,7ü%À0éÌäË—¼haqöÄqCý®®¬_|ñž­ÏàÖ[¯{ݝ7OS)à©þÒ{ï¦>ëQÁoó
+o|õ}_ø°0Èí¯}õÑoºjccðôÓÍÚか÷ºüÀ¹þû
+8‘Í»qù.ÂÔ®µÍjch6FÈÅ@Ö\’õ¦o§‡…ͨ‹Ñ}\Ý°ˆåXëÇ°xL>£ñšåºÆÂëj}ÜçK«e1î´£;DÚÞºx…v?ª1 B²µgT«‰cØvÄÕl«„ô½é¨BÙˆÝÿÀ“ÿî?éâ¦75Ókïß»pÅå{ûÎËO<…ót H¥´¥DEªÝVÓSÎôR8a·onoý¦—D¿¾9āA’ôäjàu+áðÇY5.²zbiD—îF£w
+Oô>ˆlªF9}#+Ëkýa®"é+§Û/½ü²i·uÙÇjr,B‰ØÑc'§ƒV;‰¢Ä Ÿ§Ò´®†ßhç4‰ý>0Š,-­õëÞX€æ=ý$­}êɪ·™³42àÚk8°ûùçÁëÇxùÅŽ¯®4ùˆ7ßrõYZ; àÜâadFSo&xG‰NKÇk¹sÙÆ°2’%Øv‰¸	¹9'|wQlôTS©1º|–ŽBËÞ;3ã`:F)(i×æsŒÛ’©¬rΞ&)›z$#,L9àÁ÷þ`“¥Hï¦qúSÎ0níðzF£áŸÿõS:Þ¹Ð}Õ‘ƒ·9tèÒ]½nG§ê_ý¿Ÿ˜02[˜‹{³±3¾Rîô	O­ôÑZÇ!‡(±òÏN¯)ŠÔŽ…N 6ìt~1š’Æ1ŒFØÏÉÛÏ{¡]5Î]·ÍãFµhœ§Ë«ƒ­bxÇ•s‚¹3îu÷òfu <éŠÂÆš5ïÝ»«ÕJ<)onûýAonëK¨*°B§P¾²²±ºÚf’ÆûìÞú‹þýЇ>ôºuãç?÷·w½þ–ï
+AÌ/ÌÜvûÏÈÏ<ýðøO<çSâ’$zÍkŽœë?Û€€3pá0òVìšO"ÁºI±60ùÔ°ÐxJ56éÔÆ@¬7ãäV”fåè»ÆmUb‘ü›sM=R³ê¹$R‚Ÿ6a§Xq+—!ç+[ä:‡¦‹=oa,¯Ž}3¨£'WŽhæò‹óÝßù§ï¹öò‹6‡ÔET£»PQœ®¡P’µZÙTÓ6&ˆ§66ãV”€6×XÞœ«66GÓtGóÝ9m0å7¾ ¯ 'ÌÓtOàØË'_q2–“Glq1³c/^ÏÂŽ…Q^w"_ksú`ÍzÍò¼.ŽJÕrמ»v-xŠì÷‡pð™ùExæq$Íò²N´xú»/'yܝvk~ît„ðÐ×ÿˏ}ñ¬ZÓÑ(ûÃ?øÈ¡C¦¹S¼öµ7}ü£÷ÁƒÁè‘G¾ûØ£Oûí!d°
+q~¯ìýÌôâý{:—ìiϦBÔÕpPÀ컬PS<dGc,Zµ‘O/ÕvKÌõÔŽÅhq!Ù»§»{ÏLoda	ÿ½sž%ml’41¢Ÿ<>j™„ሒYCýª§ÝIrv§JBœåÜÐôÙãüÔÊf9)´»ôÀíKë¶ðheÁN.m>ý܉é·ê’™‚Z\“½Üi¼¼ñÙû‹bÕ›i-,Ìt:IUå÷=øÈ´JeÏÎÙùÙV„9€ªÝNO×°q´…‡ã
+ôÅÄ>Ž‘ ½ïÓ_<uj¥ª¼'vä{é…¿õõo6· Ôe‡ÂŽy…ë‰üÌ!	x|4†­¦ŽY¸¦Úëµo~U£dá÷ñ‰ÝWŽGTŽéÞðÙØ|üc_ôE1€Ë.Û·°8;=àÚê&0ï4UãÆ›®š*hPÍŸüä—¾×àð—ÀýÙÏ|廓Lä²؆¸052#Ý'„\œ—I¢Úëù©Õ²¨LnRGô2yqàc4šô“ö ´Œ/Ì·öì9êr2_×ÒkŸá·@*˜–1þà;ãM?jºR)ß%…lerûl„s¯Ó’²)ÙxîÅ“ßxìØí×íNµ2){ìéSøÁûNœZßrkhg'}¬Oбÿú‘€’n¿ùò^§=\~â?ôÈsþÓH«×Þr8Ö*Š“µåVLľ1®?2œGpË0¨Ù¬öü3Ïÿþ¿þÃ_ú•w_}ÝEe^=ýÄÓÿåþbÐøO/¿òòƒ‡ÂÍ ñÆêÌžyð•*ʬÓRDŒs4[–\¼õw=øåo?ŽÜ|é›Ù¸¸ûÞ;¯»æËÐå§?ñùoë) ¼ÿͯ½sšw·œ;WÀ§ÿøŸ¼ï¹g_þWÿ×F×ç>ü§Ÿ¾áÆ+¯½öÐÖ«ðщ‡¿ùF9p[7žë?Ò€€³qÁ2ò Ûi{~6:¹R,oTƒÜÔµÄ,e-“X¡Ó5d¢fD¨Xm=¡9’„‘D
+m09Að-ó
+ßCD	Š†8jñ7夦];½vfPƒ{ê§aààÅ;wí˜9~iwu}ð;¿÷ç—î_Ü¿{&+ª‡yempÆ-Q“냯geŒ³ò?~ð‹þÄWgºéêúÞN?ºåúËn»åJ)Ðà_ǃ瓋‘`u}¬uœJÌòN0Xr†Ò|òñ§þÅÿö{ó‹³@|›ëý©€mµZoº÷-IšRWçÓצ°¾¬ðg:b0.êÚIÅ.:°ïß÷æû¯ÿ„zƒÛ‡¾þèÃß||v®§µ^]ݨ&Bˆ÷¿ÿ­Óô5F*8׫`ß÷Ë÷\sÍÁC‡|í«ýÍ¿ÎHAð¿þõÿúÏë¬ãÛn?òÁþõÚ¤œ’abÜ­pÁF-¦ t¼ÛŽöïJî‰÷ÌŠNÌÑÊ͆Š#Ç”2!˜Ž0D+)à+È?èCQk;¿FDd,Û²°GɾgÍöí™3æF1úöN”•¼uò¦h–w,ÌüÚûîh¥
+ll~셏îÛŸýÒ@Çœ¬„ýG8¯Çкßrº0
+0ýAöòñµ)Ãtᵯ¾òýÊ›v-η[-Rßšœzú¨34U2â€+ß:eòôZmœÚWUuêÄòÚÊú”ŽçæçÞõþ_ºôòƒ¬i*hëÎx8®YK­Ð-škű?VÁŸ{Þ~ׯn1Â!aeãä‰å)ÃG°Ã/¼çMÓÉ`0úÃ?øÈ”U‹ßö¶×qtÍ>£TïÁþ̧8ëoàÀÝg	çk®=Ô념EÀ¶Ã…¯‘§H4~›M—ÖŠ«Å¸Ä©?¶75i^nÈ{|’YŒzÙÒJóo=Ýl‰kÒÎ@Ë°)©KéÖl
+Z»£d:ê*uæõðI¦…’Ùݯ»>Nâ~ò¡'Ÿ9>]Çk§Ñå—îzÝmW=òäÑ¿yð	F¦9O<uìúë/A¥ìÎXÙ»õæCw¼úŠ}ô+/¼¼ì Àãs÷¼ã–w¾ùæDiÌtn–ç¦*Üé\<\‚®gºçE‚ï	pI¿úxâ‘ǾõÐ7Ç£¦@®ÕJ_uè®{î¾øÐå”ލ¶G@Æ5‡ƒl¹CJKÁ´?Ë*ÇâH楍"œK$IòßÿÖ{o½íú¿ø‹Ï?ò­§úƒ‘çb¸à¹¹ÐÅïþ…7\äð4}Îò—û¢7©`äŸùßý£_œ²0°3èåÿï>LæÃú™[^uÍÖôdŸ˜üÀ—¿å‡xûšÛoàÁ9`ûáÄÈ‘ûv&–ZÚ¨6Çدžc¬µúÝKE
+©}~1)eFò–Ê ý’»ûõG®½r?Ð(ðø®]=Üê°9“ŠðÅ=ðéUûiÙMÎÏ÷¦} €
+à€÷¼áÈuWî÷<ƒAÂjxhý®[¯¼ùºKŸzöä±@P­„_whñàE"‰¯¿îÒ¯»Ì‹ó]W:Gm9¶ I½áŽknºþâ'Ÿ>±´´¹Ñ]uhï%vìÝ3‹=–j†½­ð+ØzJûŽ7ÝÜp©Vš&º*mÒÇN(uú¸‹»w¾ûÚ÷Ýzçk–Ž__]]\\¸ñ–C»÷î]^+à8M3mß³•‰[_{ûõG.‡wYi/;|še»ºve…¦}£¬®
+Î%*!b)€y/»êÐÒ‰Õ^8YŽ7©'atˍwíšßêœÉhñ’K÷ýÓöþm§Ó¾ñ¦«¦Ÿ·¾ówíÜ9oÎÎÀUW„_‡/ÿÛ³gñškžë¿Ä€€ïƒW#ûŽs=ÝIÕÊf±¼YfØÌÝâ„ÃÌiÊ®Y¦óYƘن>k ú_¶ÿš+öûõ:N?¾IY0 cøÔ	
+tXL±€£
+ŸÄ`ÙµWì¿úðþ©èÆÆ"»ç	ÊÇ€÷Ýn|ãu_}øâŸí¾y™H\f<x`qßîE,üjœÃ¤bfÙê¼æ[˜ïÜñêËá°ØöNŠU…¼Ù#Š™²*ó#W_Tìµ*¨3KžíviÍÑ6z"è±~Ñ(%÷ؿZc&÷sð‰îW˜©bYÿcö
+\ç%—_ÚÒ—v:nÁœCc×+sŽ²¬S-šMÍ­­õÒšY®vìÜ1»0·Ð‹àdKåb/’âlõ
+}û7ü_ëÌl÷-÷Üþ½Û‚£HÃ-|öÓ®N"0ÌÏÏ°€€í‡W#O̳s>±|j½ÜYS•¨ã”haÏga¨þBÐ:.åùŽ÷¶)•f¤ ·æ¹5‚š7òÜ$FŒÕq5²§ $”}ŒŸÂI|Ïfÿm$Pò‚ZG΍cl:ÛAΣªöX²—iýxû=ŸyG>úÑð/½Àkž¬ø
+Ò>aÆF›
+x`\D,†?ÊÂ¥Ib/ßR!b­¡ÓâÃsÊÆu„M˜ÐŠšÔÕþ1aJ,=áiŒ½hAG~V–®“âXˆ­·¬•Ø‘“¨£4naêšÚŠÿŒËüGù‡/+³tjÍ×(¶Ûé=o½#„,¶'.ü•½ÐbÝ–ºxWº£DRÕØ~GÆUu;f¸\Oú´*0F\SLÙÇmáuYùPFs(GUÑÞQ#4ÒYʲð,C¤‡¯}'=OÇŽŠÈ\÷¬=‡Ò1AƒƒÆ,ªfí‰doR¢qì,ÿK?øø°/#ôëŠM>×|”Ä<¦@tˆ¶X GSJÙË™§¥†þΈ¼ð=ò.u‹ª¤ª?*TôE7äïÁ'L§Ó•.ì'J(^¢½§k·€¦9Y}r”§¶UØa at Q˜K(­c?;`Ùô‹'N_ž.H¾éîÛ®9s•/ `ûà•«‘§ÐŠ_¼»•ÆåòFµÚ/° ˜)˜bÏwõHñqÁœlfýH‚Ô
+útΑQàÊ&ÄáóÒÚd Ö¢ç_ÆÉÅÂùÂeVÉrjÏÜ@|%²k¨²²Ø6Ta¿Q,Òct¢ÓIxgä6œfRNÄMµÛÍÒ"§K…K0Ôl4í*FJa)"®¿II[0Â`­ò>¬³íXãiì“m,ZYrú'yl±ó•kF&ŒD+Ç
+,ÎŽx…#/í$"+°¢/¤T|FJ
+
+µÀÚöï
+YüÌ~ÑZÝrË5øõw~¯ýE@À6AøÓl°s.궵pý“«ùòXŽÇIåd§-"ÍA¨ZÏ­´‚ç¦òV`ð¡¡Z¢9 žºnòç`‹òμ	#4äX“nµøué#Ô¤|½ ‡3‘A¥9KV”,7,¥Ž8·ȞžÇ鐋½ÿñ7ïµäG·o÷¼j{Zç“D;±ÿ!7¢NÁÒ4jµÓŽN	ÓQk¸U.p¼©ÝwÝqýW¥Ýì3³3˜4AAÔÈ\ÃÇYQ™Jˆˆz^c6!Ö'rßH+!ËÒ`ŸY'm“¢g³\Ì´°5ÈàÊØXÊ©Ñ…	î×X‰$"ÛûŸÝÌííï¸óÈ
+‡ýëÙÙÞ‘®h·Ósý·ðqžõ¢þû<‹Žg'W²²fi»½{1^œeñf\k§$Y?L‚¿eþÛ0mñäë³)š¸rŠfzœî¨–¤‘̲‰<àRaíyw]	üƒA±…6Ó°…±Í¬±Ñ€ñ 5²¢ÚÂi±IÝdRO¥>ÙÙº&üÝXJ‡ijeaÃjcsêµÝé)×ÖE	ˆ^—
+Çós1ÝgŸ[E&<[˜Nà øÿÛûh;®ëºÛ¦¼ú+ðÑ	 E‘¢HŠ¤z¨bY¢dɶâ(¶g%˱³R;Yò²Ó#kʼn‹r‰mQ–-«KT£H±ˆ;E€½ Ú¯¯L¹-çÜ;óðMI	Ày·@èýWæÍ›‡¿gϹçìm#ÁK`g ^Â4ËCŽÈXiµn$I3…=¡ÒÈ|–÷1¸d²]&×­FÔmã©g0” §Û1êlàèÃsÃé‰æó¦’V:‚Fþ; *Ø8“6R¾÷©lØÏZ+X²j˜…Ìö¨tknÄ-‘ÇŒ@‚Â/S·ôGLm<„íoU™øT¯¬uE‘£U8©+=›Š\ë®	68ƒÖV(–.¬¯Zc¹6"<Â}0®Á\c²ñEd_aÕ<·ÖU‹´nÅw÷nÖ‘r#bŒ%J[`gûš•¥u…¹f¬E©
+o`J\3'|	FJµ:‰3T†=ÁHØwwb€Çq°”ª“¤IÄËBE‰Ÿ8¡¤ž·sÙ¸G ÌKiâˆçn`ņ·€7#? „WO`Ö®}ýÙÙÅ¢Hó¢±y&N27Àñ³H$uú؈‡sÃw5âº%Íu'TC%ÖT…câzæ8ŽÞᓯªÒž@©£Kß,ቕº™‹B‘§¾¹”•òõWöÊÓ®óÖð%lR.ª:2©÷ÐIõª·Ú·ßtàï& ‚÷‡…)Ñ	Ù
+Ah]iáD’¦b8,}ºbUæ4˜évdžƒ<+Jê½ÑÄÔø	Ål(ÆÌ9R3œAÏ™ëêÀcÏ„›R,”ks¼PÓ؃a6’^ÌŒü „8Ù/=½ûØ“ƒƒG
+©ÑÙbÃéϙϑ	­ÍŽ]õ@¸‘ko[ÁF]ŽRëþªÅÂs®õåæz=кuÄêYÕM"ûÿ‚mÄd¬Ïof®ÑØo”º­£x¿`Hü9ÀÕ»}0t»‘:[ým\w©íÝ\ÕwÞhv^ö0¶Ž&ð~Z§q”ñÑùòð¡å˽(6òBq	¤<½¾ÄAtC#|„9j†G3f©7h¤1ÅÉC²ÐWYa;¢_¨¼´iÇ\E¨ŸÊ’ˆ
+•
+ºÐ“Ù`x_YÀ‹§Ÿ¶êÇßÈ
+A`äÎéx‹o^Ó Vï=Ø 7¥îN§d>CeJ]¯w\ìkÚ5 ûú€¯øU¾‘µu/š+JÇÂXÛÕN´²§9}VÕŸ%]c%äïÆBÕºØ8ÁÎ|pÔ1jæ´Ú kMs'	ÿ2×
+/-'qUÈ.Y–%o¤#ƸqÝx¦ïU
+cûðu®™ûäLGèVQ©;
+¶Ënϙ𖞘ä|Ž¦Ü7äYTÐ@ðF)c[²`´Ä˜ÚSýÅœRF~&LEÆ6›fÍû üÖN°„»A»ZábqÖu\Ä‘sup¼‰åZOCk7o×I«yãíR[1»ðf“nÐÙ¯øéځȷˆ·‚^NcWª®9ËÖäÎØ1o9ëGH8¶âÙÑÀž­Çû”3<‚݃·“%Ò¥›Ô€±¿˜QaŒeJ.8¶¦Yç\ᙹîq†-&1w½z¶öÃC³il¡sîEB×Áì?/ºùãƒ%­A¾mb8¦ørtz$¬é¼ÈùG`ÕxⶆKCËÄ8oÄ/ÙLKCæÖÍ4PO‚q‚Äê¦Ô*á<§¾GíØ}˜cLFª
+²¶•Ãœksb[uMÀFà%yÏl%d²‰~=½eª§uãÎ
+8hªÓ€ï;FYm«¶e.ŽQ¶ël#EÂT§M\Š2ÔÄZgy¹f•‘¦ƒ¦I"ŠcÚˆÄÔT
+ÄšF,—è¡lÑ,)LXL”*7¬í6š	§ÝnâÒe1HгbAqÊ„m^ߐª„Ò„w˜ré&Ô,,<¥Ó䱨v5B¥oæ$ìèš©ôTç§/꙽g‰©±xËÚ´—V•s‹æ‘ý
+(xUvDŽò´o+&®¡a'2gÕPŠDJýŠœ¯Bø.wdUúÔ¯z9Í+F+zõ
+ÅÆÇGaÇç~D®.7׫‚þµ¶ÖÎ~¢Ñ¿cÊì|6LY”b'°¦Tªßë=rtavA+Åy[‹­ðb´56FÃÜ~§ý‹Ò8¼Wp®­‘a³ÌŸ*:­H•%ZQæÚB0+
+HÛ%RÞÆhŽ‘ZÆÿœ—J5’=Fð…ÀÈÏ
+«'Ó
+«ÛFå³GææPã?¦;øo.vÊ$娔Ý5¾Ó´*;`A¸N亀€Ã&²bp_årä> Ú{(x¡‘È‘®Ý‚ך·î© ¦²Ë öXÂ“pu>°U;‡Rdqa)ϳ$ÒË,@ÁE‘+%¤ÓisW¥v.@ŒQŽœXa ‡e‡jLÐÙS˜Þ ›]"¸2Ǽés#Ø+/dr\ÌÍp±Z·Ä)ìefØuáNÆû
+ÁÊõrÒ6âð2àEPµx¶Ø0òd÷áá#óQ4шâIA¦d>¯XÒ³0ñÁ"g:
+WÆégíZ2Ü܇àÕJ ­GŒ÷Z¯‰ÕÔ"W+«
+ˆq¥óÊ—S_‘@Zd®×ÂÏàyáì'°}S¥ÇN¸ÕÒœ!y†“BàR"ì@«™XÕŽãt||¼T¤˜]”¦šú6Ø24ªg‘ÑnÀÚÉ_Ê0ÊÚØÁ0'ØCÝUF¹^ŒO5®åxª›–Y)]ù«ÏÞ¼~ýÌùçn …Å‚¢×3>¥¶
+ÎX)sfÊBœxFÖÚ\{ÓC_þÖ8±½ë-/{ÿ».8Õÿ”NòB~ì²oïÿûþÎõkÆü
+<ß’äÙ‚3ºe]{ºi©²~fJWðí$U
+5	ÑJ,#|ÂV…c¯[ã¨먚ÏL5¾Aë„l²,¬UFrØlf]£!•«'q™Ï>ÍÚKf6z_RyÔYrÌÃ4d|¢=>ÞÆê­»³Ó““ññ±8Þ×¾I®VíHœZa\)–‘£­k“@±‹mÚ&qÇ	_'ý¯[؈ÓNÊççûŠ0סL€›­ÿÎ(Yaw‰’‘`ŸŒÂZJ_ßpä?—îæ›ï|ì¹~q@Ç¿öÿf©—ŸêA§Réo^sßÜÂàTïHÀ³BÐÈύ„mÙÐégja®ÿ¤àͨÑmrЮiŒkn„T>m£‰
+®¬ÁöKhgAiGÞl¤Já³8]m]Zkíy\Me¸BcQT3·­Úé܈#b„Zidr¬jÏ|lÏáÛïÚõÐ#¶nYýºWq涵«¦[.­ú—cØÏ»«™³{î{⊫î|ÙÙ[V¯ÛyÏcï}×…/ݶE­²ñ×ß™_ìÿÂϾ%ËŠk¿{÷ôTó½ï¼ØpœéX¯ºv磏=Å#þ¶·^ðæ×l“E™+³ã¡ýß¹n'ºsꎝ»¹øužQH,]äòÿ}í¶÷ïe”žÎÆŸy÷…¥’i‚ÿ{ƒüÓ_¼õÞ÷¿ê‚-眵þö»ÿé‡ß§ ã}âªÕӝm[0ä—½èG¸Îß÷ðË>yÝC»Â)!q_êU±Ü°µ›î|621Öüìw̬êþÒϾ֧j¦¾âª»¯¾[.yãÙï}ûyœ38|òs7¿ú§Ãó‹RýÌO]ðïÜ;?óS¯eqý@ÀÖþö«w|÷ÖGà#Œ¶÷û
+¾î¢­ðÖ×lèCï»øÂsO½Äï ˆú^¶ñÃxu§…«û.üÞeWNO´_}áé ù7¬›ø•½^î_µ{ïÑË.¿^)óö7
+ÿ»Ÿ4‰~㟿ãÆÛwõúù'>uýãOý¥Ÿ{íË^²Î¿d©ŸßxÛ£<r NW¯¹èô7¿æ%þ³øƒó3ïº`Çýûöퟃ«Š·¾î,¿Û£sÖ¶5ï{Çùý¥ÛF|ïþ¹¿øÛí-¶É/¼ÿ•Ÿ¿ùGþBýÀC½üà¼ó-/ûÂ7¾wd¶÷OÿÁ×Õöù3_¹þ<mN!3œ@ðßýÝß=Õûð“„fʁT–ò,7–'k'±a íêm%«®­,Œ±É«n¦uÑÙ÷QTÍjÞõy†õýs¾þ‹#Ôh¯L“ˆ´\HT†]ä“߈uÚu¹UsÕíÞýŽ_¿ýÁ²TOîŸûÂw\xþæµÓg”L+%L«aîù…¼(åáÙÁ57Üý䁣só½,+¯¹ážóÏÙ¼zª
+OúîM_{ã½{ö¹ùöAùíµmc#Ò˜¿ù⍇Ž,lX?59=vç]ŸyÚd3Kv?qä±=‡\à·½óîÇ·ž¾æ‚s7[LÑ2_½òÎo\sO·Ý€}صçpž—7ÍLtÉ¿ó±+¾þ{&Æ[÷>´ÿŠoß}÷ýOþü¥%± ƹ[Ídróñ€Ç7®›|æ/®ÙwÜ·ï©C‹RêÓ6LÁ=›ÖMÂáÆÝ÷ïûìWï¼ÿ‘×ßüðõÁ#K/Ùºfµ[€óÁwoyäÌ­33ÓÈ•ð-}æº}æ¿ðõïwä¥üÒ7îº}瞝÷ïûÒ7wóò
+¯<ãö(㎻÷œ±·ì³~í„ß¿ÁÇž8rèhoq)»ñÖG/yÓ9	þc"_ýöN؇4ŦÈ]îŠ_Žd
+¬úõ«ïùü׿Wbð6¹ùŽÇ€¹~ú’—ÁYúW¿óYàÄV3†û?{ŝgm]sžû¤ðä¿úü­pôö?µ oúé/ÜòŽ7Ÿ3ÞmÂC{öýôo;2ׇSË—¿¹cnqà?‹?87ݱa®þì¯o<û̵[ÝìØÇ?y]·.ö2xáç¿ö½N;}Û0Ïå?þÏ/Ï/RA•Ã>À	zæ/hù¡¾þ–G¦'ÛË|º[¾÷8|´¹ùA£ŸãN$wìÜó›ÿýKpÉ5ÌÊAVÀé¡ÝÂèþ¨÷úIAÐÈÏ
+À_«&âù©ôÀ‘¬ßÏgbm—Ê
+Ý⋳šÔÓ؈Œü(k“ûQ±á‘¥Àvôº<„T‹~Ä=d&àùnb×ÁÆ¢j2Å7xŒ|3ˆ÷¨sñ8©Õé4à×~ÇÝ{_ºm­ï¾ð{‚ÝÒè½iµVœñ‹.8ã§Þ~ñç¾|ã¿ÿ—Üvúšßþ¯ŸÚ~ۃ眹¦)â¿ÿ×Þ¾c×ê鱟ß»fVi¼(0 w{ƒb÷Þÿñë—vÇZq]sí-ŸþüMÿæW/å1{ÓÎyë΋òLÿ‡ÿúßÑìÓF¶ßþçU'œg>÷µ;/¼ðÌÍ3]{Á/ó_ýß_ßØíG;tøèR»™À'¥ö­ëî{ýÅÛ~ñg_ó,¿¬Më'?öÛüÔçoÙ~Ç®?ý½¸ü!Š í}ô#8cËê‘ßp
+ü’ÿ·ßz?ˆSøúù?ßx×[ν	‚ú+Wîüøÿ…?ù«®úîsÙ?ùägo†ÓÆ3ì€ßì0üŒó7_¾ýõ¯ÜÙo>øúwï™oý³ßü4pÓ{.y9|êÏíNá~Œ1 ×Ÿ}ÏE ÍA‚à}ðѧ~çß¼gÃÚ	 , A ?ÂW^wßôTûSøAäU™nÙ4½|OÞ÷Î.}ÇyGçúïÿÇ—4öwÂa—ž:¼ú7°öòƒ³~fü#ÿêÝøã¿üK8«ÁÁ°„ó{ùÀ^u|„í·ïúÄå×Ã.ÁŽÝpë#·~ïqï~î>g/ØΏ<8Ë5|Òåç÷ÿôê_ûå7Ã{wUç~ì_üíM¿øÁWÿòÏ¿ööêÓ_¸ÍïÀÉùõ?	uä猱ŸC_YÊCs¥4¤R7-\gG­Ä߈gÆîZY¼â'ø«WY[	d22¦¨9ÚÛÞ[gdá¤5_{*yÒû;¸ï‹WÜñŸ?úÅÝOà¯Þ<—'èMF_;ŐiÐAÖ
+õùap2³z˜ˆsë–5Oì=Gœ1ψcñ®K.šžî:qUfÂü^-.
+à9X¶ù֍S{÷σŠÇÄkgM¯•AfÜ1Ì3TØÍúƒ|¬ÛðŠ¾ÕˆÏܺ¦,°äjœ¯UáWˆìͯ}Éóç>æg¸ˆ,‡ðKžrDg ÍúCŒØö?ëÅ‘ë4ÖÎŒuZ)ÜxæíÃÖ@D.·7o˜zò©ùa&GO€‡¦&ÚðÖ°@IpœDç—†^Ã™Ï}éú¬Ž'˜1˜â¡#èèÈ|ï޽眹Î×àïKÞxö¶ÍÇ‚_á»Øºy•Ë펢¸a^V_»ý!­
+œàǧí<øRá샿Ž¸|ñï»mó*8—T[;Úë´“Ñ2À¹/Ý ~TÌ÷jàñåç•lyã«Ïô_â…ïb÷¾£œ»ÉÿØn'qòBÓ”/´Ïsr0ÙM§'do LG–r;Õ¤‰[+cuùØ·9xêÓ#‹NŠz¹*×õbÁªLUüÏÕ¡YíIojR®C<£Ñ;3’Ôõ-Z;|z¾óÞ'.yËËë_¿·ÕŠwï>ôäþ9oñì»8ü»3‹“rYdmqe
+Ûª	0ìS‡æ›ðª'½þâ3Ae[ih-ÃÑQÈyØSŽº}ÍÌäx·õ䁹3¶ÎhÙ¿uÇÞ—žuZ»™:7;	Ÿ"Ž¹+×`o²2jÕTã§/9oÓ†é‹^¾y|¼!(=ºû4'KõÈã‡Î;uhd¡ï{çùIÍ#œX;ppáËWî¸ø¼ÍðK{b¿YŠSã­ënzèÝo;.2xä)ŠÑñ†MÁÖVOuvÞ·÷õ¯:£,Õ5Û:ÿœ­æ±º3\¸Àå#à#¿÷í$¾÷íçmÙ8ýÊó·LŒ7ŸåÙ„$\æÿÂû_	üçÈk¶?ø’­kÎ=ký3¼´öìüàïÃgŸ±´óÇ>ñí…¥ì™ßŽÒ°åRªïÞúèáÙžèçnþÁŸ¾ä*Hïïí÷î}â[×Þ÷«¿ø&ØÃv¨áÛ\~p¾pµðš:ÿlÞµûÈâÒÍ%Ô‘pŠ.J;ßË@€rl7jœ´*8°ºjá,+ˆõI{U×pM©Ü%wàd¶Ëôóôí¹Ø;ÌÁ3ÓˆÄn6dXV^ ¤N	¡u1šVŒY͏´šÉ§þö†í·>|ý:¼xèÈâ]÷ìÙºefㆪüê-&{ªßÏ]Ê(aúðcOÎÍõ^øì—nêýùK_½vMg0,þàÏ®ºëžÝûÌÞq×£wܵëô-3ívKpÞŒEQÊ?¹üª[nàÊë<:7üGÿà’ɉv)miˆ3ÐÈW^³sýšIø½ÅÈì̪±?øÓ«/ûËkoºýÑ«¿{ÿ]÷í{åù›Æ;•úûèÇ¿ýÍk‹ñ·/“{K½üO?}Ãm;vü“ׁl¼ôçûçÿ0™íýï?ûΗ¿µã¡]w>°ïkWß37?ðuäË?wóg¿z磻Ãå9Ü4á«Ò@ý ?úñ+¿~õ½Ÿú­wìÜ
+Wî§m˜ºùÎÇà"¶”,	—ÛþÆÞsï¹ä¼¶°µ5«º¿ûû_ûÆÕ÷ÀÖv=qä·~ý«¦:þÑ»xØ
+Î1ÿçϾ_å¯ý£·øÏÌt÷ýñUðç×ÜxÛ£W^?<íl§÷\øÏ¿ÿõ»îÝ;Ìʍë'ÿÇ~Ëß~ÍE[Abï¼ïþùµ×ßüðe—_¿ïÀÜß}a»•ä…üè]	BÎa µ?qùõþ6pßæÓ7ÜòÈ埻^róK©·ß¾>ŸÑÁ9ãôxþè6èY88p®»ùáÏ]q'\qû¿ûï;<1Ö|äñÃùè—¿råÎn{ôÛ×?à…ÿèPÀ÷¿þøê·¾î,xßÑÁY~¨ïº÷‰ûÏ.ñgt´Ÿö­Á6Ï<}æ“Ÿ»ùkWÝóÅoÞÕä{÷Ïù8Õ”pÂ돇f‹ÍQ&6l˜Ú<Ãb^õÿÖ9FŽëé
+OÍ^DuÍ@{{ 7¼gle)E•¸ö=J¡Ï
+™h‘É””šÌ±”\ÍFûê³wïU÷…gj*bw=~ðÞû÷ž¶iúÂóO»ëî'vï9üªWlÝrÚjRÜàž'ÃaAg,†M\ñ­ÛvÜûø¯þÊ»ïØùð眶nºsÖ¶ñóÙg¾r[?£îÓ(ÁØÅž9>ÖáÛ×ã;ï~ ñÖÓ×­Ÿ™‚ëÜ~Ög<i%Q«Rþ»ß¾ümo:ïC—^;qœéõ†×n ä9ìöôê©÷¼ùL¯á$\ƒ?ðð ò×^´uy=ÔwÃÕîôT{Ôðð½³sýÑ=Û¶¬öð;¿k÷áÑý¯½xëòË| Jßf7ځ]{ß|Çc~«§;pÛß8|´÷#[>€7ï{hÿ÷_àþ/¿q)ˆÇ·¾þ¬Më-TÓÁ'
+xÕ/ÛôÒ3ÖÀÁ;áÔ91Þzõ+¶|çÆýíw½õe P´Þòˆ?8¯å~¥KiŸ_DÛ^zë]»ýíw¾åeÀ¡p|¶ßþè`X¾ñUg »ù;9:8pXàŽnûCçkWÝ}ÖkAÿÖûâ§ÿèŸlÞ8µü‹#®¼3Ú NxáÛßtöÓ¾µï?ÔˏöÓ¾µÑ¦€÷ÍÏÚ¶æ_|ä3òÑÃÁIýå>ù81ÈÌ=..ͪéöæµb¢U]Øæ5󊚈G«nšTN@ÒñµvþAÖÙcRgoo)ñ86mª	éþ_8Œœ~Iú…k¡‹œ{œq–ž®8ÂjGPe2rþ¬œÛF…SM	Û_X4‡Ì+eq`ƒ'wß¿ç²?ÿúì|ï—>ô÷>ðþ×e½A*è¶-Ýý{‡ç2Â@¿HØ 5Ú÷•p¦ÖäÝv2=5þā%ø$I$¤*
+£Ûoypû-D‚ë
+úÙúÍŸ{ŹëqüÏXƒ½Û,—*¤?…4V·NõWzR4ô‘~øî7~õíϼ¶¢ tñ¥oíøöõ÷Ã5ÊÜÂðC—^üá¼ê$ÇÜyÏñ™íE©öì›}ókÎüÍ_gü
+N|á|’“Œ8¢­?<?,Ëx˜‹‰fÝ5AȨ\;r•¨z-&3á 	©$¨»…¼¬ë‰’ÚdWU5{ÿÞ|yM»¾ªˆ&?½íçAHÍòÖ»Á©eQÙ#JvÝÍÌåû)MŽÎæ‹‹}Y*
+ê
+3ÉøXë§ßq1ÜØ´i5®å‰X•DJE±2èMoÝ8µ›W1‚oÒ¿zõø“OõŒ¥Í4R¥D§Nk6`™bK’0ø…¹ðå›×¯›Âj¹«ËPŒ¥B1{q Ö¯zÑe߁¾þeGÄÛ–]ÚÿD`ÓºÉ×_¼
+Äû+Îñ¾öäïÀÔxëuoƒ¦_ùû«_uÁßÂü‚AÐÈǏÝû‡î^ê4’M[ºë'¹È¹Ê•qáǤò{ £…!íëÈ„ŒzˆµëÁðë~䚺†9 Ú×Ü0@$ÉLù4²²ÕŠŸ÷-¢µ#>ZzÒŠÁ	©Œ=½«‘ñu;R<#ƒ!Ù`^*­4¥ØL‡Õ‡ª›ÙZ‘ÎiÑÏ';ñÄXrx¾—xš›47G“7PÙBpš$tr¬9·8è
+t·Û1J8ë‚ç‚4bԐ±ñö­Ìe»)œ1Ãñ<fà]ËR¶ÑžƒmÚ§úËXxA^N2š@5B”ª,
+ëûGm]šÌ
+†TÃwUWœ©‰xäÐ6šÑࣤԺÐaj»"GmHоïÍgK߉aê—¸,­­æüB∫ˆ;Rûû]2VÄ	ç	eÂÒª™Ž¹0Ê8wN£±àqĵ1nqÎh#ÑLƒyS$lj£ˆµšÍ^¿œ_È[í¦Ë R.CÏ¢Ž·’q,QøÉëHààµÛg´«‡«N ô}{ÓãÉ©þ&V
+#?8f2“¸ÑÒ†UÕÛºVk¼ÿÈ^ëkVq_ÓàŽ»}°[f<äÝâµ®ÆC|7ÚÅa)¡*‰ºÐlüDµËuÏ«
+z¬Œí_á—±µÝ68õ§X†ðF›ÈØÀ¾˜ghâŒ8©°µ§q¬PT!Q°*N"%õì|¯ÙjÆQ$Ë¢
+ÚCÉíÊÜ‚k—…n6„ÔšbcsuQæ&Í SãíèYò€€8#?’ÈMõúHÔÄÕy™[ùªÌ9ëå/“KGʼþÑó¤tì$xEš¬n\ó†ÈðnDi¸j¿+nP_&Æ
+¬€öýÅ´Jž®H¹ȤžÞ¦µF&¬jzÃX&ÔÄnMÐûa Yj”ÇXì`M8y¡TY–Qi—hê_	ÏÐF¥
+Œc]\êÅØPѳRí¦)@DcªÅʺֶшÚ-꫽)¼éÜ|rì2üpBùøá’œ@Ö&íhõ^Õ…y­I}]–Ôíž0qqÎZoJ+wyRU|½B»)‘-ÓúšŠœjv¡ÔÔ»‘Z{í<*ñ)Þ´¾"e¿ÏþL€Ñ$Zi£14c(“[®‹°ƒÂ™:'7xBžqq‘dEÏšV#QZÍF\ä9ì»36
+x,0ãðž1Jc}ZJ
+/‚€ƒÚx8,lå³6ILIg&_tkzÏ€ÐkqüÐXeSå³N=Ÿr{,/Î̓ ír…Çúü#£7VÕ‚+cmª4<à2Ì(‰m±wØÖöÇÞòÍ{áûÈT?Ší=á96ìç5)«%3ªuM{&ËJCcx=žÆ,q"pÐÙåý£º“‰æÄ4’x©_­A4w[)06p÷äX·(²,/º““ýþÇŒJ¯V:O|o&b›4pù¸?TXzvR)ÜT^¨±NÌC²^@À2üc:7‡VƒF^¨:­š²c#ÔÄ+"BbZu\ØúNRó‘Ê
+¹r4fµQ°-HÃÝ.̱Z„ѵ-œk!ƒ¸5Z—mEj·9º|9ѐ¢ õ­y‹Ý(€I	o$~Âò°’F¡fœk-±",X–áÂ¥º?lX»Jˢ׶'&{ý>¼+ÎêžhéßÛÅ©Jx#5ì§R4Nh‰ÁQ îE,ØÑùl²?ë#ð¢@`äãG)ᜦ‰ËvD«\Q¸Î!­*·#Nôðí¤–Æ®i
+©™/++øö	‘´ÈÊiV`9Á+u¬t]vnpžmí¨ŽÌªˆwLö9~ð|‰äHâDÄIª8œN,ŒÀgÑJbsŐ‘D±*d«û
+D‘¥ÖäÙpÃÚé2,õ†­îÄp0(7ˆaz–¹dŒÎãÌGÂ	W‹ëXÓp]"@Ъ?,;­$>^¿ˆ€€*#?
+©³ÂD‚¶›è0©\a!r]À®¹‚æn at .ª-/FhuOı„<R·a “J	\&È°©–ãÜa‰[¦¬j+ö<&\ór•Zâ:‘•>¶¸G—‘}•ÃÕ†]#sD¢ˆÆiF¤•ZP±Ž
+ÅãÈF0yY`þS»aEºn¤bóÆUKs‹ƒ¤ÝÍ‹"Ï>™qȾ|¬‹A¨F»b±‘ žº‘ˆ¼´
+£mGs‹jÍT¨ <¡Ž|œÐÚr“&ü´u©ŸøÈ]>ˆŠSÎÝ‚:Þ4N;ûõ9ƒyÌtùhµYvVôU`d à8%“hWI2…C"h½ìÝ|c†ŸþðÚÛ'øÙQ¶­ì2|.!º.c]‡’ø¢ò/·ÞÜÞº)BmÂ4VÃáìY¶8²¸˜VO­šhíÝw¸´<iµ‹²Ì3×*âŠâ.ð³9ß}V]$
+‹H{;:¸6ÀéFÛ¥~99&Nîäm@ÀO#/(T#a®è“NÉ6œÝOŽŒ„Ãé±zEUN ´ŵùqïì›Û@w;9Ì™hb騵@Cáê©­ÛÚª=·•jrîlÝí¬‹|vŸO#¥£6Ø5~Ýÿ=¬‡F+)¥ubiè¾ÛîªRçÃáúu“°Q cîq³™çEYê²Wy©¼³ËŸâJÙVY=A
+³^˜&Q‰Ív8—­Œ]Û6¼p̺N #'ú™’Útǁ{0%ºTè5,"”ÃÚxn"£)
+¶¬Y;å‘V¥cd­«,¾±i¹Bpa]hˆOª¶UÓ1<U9s½d”Bµ«ƒÐÚÎ+ÎÞÏ4,wáOnÍÐ8=i1p(%ºaã›/@]æÍ4M¡e9=Õìõó¹…‹ÚQeý\)àbj˜rn¥äŽô	º%ŒnE ¶ÓfCä–›—Aq—ªÝŠŠR÷å†U/.S¡€€gPG>N+4¡“ÀÈUíRŸÈÒ—º\³j‚™Õt<ªW‘Ëš1ª^¿ìfH3!ciån‘a_DeLá+Ê­Ñù,O¾Þà· «>BªfäÊþMTO󚝻۱ÀÙ$ý[†ëÁiëÜŽ°§8‰ne’RYÊù¥‚§,:.”ÄÞeK½àWU^ óU²LSr»Õj”¥ÆENŠýª4q$£Zá,uš„½€€ŒÀÈǃRšBš±NìK¹´hFÝL›>6*MFmgËþZq´p>Od™å0²`d¬YõÉ
+ÜŸñ¡|~ÑÏ5lŒc¼Ê«Öµ»vËñÊ:™±ê$ IÝ€a«ÞdâHÙ/º¾4\.dY˜ã½¦Ì‡Ìä­”uÿ÷JADËXÛ_*Ê'[ÐgËÅ臵쬀“è|¬;ívY*Ñ8Žòb`UÚ¤)[\,zY¹au0
+ø¡U‹ãUÐÅÝv"*Þ,§Ãœ¬ž¦@ £ª±Ï¥6µ¶#׋eËz¾ê`œU›,QÉ6blg½³è¬7|í[&ledQÏL“ÊÃG:Q±jGšÜq:
+âÊÇÌ/ŹõFEd”ʤx& Õ¼,‡ÜèUS“"Ž»Dýa®¤y+µ¡Nxã_næZðØR­1*Pr”É6‰ã,Ë8§i­à¹Àâ4d&ÍÆP¯xF|<XêçFŒ½1Å‚&@j¹²qñwÊO›¢ö
+SY“ú9…$y‰L×t®;C cUIÝÈ5½i“‚BFA|~þGS½…{¿nèc¢¨3¥ð†Þ=C¹Êh£Áâ„YꢟFjýšîš53K¥=´$ãTû¹„3ƒÇDŸ
+o2‡m°)¡‰Æœz¤c4 è‡{—¤¼™FEQXlÎÆgs}9Ñ¡^ðÌù¸@EQªéIlëIohg&‘¦€1½VäX—Åhùº^^ûþø'À3—r,C·2Õt±O†nùŽ¸z´Ï‰„+%×ɪU™¢¦yßtLêÙkê¬?Zuhøéopal5[hŒKºU Íg&; s‘K½žÁDê¶.õâÑ>çq)µ2¾N¢™Ø°mM
+¼6À¨ ÅÜjÇ”ËáÐ4[Q§-õúenX$'ÆŽd­„MS¡€€ÀÈǃ¼4T`ß× ·Ã‚*%Ñ4˜såRJ¥;¨£êÄÈìÍå9»ò±Ÿ¢¶D¹¤; »©.éÄÕj^¡pØ9Ô`—1ñNó8ðF¹¯{ªMú$'[;<@íR__®£Füƒ°ŸXAÆ’·L	ðþ\ôeY”Rš4à%‹óÃ(Ž‡…sªÀ¦8ƒ&ÌnZN,.XV¨áínT–K¶h$	ïÆÆÚ……¼ÙNZÍdn!˜Ý8Ó<Õ_Z@ÀO #?g(mµ±iŒ®•‹ÉrÛmGq‚Gè±dS{oÒeEdïú¦\W²rä‹&Â™=M•-4µµq=®àÕ¦žÕ}´*YÚI™²jlšø·ãÕø¶’hEœDØî ü þmq´ÏRm|Å“ÊÛ…á”bŒ-€‘K31žtÊETö–Uµi¼(p•íqviË–²gLCDl¬K©çæ†ÍV,8ÍŠRk³ymû$G±ü„"0òs
+Ð`ÌÑ¥¾(ÑóW+
+Ùº•7Ìsb#‘z,god*t,
+)
+¶0ƒ2MiEX,Ž”èxdžiHÕ‰lm­vYU2™Ð»ä:á\ù]xC
+ÌìˆàÛ¥1¶F —¥umÇØPQù/›÷M)•ˆDÌh>ö—úR±N7ÕJFÆ¡ý³ÏÌ'lkªÑ¼BFâ"¤šmçV¡S8Íf\*5ä"†·ÓTô‡jãêV$ÂrE@À³B`äç¥|3:QŽ‘t9‰£ÚxÞh=ý¡—Jg$(k|B§IZ¸dNÒMK»„'ålÌ+¦¦ušx»úÚÞ¨P–8½ŒÎóÌg'¡=`ÂèÈyN"¡c¿Zœpxœ	ÊÒhC¥2%jX¬_(c†Ã¡¶œÇ(â­æ­ÉÖ‘Ù%YJ
+wQ´}Óp6†}ìU»c‹Œ3,O[ͤÑ`ƒA¡”2š®™n-
+ËuSÍ°šðìù9C¤¿8ây©}‰‚qG•’%Ž…#_ãk¾ä˜=q-hÆ…O'i¸¹>ié8ZÖgãú…]£…®Ãô˜m*õ±‘âzŠYoŠóøÇÒÊé͐œUݾ؁¢ØÐBZ4ª—¹¸T²,ö«%"æül¹&FØ’>9ÙÉòr°4<é¯á$¡ËÈ
+þ¤üDt·eKÌB°4aŰȲ¢,Ùª©d®—¯j¶šáX@Às@ø…9DJÓ6\Ô½ÕXD¦>
+ÄÔEdã;ZµWbxòc»M:>87wT‹¨é›ø°>RYÑe&ô¬. <-1Kª2M‘*ÑæX/ë“Ã4Ò‹ºh.šÙ ‘F’ !' öó×)“ÆèÉ©1xËÁâ¢%¼ÀõD4M,âØVÕ‹4æ­V{i11jrÎx§X­–úyV°±n4ÌÕÌDc¼ìž#Aò\»R WX)À54Î*ÛM_8ƦãeqJÚ¹¸•›—£ûŽ¹»³§qIÐ[{§Má–æ¼õ„o_³®MñcsÆY[¸Ó€ODÅ (œøů,%fB»¾7äbìP.U	6A½åœ*â(Iàèa–++Ì™2ÓÓãÖò¥ù>å¢4
+ Ð`>VÆÜRJÇÛ-¥Š……ˆ|,µm·0fzaiDÜj¦ æW§“c!a: à9#0òñ ‘™[)mY€¨¤ó¹JãxjÂ%çq×êKÐY/›ÖS¶²­HbÒŽIìÔq/Gd!p®„» =^Þq«ò±5u‹…Ï
+ñÔﯕ®Ì‘%2²V
+ØØxßÌ©¦Hœï…UŽú1éŽG4m$–ÙA¿”®¡Û(NqÚhl\Ûw`V*“¦	¨fæ¬+àÍ';­,HÃxÌ#.Œ-»cífLææ³Ky»Ý`ÜL¶Ò©@ÇÇ…°~<h¦˜¶ÜL£¼(úbÁ÷ÌJi‘%°ò^Æu½¢ð–¤‘£cǧX¨`8úAˆ[Úó+xÄ’º›
+Ý–uÖ?n;uþž¥è:ϐÇ-g¸3/u^Ê¢(PƒèÅika(%
+?I)‹$½ñ¶”aÃDÒQÌe‰%;Žr˜Z1*ÇǺóKn[hmCŠ[=Ùêõ‡…ÁÄ&´V&²;ÖL"37?˜[ÊÓ$‚m\Õšž“ lj ‘©0ƒ{xýŒàD\4ß#«&ªìQœ©*ÂV
+]â(2iD$qt¬M£ˆv
+2­¾vÙ @Á>´‰±jèÛºaFŒšÚ—5Š’f9¶|ÀÉ@JƒA¬3¤á©
+ãí¬3ŸÀ
+3è»E>z¶ÛN›ic8ÀìRt«°§’¥éÎÌÌÍ/
+"þd…dc«ÚÃ^ovn`8XÌŒæ	‘ÍòƒGãc(ŠN[Ýh¤á_T@Àñ#üþ'bÁr©:MÒhЏy^,.#7HÝq!}»…¦XLpä›DÕ˜56ÀY¬ZR™Ð‹¨rqƒ‡+_c×D¬ÜŠŸÏþ€ûŽ]ßvà)I=Ì0/†ŸZgÿéÝ4Ɓ [?ÌG]0r‰ÊTðȲA¿f œÑÖFd%lb¼Ûïeífs¡7_j2Ñj%†ÊÞb_ëÈr è>RÔàí–hÄâБþüâpõtÎ[×µY–øñù8‘&¼T¤Ý$qT*mÓ4^\Rûæ§oHYÕ†™s£—X²HX#掩—†¸ÅÎ÷ÇYhú•@o¡é;+Œ©Æó0:Ïå0I7ýœFN€уè¶ñ¸u]vØE¡ªdüçÅ Òe³¦Ì*ÆtšÄfGj²8XÂÓ…Õ%·Ip D€Vžœ?<;zToÜL—úÒZ†Qz1ÎrjâF<Ñåi=uxinnizºzÚš@Ç' ‘ÝgœõÆâC³ Š’O@Å›6$ÊÕ…•AÍÓ’1,bh3T”¶ÈÕpÈ’„sgŸÄN#›c¦ntÔ³Áª†
+oÔ»GV’"'ƒLç¥*•½l´o„s©I#ãæ´ÖÜY»ˆMâf«Ù„óGoÐgV»i at fqÀDh#Û‘˜oõû‹¦H˜9²¨æ3.âˆ1c$œ¢$Ic19†›Ü½ïˆRjfÍÄT;
+B'
+‘,ÄÜ®N¥öKkrñó’óh¬ËüÄs^¢ñE#±Ígó2¡R1m)HinAAÛùÙhØN+ŽÚM€fý+]«\Õƒì½ß(vÎÁCEa‡…b‡›£c1‚‹s×[áKÎ$-ó#ÕJ›f#i6pfd™’Ò•8°ÏÓºŒ91j˜—ÑX§qôÈÒ|_eZ¥q×û´dN¼	t<³òБÅN«!ZÓ׶1	*  à!0ò@v3cñMeQ¦†ÝÍ-Œ7
+T»E¡Ëܶò¶ívß\å³YQŽH²·˜ãT´´Iqš&QÌ#Å1:†?¾î,Ñ,ß9T¸å>kjÿeK…K-E‰¬ñ¸Jˆ¥¬2·i«U÷³2ËJŽõWA&JkŨ™šŸžìY¿§z¹Q”Æ
+áà!Æ¢4æãcIšòáPï?0;99ÖJÅÆ™V°
+8±Œü㢙	²~ß.”Üh§¸ö••ŠqáêZ*;’~ä
+M{åb[5vBà<µ V íÅ]\¾‹"Ak7REL;7"Y癕'¥.K×Ua*ã!üËÀöª»,Nß¹'ƒFÍ­fÚî¤ZÛÅŬ,K7È¢	U@§­V«Ûn•E~tn‘;1Ö–Z)e0”	ÑH	pq‹#G{<¢cV7;ÞZ?  à„"0ò	@»!6Ì$–³sRTÜL4´%*ÔYÚ`$i'$oòA¦¥–”pt&J1!%-e	¬×hD ‹Ñ„“U .Ž8¹ÍŽ_ç™URãTž2þHí#SVÅ©èj"Å;d`(KÓÔ1HïÅ…Q’3“Ä<Mâ8j÷÷úÃÞ°0ROµ•±™Ì%ºâyEÒNñ´Òí´d©çæû„òNÌÖoÉLÏ#Ÿ€f\7I9åK¥Šr¨x³ôJh_¡Š"[XBÄiL³~9{h^Di³åõ,·Î¾ž1Ê8{r¸…q¢„Ç$„q|G9J\©“4´¶(ˆ‰qMÖj쀳8ú3ÒHÒ(™Aê6“¸ÕHdi‹¬l'4s ò¬kË,Õ‹%\æm‘ºá'c+ÚQÜiG‹}Å¶i&øj<¿Œ|Â0Þ‘ {¤XüµÐ+µ‰9ɕʁ?ç³$áét£3Ñš)Ì‘…"“†s!œD ‹Ic"0ˆÄû2´ÑàQ„䬵ïV6nÜ”¯@W £|ü(º±ÈU.,p:ÖŒj¤i##ÁK©9)Çšpšý¾Îqò„P&(‹0IÚÚÒèžV2)t^Èɉ±AVèØ5Å­­B¬[Õì·€€çÎ#'àĎ恣ò‰ƒýɉV^€¤EçÊ¥ÞB–«©±æ†5ããcQ.큃½…žJÒ4ŠPwrÔž–9sNâÔ®ÀbZ\Æ1–’Ë’d)­”šD»yOÐÆw [ß:ǨFŽpiPhˇEY–2+Jãè8:9c:¨j㲡péÏ2xóFL[	ƒ7“šáÉ y¡¤Òk'Ý`Rp’„Ï	%dýtÔm¶ß?`"Z5Õœ›ëÞl&raqȹÑfªÝãci.‡ mED´Ôe¦ÆäÁÒ G‚¸Ðs½/%Nþ[­
+ö»¹%<7B\ª*Ú^ `ÆVd¸›	"$27Ãlh´"}(¼Û+[{³"npE‘;Û
+:½TîyÚv;v±7k'Ó‰n°Ó8©ùù°ß“‡†ó½¤©”À¦(
+¢äx7Z·v2I£¹…üð\Σ8‰E¶ÔÆGB$‘ •G´Ù´SÙ3
+¢5ËP%+]
+I{ sÕðJÿóÆCèj‚Ø…WceÍ+ÐnGífK#A at k£,
+†À„‡Wm˜iuáTp
+ùùE.Í“‡‹¹Å2Ï•3›×e9l¥ñÚµÓI/ôóÙy4&È9¥Œ~Ön[­8Š±® ¤Vh|¬½ß¦”
+¹TKçØB[0ê˲@7NgtÏüh32½ÊnÄX"Z—Ô°Ñ­VÚiGð’VÊ7δx†8uŒ|2êÐ|yàh–ç%g25r¼wºmËØÜ|>*7gÇ82¢#ž$,IAõRÁ0Ï)/,0к›ÓÃf ¥ÛØbàS9”«iàì5uîùŒÁkÑ÷;8ˆ4ÞS¿nãšêÆÇ; Ï­ÑÓãÉD7baÞ# àT#0òIƒ•Ê™/æ{r~I2fµ1͘u[
+siàQ°³†p´f”¡?2ÇÅ>dam²¨€±ËQÃße)ó"£nfÕµÆdwœ"عìà˜Kç¤Iƒ>ØªñtõdB¬F>Ù0¦¢æ…^1;ŸbšiÜHãV‡¦ó\»H¬7ÀŸH`XFùá`4ð²¢®|I)ËBEé--.áQøÛÅŽ å±ÁlÓ$)Ýj5Azf'»Q§óàG°òù”Áù“aìœÏ-½òm5£F­·4‡&öuaƒø(Uÿ'¶
+º£ë¦q©ªF!‰£·¶¸%ö:cj)¥–kFãÝ8ÔˆV8#¯ Í¶Kµ°T²}ˆ@™u¥aZ}S.÷ɺDS¼ß8à '¨ñÿ(ç,â´‘°±NB8Ìb"øÉ@`ä
+çRd±²ì¨Wâ¢zn¢=¦ÅÙ<΀|‘pǹ°.ð@`䀀€€•‚`°R9   `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V
+#¬FX)Œ°R9   `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V
+#¬FX)Œ°R9   `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V
+#¬FX)Œ°R9   `¥ 0r@@@ÀJA`䀀€€•‚ÀÈ+‘V
+#¬FX)Œ°Rðÿãz߉Âʼn=    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_emsmdb_graph.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_emsmdb_graph.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_emsmdb_graph.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,325 @@
+‰PNG
+
+   
+IHDR    Ï   6ù"ò   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìw˜UõÇ?ߐ¡w²PzPŠ`AAP	ÒDAP°ó£	XD at PD@ª(]:H—zMBhi$”ÐB(9¿?Ι¼³³ï»»Iv“Ýä|žgž÷{ïܹ3o¹gN»23 $ílô.6³Oh'’––Þ0³—K友[›Ùóíí¯•ól
+œ
+<nfCÚѾðU``àànà2+.ÞÛ­ì,Œ Î6³É•~öÖ^®4³ÇJõ»Ç9F ÷™ÙÔYºà$é`$m
+ì<cf'Íéñ$Ig#iC`]`˜™=8§Ç3£HZŸG_3³÷´Yècf“ÔχÏÑcÍlZúe€^föj¹¼'pð8ðCàûøz° ™Ñž
+ø%`À…•ò7¢|ööÕÆy¾ý
+mgûµ£ý'ÀÛñÞ€3Km6&GùÔx	,õ}‡*õ Û—ú˜¼¼U:Çñq͹åÖ‘°g|?oÓcÉ-·bŽ(ýw–·s; ï㣯SçôuÎà¸wÆTîǵÀb¥6ËÇœ=-êŸ6.ÕÏœL‰úwCJõk¯—úŸ \,Ò#„‚µ€ÍÌìt3;ø|tzD!YH"é%ic«([VÒÀQµ|”oE$-'iwI?‘ôI=+õóKÚAÒO%íÒS£¾}‘4¸N“w…ÅãFì#©o¼?)êÿ€KXw ƒ€ÿ‹úïáBÔ@à0 p²¤Ñf`A\ƒP÷£Ú’¤.’úJZ4^ç“4¸ü{´Jé;V”õ4PÒ†’V•Ô»R¿HôÙCR¿è³ÜǵøïuŸh?_´_(ö—‘´|¥Ï¢MŸèw-I–ê—’´®¤EJeŠc•¤(ëû‹”¯½tL³±$ó$oW—¶Gçìpæ(+ãÂ/€ßãóÙWJm®¶Àêÿ¬
+Ü,iá¨?$¶·ñ¹Î€“$íõ=€ëŸGÇþø¼ÉÃÀáu$—݁1ñ~»èôéRýƒQö5àXZJ}E»f\"z§Òö)`™¨¼X©ŸlõÓ5€€¿Åþm´Cã?†?é÷)g“hsHì?û7Æþɱ? tÌ Jÿ‹ÇEÝÝsZÍ­koÀŸâ»r0ºô}ß*~¼lW:fRå÷1æÚ¬÷¢üDàÃx?X%ê›i€ÍKç¹°ÔÊàü(;+Ú°%°p{e<ÇïJ¥ßÎáÑϹ±*°c¼ÿ_iìûGÙ%sú³Ém¶ÿ
+
+Âý
+êÏÂÒöŠýoÆþ¹±ß8 (Þˆïé/£®Ð ü-~s¯ —ë—ú¿…k“ÇÆwwÝRýMq¾[ñyê8 _©Íñ'ø‘ñ]¾6Ž)æ–ùßÃð§ö¡åßvk^¢²ÿWJsKü-~çóEÙ£QöãØû»Æþa±OƒsžVúó0¤N£
+¢Ñ‚Ô„GKõeaÙR§×ë'%!úz3ö«6îŠýs¢ý-Ôþœ•úõ…€ðpf¼ÿñGÖÆ°7µ?³ßDÙzÔþØ
+!å±ÿFìýŸÅ¾pƒ_.õÿp©¯ÀâsúG—[×Þ¨	Sñ?±¡¥ïÐ…ø×—Ž9Ø×jõcJõƒ?¥f».ê	Ü ŒýŸF›óKmnÇÿ×þewáæɧ)™ð€¥qq}¿Žº‡ã·8ðR”
+ŽöÅïs›9ýÙä6Û…€0	ŸœŠí‹Q¿
+þü6.@¿ïW‹ú_P›,¯Ρ&<ÂÇñ-þ«¯-ÿºhw>§ð< ¨¥ÔÿõÔÔò»E}1O~õ/Åù¬t
+Åïè‘øÁM[¶óÝÇÿ6öˆýJm.‹²Óq¿…âw[);Qšß¢là7ÀyqO‡?ÞÝêä3qq½KþH©~º€ûmú  ›R³ß÷ú}£l8.¾ûŸ+})¦OàÔ„ÂÞr3!9µqc¥öçó×RùàRÿ+DÙî±?6ö‹ýÃb¿Wéƒß²Ô×w€“ãæîH9Çx¹uݍš€pSìÿ0ö'ÇïaPì¿_:f]|âÿðßÒ÷wñ¨/„b¿ÐšMÅ'åFÂÇÀ¢QVü¡ÞûÅ۝¥q,Q:÷ÚQ¶[ì/µû"þ§Y\×Ê¥ºŸGùIñûþÿ#î1§?›Üfûo¡‘Âþ¥6Åsñ}Ú½TW<|~¯TÖ#^‹ïóˆø]-ûï½£p¡w_|>+þ㗏úB@øuìûçÆþ¿cÿìØ_¦t
+_¤ùd½'ð9jðKÛqŠk¸ÚüYÌ»•Ú^ô‰›ŠsÄBë0šÖaIj½†Ïïô ž>EK>…?µ7
+\X(¼!W­sL[QÂÿ¨ÀÕüE]1èryÙ?¡U1	¿ Ïâ€
+‘´po´;	øI©ú¥Ò9ÆëÊñúB嵨_¡4þ¢3;ßÌÂmD ë…÷l’´ÅSñúz¼Ž4÷4.¢`搴4!s"þ»|²ÔÇ•>ÇÄëøxí]§M™wñ§‡ò1‹VÚÜQz_ö
+[9n‘RÝ(\ð šPª;wžú°þç}žÕñ²Næ†âß÷b;»Tw!@âÿÝ—HZ’Úwõ΢qïÑ]Qöfì/ ô§€gpÀWKÇ,^é£è¿ècéxí¯#âÜð䂁¥÷ÿÄKÄþ  ©·¤ÃqÝföAT¿R97¸ÓbQ÷*>¯–Ûõã,"Íl’™õÅç¶Ë¿ôÀÿhö—´zi at M¸â÷Qô>9¯&é+Q^u¯HÚFR½~˜ˆÿQýFÒf¸´nS1j7ÿI› GÆþk¾1Ø ®nä)©?þ‡º&®Vz!®÷ I‹Å¾,š.i;àÛ±aåuICpµ.øÓÔ«’6–tp¼nDÍIj_¢$ijHq£	r7üOó3û6î˜Ôˆo†ÃcáŒô¢™½ÓJûE€í%- leOVÚL)½«yöŒsíûOƒ;%âOV÷㧘ÙëQ¿5sɹ­Œ1™û13û ´•¿Å'¸7ñ	÷Ø8`5ázÛ¢±¤^•¾‹ï¯UÊ¿Ž;ë?bfýqÿ†Ô§Q#ãõጻÍ…‹Ñ¥ã>Ï¡Å¶u´(îûð-ÜOi3{·Ôä¡x].…ûPx0æ·âácÝxÝ ¨s,Ytff¯àÀÚ…JâpüæþW%¾†*©-.§¹}}4ÍMâÚˆ¢ÍYQ^uRÜ––NV÷aÀŠÔì˜Åö
+¶A%ÌWÕLÃ7«£–Ù¨ÒWy[+Úž¨Ô]FsÕÓß*õ£KǵNß¿šÓj»ÜºöFÍÄpBì*úb`ñŠýUpaâcÜité;7 Ú&†Whî¼Ô721¼› ŠcÞÖŒ6…‰á°Êø¿CMûW„O¶Šú¨©;{Q³ý~§ÔÇú¥1Þ1§?“ÜæØo¡01LõÃÅöߨß:êFM¸À4Â_÷º/Ž¿Ÿ³þuÍÂñ(´â;·þ i¸íOøT|¯×‹c
+C1æñëc=jNÁããwTü„3bðGà/¸Öâw
+îIáWaø¼<>¶²¹¿˜›'Q›ƒ‡S3ìRº/Äû€OGýi¸cåx¸dÊnO 3;AÒ¿p§„žÀ1f6Šf¶s¨ËઑÕðÐÀ§¢þ]`P„.GMåø5üá¥hw“¤Uq„%ãC~Àb¤fö¢¤õñ?­¸Ä½fV¨(SÁÛÑþ"IÃð§ŸBíRf$M££—B[ñi"Q’™=Rºv~ 鯸ö. ’Ü
+¸T¶:®²šˆÛ„Æ“$­s>)š€§ñ'é"YÉ[Ô4V˜Ù(Iã¶ØpGÝBW˜
+¾Žû­€ÿÉ^åOFŸ/TÚ¿ÇìƒÿfÏ5³aQ÷ü÷roù 3;_Ò“ÀÎøïþ%à3aïãÎO6³$}ZJR3›ffKŠÿþÎiã~%s//á*ô*ÃB°/îû3#iO\›½¯¤;ÌìIãqgÙñ§÷BõBôý\ìO+ë#3&éûøwÿ3øÄü=üÁ·øŸ¿7'¿³qÑÇ“ föDh²ýŸG1€OÞàæíáø賂è{¸¦Á=y¹Á=y­ô~Üx\»øàçV3\šï+áÑÇ›Y¡)¸מ¬??Œ;yþ¹ðÎL’d.AÒ{¸ ºŠ™U…€zí7Ç”Qf63¾E3M˜"7ߤÆëX;š$Ý
+I‡á“ý|À~¸Vc<0ÐÜŸ¯[ѳí&I’$Æ>¸‰ó9`¿’nÎqÔ|÷À5{wGá jñI’$³0Côµù㓤;!_Ï`=\Õÿ2ð”™}ÜúQ]—’$I’$iA£0Ž$I’$IæaR at H’$I’¤) $I’$IÒ‚’$I’$iA
+I’$I’´ „$I’$IZB’$I’$-貂¤ë%1§Ç‘$I’$ó"]9ÕòøBI’$I’Ìfº¬!I’Ù‡¤…%}FÒÂsz,I27#i=IÏéq´‡’$_êýþxM’¤óXØmN¢=¤€$I’$³¤9=¶H!I’$I’¤€$I’$³b	å.¯AèÊQ³
+I€ c€Wc¼f¹v’$IÒñty!5ΚÀuïÿ ž¶kë@I};whI’$É\D·yèL
+‚Ó<ofÌÈA’–ÆIšŒn1³ë:aŒI’$I÷§Û˜RƒàÀÍ
+
+‘´¢¤ÏI\*n>VÅ5Á?HºJR~©‘H’$Iº) 8MÀç%= é
+I–´WQ)é4`$p,ðoIçFÕ `¬™½mfO™ÙÀ§¨™*ÚDR/I¿’ô:ð"0VÒm’6é¸ËK’$IºÝFƒ&g pp1.,4Ÿ HÚø.°’™²åKǍ)wdfïI:ü5Úï
+ìÌ\œbfÓâ?_ ¶4³g$õv N¶è”«M’$I’6HÁi.7³GG+u_þU föJé¸z¦‰w€… $
+NŽ Fú‡HZ
+ø	°®™=}O.•tc¹Ã0Y|\,’$I’îG·Ñ ¤‰ÁiÍa`R+Ǎ©S¾"0.Þÿ8ÇÌÎ6³Û€C©™>¼`fOU;0³w $
+–ô ð&0FÒEIËIúŠ¤Þ’Ö‘´`k™$I’tº¼€0ÏkB¥¿$p”¤oâþà!3{w<ܲÁáMÀã•þúâá‘Ž¢u€ß”š<,$i~<'÷è6†x)pðE`uàJIÏ™ÙåÀ¦ÀIÀëÀ`eI?6³«c,?Žë[¸ <fIŸÁïOa†é	ô0³gµï$I’¹œnæ˜øØ 8SØw67	,+é>I{Hú¡¤Q7 è-iYIËÄÄy9ð>pN´yŸœ6&šÙÜѯÑÀ$­	¬gfï˜ÙCÀ-À×£I°°½™mŒk,
+vÃ}+vÖ†KZ¹Ôÿ§%]*éNI'JZ¤ÎTΫýÝô*5Ûø@ÒIHºFÒé’5º¶$I’yœÔ Ì*’v¾¼\Ù^ƘÙdzÒØô§¢	(ÕO”ôi`gà3ÀÛÀ䨊OÖûÅþàZ`?3{7Ê®ö‘tÐ÷9¸4ên N”´¢™½Xçô+àQãJec5â}àßf61öŸÆŠ‚&àl3;@ÒÒ¸ÖáIë ·â¾?Œñlm·Ns½%é3ûi´Ÿ|ZÒ+xäÅ `ð¥8ç€Ø>¨sMI’$ó2ÝFƒÐå\%'>Y~Ø5Þ/L“4––ÂC!@¼lfoÍê Ìl2ž]±Zþív~8þÿLŒùŠ(ÃÌFFå-’~‚‹ ßÄ5€’ú™Ù{ÑßWÿÄû&à‰Ò¹Æó2+…-\Pª¬ïÂ#*þafS$=L–´:ðFœã÷ÀY¸@°¤ùpÍÁdà[¸fd·Ç+!ÈŒÃÍÄ8–z—<“$Iæaº“b—¯…_8ä­ Œ×bûL¼ zJz‡ÂCl³¬…hcüïß–Ôø¤…`fJz8Øxø/0ÞÌž—ô0p¡¤pmÅJÀyqxPÎÚØ×0 ,…‡U–(—ž÷ãÂÄýá71ÿâ.Šk&'•Æ{€¤ÇµÌì{E§±–E?IÛÄùƘٛQÝxRÒæ!-œmfÃÛu“$Iæ>R@è,B…?,¶Hê?A× ÊZˆO$£± ÑQZˆZ©»¸°Aõ6À¯puÿxàföRÔUÃ,›¨	MÀ¸Â‘°Nýà
+3;<a~¿^õ6©,÷Q.ëü(Þ7IºßÌv4³q’Žþ"i7àfàªz¤€«p3Æ·€fö»p$Ý `®\S’$Iw"Msš˜ÜŠˆ„û굑´Í…‡öj!^ªìwš"žÄjPýõ8Á‹¸¸ð3¢Ò¾¬a8ø‘¤[Íìa3ûHÒëfö¤ñ¸ÏE=ê	€3ÍìïEAÙ±èØÏ1qƒ™ýºAßËãQû঑·$­ûu¼;|.%i[3{>γ*°wÔŸ,ˆéÿ$IW&5]™ù{&¶„¢?-ˆMqÛû@\%_ÖBT…‡ÓBÔÿ³•ýkKïon¯r5Ëix2§k%MÆMwâù?#%ý8˜†'izŸ¤«Oð-FU–ÉN–Çó@4¢)Ú}7L3HŠ‡gûÇǘv‘´
+ð.½¯K{ wK:øŸ™ý3Ž |ÚÌ®(ŸTRö& Š,š_6³>)I’$í 5s1i¼ÛŒj!6‹×&šk!ê
+t²/D\Ï¿Kï
+Ÿhè†©áŒ‰™½!›Gâãá“/ã÷á/’–Šºûð|‹IjÂ}'¦aº¸_Ëb,ŠùÛCln,	ýñÓç$…k.Þ֏öG ÿ5³=£ýhÜ™´VÖÀMÅuþ{àá­‹Jz8ÐÌnº>À`\YÆ>…G­´* DôÍ^föRÙbq#:û³N’¤Ë“„¹YÐBl†G+¬@MÑ("£Ó´q
+¯Õ){h±üµ™]#én`[<Œ±î(ù3àD`Iùò×Âד¸ w€Ü× <,é‚’E™&\€*XÏSqA¼ï,NÍ1ssàç¥öÏàÒyaFi*½‡’‰EÒFx„ƶÀ½ñúIÍì
+àz\Sò"p´¤ópÌQÀÂ’ž5³+«BãÉÀö¥²}€¿áQJbf÷Ö¹I’Ìݤ!qfA1–Zˆ·iE€`6h!`º_Ä¿KECJ×Ò×(|Bm2¿"Æ5ZÒïñ'ÿÂ~åIóe\¸˜VÖ~”è
+Ì_Ú_˜ëY€;]–ý%Êû{áÑ1‹ ëᦊ-%=…k/Lñ}ˆ†ýqgΥ댉¸¾[ÌlX»p:°£™Ý(é—ÀExJîv¦Ÿài»G”Ê kšÙÍ
+N’¤+‘aŽIûi‡b>|r+3ª…(òBLnq‚Ž½–iîpQ¥þÄVx¬Ôv²¤C€ËŸ`(>9?hfCñO_’T$žÚ¯rîpÿ‰‚ñR€AøŸ>û㉬÷g•t
+žŒªX£/pŸ™CcvÆÃVöF™Y± ×™Ào%­…çùظ¤4Ø¿vǯ#JåogKZ9ÍIÒ­H!™u¦?#Zˆrhg{µ…oÄØ95Ñ+eGÅ!x¦Æ	ÔÌ¿ÂÕþCqé5škžv”ô7\Ý¿
+µØãÌìàzc‘´>Ñ,éó!\5·5ºy*ë•€»KÅ›à)²Š™ÙÔ8ךÀA’–À3\žjfçEŸ+á‚àÏðŒ—Ó3{7’\mƒ›E’$éÚ¤‰!™½Ì ¢*@´G1ݹ²³µU̬n*ìH$µ*nìIóu/ÄóGü
+¸ŒHÏu'wH:÷EøXÕÌî’´¤™MŠc.“ôðYÜ\²,Íýª¬Šg•,kPÓ\€ÿA|Œ›OÀý(†Iº,Æ{G!¿΍ñüMÒb¥DT ÿ¾A
+IҝH
+BÒ5˜-D5±T{´ÕȌ٦…0_Aò¾³å·Íì`‹b?¢"^º§$}×܈›"®ÇWÎ<M¾(ÕxFÊÅðI\ƒ±h+Cz7U”鉧Á.Ø_(mdŒe¢¤cãÜŘŠ1¯Š'öÚ‚G€/‘Á;¸à’$I×'5I÷#žzŸŽ­¡…¨‘±9no¤…hÚÙIZˆiÀs*«ëADï½ë4Ý׬;MžZÒœœQ?0_¼Ì›4wœOXµxiÿ+À£¥pÎ>À1þë*9$~‡j~ɧn¶¦¹€0w¶L’¤û„dî!´¯ÄV7D/ž¼ëå…Ø×Nô§¥¢^nˆ13šRÙÌ~<ãWU·ŸOð¤QwÖ©»XÒ%ÀʸC•gñE¯Ê+tž\)é|"ÿî˜X]ÿÆ‹¯gIºÁÌÞ—/œµ+n6z
+¾¦â¾ešð¶’$éúdC2obfo3óZˆ=âý"Ô´KÍv_ˆ‚xÂÕ¨NÒE¸Så)Qv£¤½ïâû™Y‘ËáïxFËíÍìCIâNˆ¿Âs.\bf߁é!¤á‘¯¡Èñ9<u’$]Ÿ41$I=fQ±E¼–µ
+fBÑAœìR.0³K€Kê´ý09|)À×Ýø¥¤ñü;•úø%_áskà’æÇ}~ØÁא$Iç’„$™QfR1š QÖBŒ¡± ñRœ«£Çÿ<žÆº=m'Tö_öÝ5ö;j~ãyêj4’$ér¤!I:‹™ÔBÑ…ÑÌU5 ðˆŒ.µ¼´™]Ó£2ö¶›³#J’d&H
+B’Ì	fBQ Ú£…(²Sv¸¢|„GDü]Ò›À_€›+QI’t-ºÍï3„dždµÕÜíÑB”}#:Eaf‰’vÁ£¶^•t2png-î•$I‡„$é®Ì€¢ž QÈ¨j!š9WΊÂÌÆJÚOæ4 ÷Q8AÒ¿ð-²P&I2ÇÈ0Ç$™Û©h!êZˆzÙ)ÛÒBÔËNÙPaf÷H:ø5Æ=€oKzø#py)Z"I’¤UR at H’N$4OÅÖ‚ÐB4ÑR€ø,5óÆÂÀÇ¥ì”uC;Íì/’6vÄÓ=÷ŽÓl ü8]ÒiÀ-‘$Éì'5I’´MhŠI¾.’¡¥ 1"Šì”…â|á©iøzàD}c;8\ҍÀŸÌ¬áÊ”I’t
+餘$IÇ#Û«…ØÏŸÐèé¤XHj;à+’ÞþIóÕ&“$é|Rƒ$IçbfŸHz
+Oδ35ÍAÃCðå¦çÑú¾bg’$Oš’$™=DZæëñ¤z—ª¦á+=öú “ñÕ.Á#3†ÃÌlœ¤ÏáË['I’ ) $I·FÒ—ð¥ŸÂ} ^Ç—˜~Vlföúd’$eRƒ$Iç"iWà[À„6 >3;&I2‘B’tSÌìRàÒ9=Ž$Ifˆn£AhË™)I’$I’Ž£Û„9¦€$I’$³ŸÔ $I’$I241$I2g4_d_L’$™iR at H’¹ IËJ:HÒ<×Á‘szLI’Ô¥Ûh2Š!Iº8’,ffoH üXx8ÖÌÆà¿åã€{€/™Ù¨95Þ$IæRƒ$]IóK¯¿‘´ðpš¤…€»ÀéÀRÀÍ’0³W€«S8H’.Mj’$i?’Nž~
+܇§=>ø2ð-3{TÒÙqÌøêÛ—ãÙ_›ÃO’¤ýd˜c’$Í‘ÔSÒÉ’^•ô±¤+%õ‹êÅ€“qóÀ.±‚ã³ÀP3{´ÔflÑŸ™½‹¯Á°q
+Vš-“$ɬÒå5) $Éìãx`°°¾€ÒIQ7kfÃJí‡Ó\#ð0XÒü¥²E¨ýÑÇ—zN’¤ëÒmL) $ÉL iuI“tž¤Ý%MgÂÖØø#î+°.>¡SRxÿ^¥}U#p¾ ÓÁ’zKú4ðiàÆRûUf庒$I
+R at H’:Hêùv”t¸¤-KuKÿß ®v–Ɲ[cAàïÀðE–^öˆ~†ƒBX(h¦0³€ïâš…k€ã̬X¦ù3Û|&/9I’ÙC·Ñ ¤“b2Ï#i0wÜØxŸÈ—Ä—M¾LÒ3»ø:ðš™ÇÅÕÿkàNƒx¸ÉÌ~S:·ð?ŠãuEà…¨¬\îÀÌî‘´îð¶™}Xª›6ãWŸ$IRŸ’þøþT¾ð:>I0³m $} 
+|èŒ+6³	’îÁ„›[9ÏñÀE’^ÁCâ9
+ö7³§%],Tjÿu´fö	0iæ.µ%’æúwTI’´Jj’dv#©°9>¹¬üO&ôQ+‡Ç5ó›ÙÔèk8Í'ák€#J폔ԧh;®ÑÚøÌìjI»àBÁw€‘ÀN²Ø,    IDAT¯Ììé¨ÿv¥½Ñ!Q‘Ga0~_V/½_
+w˜L’dö‘B’t4¡–ß
+ؘü+&Ꞹ#ßýÀùÀÕx^¾ÀÏ[ér8n2˜Z)\Úè'iYàNÜ¡ðW’NvÀýÊíëbf7Rs*ìpâÞ &”…¦hö	nҁPæNí¬q%I2n“!„¤;r°=p!°'ð}I[™ÙI/O›ÙY ’Þ.—ôëŠ Pf8°˜¤žföq©lÇ¢™},éy`
+3»#Ö<8ø1nV8øIÇ_j}"ÔqÍ5«GY‘[á\K1¸=^GÏUï…¤ÏÍ–'I’&†$i/’âiƒ‡›Y5Ô¯Úv
+Ü‹3›(éhÜ1pà<|b_´7³ÿFdÀ`àÉz}šÙ«’¦«â“(ÑÏê’ª~€[pmfö$bXŒëXàåÒ¾€ð(„b»ÂÌnhó†4¿ÞeiiX=úîÿÙ¼ã¾8;ޏ0³±õúL’$i) $³
+IâÎpÏšÙ³±.ð1þ]\NÒ—ÍìñVºY˜hfÌì=I Ÿ§& ”'î¾À@[þ#ñI¼F'½ñÌìg•ë9xØØøb”ÿ÷…x)Æ3×6<Ýà¾ôŠëª'Ë6OÁ3+Ž.ˆqŽÀïe«BU’$]ŠÔ $ó&’æ/ûrÙ@àZ þ”;_Žx*°«™Œv‡ãžþ_iå¯}b¢÷£l5µúpà IÛáªÿCð‰ú™6†¾0¦Ø	§Æ߶qÌ+xXâ?½"=2À«÷ @Òâ±øRÕ7`ej¿ÅñøÄÿp15A॒&#I’¤ÓI!AÒnxšß»#	Ч™®½ÇoƒOÒ» ;Iš ifWE“³ñU,G˜Ù3E2"`ü	~yI½Z‰:Šg"Ü8=4Ssü¼ýý_»`§¶&W3{¢½×[:æâjY„®$©ê°:žSÿóøÄ5߀%!#I’¹“Ô $ÝŠÏàOówã¶í3å«$õhŒgc<tïOxFÁo ÇKº·“‘Æ¡†ÿÝ€OîoâawÃê´ÅÌ>‘ô=<ŸÀ®ø¤û6ð×h2XøNIÃP½ŽEiîð‘™µåP¯…¨oX•ZÈàëÔœ¯¡¦
+]r†L’dÞ$„¤[0øZ¼ ˆ¤=«?3³»$Ãc÷ë%Žç89&ðËñEˆ6Ç—.ž†Oâ͐´°ðY33IëGÕš4 ÌìªÈ~ø<¹Ñ=…†ÀÌÞ
+
+Æ  ™/ƒ¤íq¿‚7©ùÜLcß á‚RÕ$°:µÄBŸ £qAà&jBÀ3ë°dFI’Ì5tSa
+ÝI_ÂãûŸ/ÒþÎÀ±Ÿú™ÙíøDyXTõÅ'Ý«Ë#ÿ?x¬ü˜9Á÷‹Ð¹˜ìÖŽÔÀwã†}Jç+‡â!éUàpàÚH8烫çëq1îïPå&3»¾Z(i~IëÑRŒ;8‚8ՐÁxÈà‡Õ>“$I&†¤s‘Ô_+àsøZmµ?8ÑÌ
+g½MqoÿB at XYR_3»XÒÞ@’p€™ßJ÷Ï}%õ/…Ö
+§6Ñܱûâ&‰gÍì¨ðØ×\ì…Ûæ§4¸†^¸ùaDkë˜Ùÿ5¨ZºoÀ
+øÕpÇø¹å,j¾2˜$É<E
+Ý—¸ß€€/ ·IÚO¼6þd~˜™ý;Ú7ëSóæF<ћٛ’&âjù'ñ	²Í§ø3ûHÒ(Ü4PöŠú‡â	ýÛ¸)â
+ન»Ï|ØI½¨ù	¬ŠOàÏßÇÍ-ˆãŠÁjZájÈà<4²2X×o!I’¤ƒH
+BÒyHZ¸_Ñï¸ý6\ ø>>‰n\'év3›@ó'zpap),q>?m·¯œsaà¥È„*Õ•oÆ'a ÌìE|}„ö2-ú{¸7£Lwì“´õ}Væ‹fãp
+À£À¿¨	/gÈ`’$s˜’ö!{_ÇUðï¿­OofïJZN4³û¢üàȸ=ž8hJ¼?ŸÀ¿Xêf"îm¿rôSà÷ÇIÚÿŽ<Š«áÿ#iI3{½Îðw.5„’	3u#˜žÚø`%|âÿª¤²0P„~H-dðrš;	¶pŒL’$™Ãt›‡“æ ’Öƽàï)TÚ’õ þ‚/žÓ:Þÿ f6-V\(OÇïÇÍëÅ!÷ G‡ŸÁ¸-Ÿ8¾>}“ôsàøwäHüI|=à­ãi!È´—ÐNÔó
+XÏd2XLþWQs|aVΝ$I2‡H
+¼JØÂì†GÜ	‹G|Xè-is3{8 ÷êÿüLxÃñ0Á‚=ÌìÔC‘|3{RÒ£Ày’îöÅÍ kà·Çù‰ögã	ŽÊÔ]Ë =”Ö&¨ú¬,ÍŠÁÀ
+Ô‚‘2˜$É\Bjº+’¾,bf§µ³}_`#à=3{,Ê–Àй.ÀŸ¼w.6Š|'ã^üëÍàÓðp\ )è¬#ià›¸câR¥ú}qÆ@`wÜc
+€™“ñ,!iÜÙ±ê0ˆæ!ƒEöÀ[©	ÏgÈ`’$s9é¤Ø™øÐL@ˆÄ<ƒð”ďFÙܾÿ °¶¤ûÝÌìõXfxš™íZêãMà®’p2p—¤žÀd\«0#T5GáK ?‰G>UTšÙ«¸	b–‘´-Mƒi2ø2>ñß…gg,|ÆuÄ’$I’Î#„–<
+Zì„}üRÜþ~=~ÏöŽt½[˜Ùc‘—`$°+ÍÙ)3œæꥉøSu?Ü1ðJIÇ„Ç?’µ2Ö?K›Ùx\¸)óR»¯¼B%d°*,ÍÞ§2x.5߀L’$iIjº’¾Š¯ÐÑ_YRŸÈxþ®xÅo…{é÷‘ô]ÜÖÿ!°. §e6¿áøªgÄþ*¸ð®™]'é4`˜¤‡ðP½q…º˜Ù;Àgöº$-I}߀•h28x_½°0dÈ`’$ÉŒ“BWGÒ2¸&à`\88Ÿãªú/m2ׄOøÃñÁ§/FÝpÜ7¡Ìpà›’®Á'Úƒ€£“ƒ™ýŸ¤3ð‰y×艣Ûk³UW¦þCKD³ñˆ†‘¸Ö¤ì$˜!ƒI’$³N·y šç`k`\xí#éwÀ÷pïþ'i°ÐžŠWÀ•fvCQ(i%Ü8¾¸Q™á¸ q2°!0ÄÌî,7“Ât³BxÿïB-£àjø
+‰£€ŸPY!«š€Á4œDóÁò*ƒ2˜$IÒù¤¡ÐŸ00³%=H-iНøBCÿ,ÚHêefoHúpV¬^X„/Îlƒ¯p^å\Ãñ	þ®ª`ЈXøhe<EòeøþG¸3àÚ’v¦¹0°lú	ð>ñ_OÍ7`DƒDGI’$Iç“„nÄãÀÆ’–
+'?ðIö£xð€¤qaa °(°‡™$é^Üï ðÜÔPd<¹r®—ñ‰{ ®eh•ŒkÖÂÃ$‹Áù£Ùdj“ÿÍÔ|2d0I’¤ë’„®DD,‰‰ 0³'Â)ðTI'âõ£–`èÕXhè»ÀâÀCø“|qü}D&ömÀÔ4*ÆÕŸú¾ËS|	ŸøïĝmÀx’$I’îBF1t%$
+À7«ìœ‚/ès7®X¥¨•üI³8†>¸À*Àö±®@!ùÞ§¦
+8‡æ«Ö]9I’$éV¤‰¡+†§ þ Ø žÚ=÷ìV)~¥Ú®ç\Šúë
+¬H-dp,>ñ?D-dpðJ†&I’̤aN é³ÀÀ¶Ô>„™ÙsÔO<d°ž °x4›Jm•Á"qÒHÜ,ðNGŒ#I’$évt›‡À¹F@ˆpÀð•7Æ“)^/3³óg¢ÏE¨ï°*µ$Hñ‰p%5mÀ‹2˜$I’4 5MØö÷Â5+ãQà×ö1®Îß¿•ã{P[e°*!ƒS¼Žš0ÂÌÞèØ+J’$IæbRƒÐÙÄÓýÀ!ÔÔúP³óƒKh;›Ù;’úÑ|•Áb[æ!ƒÅäÿ_jƒÏ›ÙG$I’$Iǐ„Ž&B~„glt
+< ü."àÈ4j«ÞŽ§G.|2d0I’$éL2̱£‘´‘ð-üWBjq.ÜœMM3ð\†&I’$sˆ41t’¾¬‹?ý÷˜Ã÷'›Ù»0¼$I’$™º¼aF&ÛÙÍüø’ÊWàÂÔL3®ÀS’6ìÀ±%I’$É̐„`
+ð?àÿð(ƒðdC+âÙWÅ—[î[:¦p$,›zƱC%œ’Ɉ’$I’9L—× te˜žåp0´^}d.\±²Ä  ®)é/žôEI{›Ù¤–½%I’$I§’NŠ³3›ˆ'+z¨^}â8IÇšÙ˳eI’$IÒÍèöB[´%@$I’$Él¤Ûhº²“b’$I’Ìmt¸’$I’dö“„$I’$I¦“„$I’$I’„$I’$I¦“NŠI’$I’t_R at H’$I’ÙGj’$I’$龤€$I’$³Ô $I’$IÒ‚æf$Í/©Ë¸I’$I2³¤€0sœ| i´¤»%ý[Ò1szPI’$I—§ÛhæúÅš:‰À1ÀÅñ¾	è×ÖA’ö¾	¼</aý ™}ÔyCM’$I’'„™£	ef£€QIêafÓJEëS€›µ€?}%íefOt怓$I’.A·Ñ ¤‰aæ ¬!é³’V–Ô·¨´€¤³%½¼-éIk—Ž{ØÌ.6³_™Ù&ÀÕÀU’zµçÄ’úJ:Xҝ’—t©¤:ú“$I’y›Ô Ì ’Ö6ǵ	M’ö6³+“€uÍ€§€
+Oâð&àúJ—Ç?¶®s|øð
+p©™½å=[pÉó×ÀàSÀ¯%-mfguÆ5'I’$F·Ñ ¤€0ãˆ×=Í샢PÎ|ÀÀ¾födT=R9vL¹33›*i"°xôs°;p08TÒ¦f6ø).d¬kfïF#%]	ìÈ‹L’$I:…n# ¤‰aÆ ¼^ Ì̀ŀEû«ÅÓÿ2T„`1<*b)àP`3;Ú̶ÁµûE»í—„ƒâܘÙÈ8ÏF’®’t¿¤?JZ´4†%%Í?s—$I’ÌK¤€0ã4á¾kKZ¬R÷6ð>îŒXe9ü~7$­,Ü|xÅÌî-5yX-Þ¯›-ê"iEà6àQà@`uà¿¥&ÿ N”ô°¤±’Ž”Ô'Ží#iOI=$
+’´t£óÌ™/"I’¤©A˜‹yx¸-é}IÏIdfN‘4$žØ?Ç5þ ’â“öef6ÿÂ,P9ßRÀ;ñþ=ZÿÌö†™Ù1f67Ul"iýÒ6v6ÂC.·Žº€³q?ˆs€'$ý¬Ü¹¤
+$!éI«´qŸ
+~$éœv¶M’$Iº]ÞAÒÅÀkø“÷ØÒëX3{{vÇÌ®®+¯>ñ¾õ‡Kzø	î€x#0MÒ8`0?°4p)PLÄ‹JÚÐ̍§ø¯;GýÃÀVÀ¿o]JNfövø7,EM¸Äèû=¥cš€¾À1f6TÒÀÀ©Ñv/àDàßÀ4àIC
+m‡¤%qdI\ëq5nnÙ hfI’$™‡é6„®. ¸Ÿ¼úãªûþ±5IšFEh ¥ 1Î̦vÖ Íì=àÙJÙéÀ镲~a–XøxÓ̦”ÚŒ—tp¯¤ÛÏÿ¡<BâIwÿ23Á—¢Í{Ôœ(“Ã’ÀËá±4žœiz\P¿ÇCCó 0X<ü"ÞÀ…½Íìšè{p8ðµÐ&<ˆBwâBÍʸÀ³5ÐCÒ¶ÀÍföãò}‰q-”$I’y…f3³KUJZ„šðÐ?Þ¯Š?eeËJšLÛ‚Äk•¤F‚™½	¼ÙJý_%]‚‡/nfO•ê•ôeà¯À%½,\€k5®N
+“ÂÀ‘À“f6\ÒòÀÔ²‰¿_O”Þ/Õ-€?>ÖNt ðjÔ¯mî3³¯I¢$=œmf—4ðGÜ%é,Üäq·™};|3¶ÇµW™Ù³uŽM’$énXÛMº]]@h3›L†5j#©nÇ/ˆâu£JÙ¢ñTܪ afouÖõ˜ÙDà¦uCÃü°®!y+ê.“´nÖXwhÜ-m¢eE¹¬	Ÿøúï™ÙäxÊŸ
+lýöǝ.‹ïÏVÀ•qÂÖôsD¤G•¦¸Ž	¸¹£‡¤]p!èb<óä½’v3³Û$í	üx8Tî
+ÌrÀd3{¿ÞýK’$™Ã¤‰¡«Õ„ØkÔNRo|Ò«
+k”Ë"×AUx¨'H|P=GGbf¯á¾Õòã"—Â|•5Æ ¿¨4ÿ£¿Æ² Õ„_¸ ñ6°“™OKAC¸Ù¤õ“jý(àÔ0™ø3ð33»@Ò+1öÛ%mƒ›;Çý>þ€F_ Æ㎖WgƱë;›Ù/§VZ7Å<ÂX«HÚ ØÏÌ~ÔF»ÞÀÚföh[}&I’tuæz¡½DÂK±5DÒB47iôÇ“mZ*[NÒ{Ôq¬¬”M0³Oªçè€k™†«æËe¯PŠ²MK»ÑÜ™p2pQ´{?žÚ/‘ô=\ÐZ8ÅÌî$ü$]÷±Lo\¸hDp[I»°:îTy”¤ýq­F¯8xÖÉóÌìl I‹ãš†BûÑŸæÉš¸¹†hÿw`'ÜgbsIÇ›Ù	Q·:°
+®‘\&¡5Á­\CÁÏñ„WÓIÛáþw•’g%I2ï’„¹3{[]â)xIZ
+ë_)•-.imföFg]OAåýÇ(i\Ìì6IðôÒK〢ú0<b¤¤ëf6$êFGHº¸§Ž Q5môÄ87Ã(sÆQ¿¾ÈUÁ(\RhªÂôý0]|XÉÌÞ	sÄ’.ÅïõuxØé#ÀÆÀ®’þô–tð¨™Y½¡•ØX§Tö<å?ÀÉ’~lfgVM’$銤€Ð	ÄÓðÄخҶý¬Q$ÊN–M©0–Æ–… Ñ©v÷0›ÜV§|Œ¤
+ñÆ•€KÕ[{ßÇÃ4ë	•öŸÅMß4³¿Q3s|HM› >‘
+óÄ|¸ðR>¦,0ÁD-iL”¿Šû>îq–™M¢J*éŸñötÜ£Gg„ÆI›ßÂ…¥‰’® .tŽ™}Ü éHú	®Õéœkf¿)Õýø‹™o«Ÿ$Iºñ_©AHZ#&Šªÿ*’ e´F|r,ÊúKšJë‘EØg›ÔL\Ë4üÉû‘Jù$ÜgàÔ‡žK);d¬M±p¹¤ïàÂCp¦™ÝÜ |'žæûáΑ…ä'¡‘Yx-49Û§D÷K wàY+ûãn݉ߓÑñÄÿ|D‘mf… Ñ„k?^¨wá»måwÄ#;
+ÍÆP</Ä:’Fà~¿3³£€Ìlœ|uÎ#ñü¯Ä½ofgD_ŸàB×ÜÓ$Iº>) $³Nhž‹­!a¯
+k_*•-%é
+Ú$&5ˆ:èPÌìª:e÷Ä„¹Æ9žš9ãHà<<$sR”÷)þ(®!8øž¦ºÐ Ö2³kŒåI§âI®ž‘´V	m9ZnŒÿ–ÊÂÑFøÊ›Ehk3›"éE\ ØAÒÆxäÉn¸éæP<ÿÅ¥ ’NÁ+„«ðl—) $IÒi¤€0¾
+oÐúz
+óáN€ÕhÍ*eFÖÇV‰ðÉèŒkùº¯–¿ì"I¡ªûž²`W<Âá àBÜìQhh~üOÒÿ€³pGÎ¥ÍìI[†/Æa’¾ŠkÆ⎇-"FJ,ŠçÑ(;œ.ŽóÇùŠûõàiIã>û‡ŸG/\¸8¦tì›47«<¬'i©öDa$IÒ%I
+BÒµˆI¬˜ðnÔNR_Zš4šð¤Iå°Ï¢¿¶²YV}fõ:
+íF9Ùæé·ËN„—•ê&ÄÓúÎxÔÉ'Ô„m€‹Ã)qéw¡xØRÒ£
+ÂW'SËHY¦ì¯°5žÓáùËTI¿Ç•̬pÂ\׈”ý2&ÓCVC0šŠ§ïN!IºÝ"YR
+I]b"|!¶†È—“®
+ƒð4ÑEÙ2’Þ¢mAbâLd³|˜RXa[„ÆãÜØÊ忐t,°
+¾¢æäRõQ¸?À³‘°©ºœ÷xÜï¡Ì4üžjzL_¨ë(\`X¸Ô®w¼ÎOÍ,±>Í?ÁW-L’$Ý#5ÉÜNdq|‹¶³Y.MKAb“JÙ"’ÆÓvªé“·™ýµ¯e
+¾ÐTµü1|¥ÌFǽ(i´¤õÍìñ(þ3p_D ,/å½)@dÁ¼8½_ÒEáï0	ÿóX˜Z4ÆWpâø¸ƒæ¨™¿Ú®I8Ÿ~ˆG—Q&e‰d.$„$‰§æñ±5|ڏL„ýi)H¬U.£­$Tã:;›e…ñÈ…ÇÌìiùRß;ãþþ!HôÀó8üËÌþ élÜ'a0ƒÜ-éûøú«;”εðPR9·þ1[ã¹0 _ijt¶* HÚ,^´æë$IW$MI2#„ŸÂ‹´T§7#²YV£5VÄ“8eËIz—¶‰ªsáÌr>°EåzžŽ¯”MÃC˃;^.+{âËjOÀw¯$²ú:µÄQsËóá3:ÉÿwVí1æ÷¿5³g:vˆIÒa¤!I:šð#[]JÙ,«‚Äúø*‘EÙâ’&Òv6ËVŸÖcB»z&¯ç=<t³ØØTR/k¾žád¹°WµŸp,ý¸3ò\Ì&àZ€º~(’Ƶ›á†kñäTÓðÏv'3»3L8ßÂùÚÓÌ®oï Â|³&î(ú ™M˜•J’¤!Iæ•l–7ja…ËÒ2Zãs4Ö(²Y¶&HŒíÈl–Uá 8øaƒ¨©À!ðœ]$aêF4ÅëÈHVÜÛ¯„¹èR\KðwÜ7aw|õÏ>xXi‘0ë5<µuOà’n(çôÔ·j~
+òÀ¾x"­€ó$݈G™”×)I’Ž 5IÒ•‰I¸=Ù,ûÑÒ7b 5GËb‘®h[?Où_h”À*ÂÁíõG†/Àk»‰Va 0Ô̶TmuÕ&3û@Òºx¯AfV8gÞ
+ iÅد&³ºÏ}± ðŽ¤oáþ}"QÕÌìÞh{ž¨j]3{9úí…'£ZŒæ™%ɬ’„$™[3@{²Y.AKAbmàË¥²%%½N‚D¤©®Ž£Õ?óE¨¾„ç†Ø÷øDÒYÀßÌlt{¯y0}á.k¹ºêx4C½ÈÀ[u´7…oÉ’VÂâÜŒ¯
+zƒ¤þñÙZ1†€Ÿû!´lŠÿ¹ßß@Ó$í!Ód^#|^§íl–…Y£,HlAóhðÔËm	ÍžnÍìyIß ®Ä# Àó8üDÒ£øSñ5]P«0€æ+{–y_6»ÕAÖÁÃF_~ ÜkfE¸èŸ%|NÒóxvÑ;
+L¾òçÿp'ʉÀ IÛšÙÓQÿ7à8<
+ã}àÒÙ‘ª<éÖ¤€$Is"j¢XM²!’Šå®«‚Ć4$>¢~„Æðõ(槖€i3|âœ&éLº–VaàÀX¬«¸?#Ì—×¾	w88ÅÌ>”Ô;4
+¨ÜË'= ONe‘˜ªÙBb¸ðՏÚZ­-«~ž#c§Ø?7W|)ÌO k âÚŽŸâQ5ÄõlŠ/}¾5îÌz~5)X‘>¼{Tn¿ð¤™
+oï1I—¡[) $I%7¢„H‘Ͳ­1XæëTZ…ƒð	ypk
+{¦1³KN£MøÄ?Ô½#ikàL|ÌïãËoŸí–’¯þùî3°'¾ôøÑý<: IƒUqMÏÛQ¼ÐHXÚøN1GB§ïG]á\y˜™=õï”ÖÊX
+w~ü-ðW|iðñLšHú,p°R˜žŽ5³³Kcí‹Gßô-™Rþ×Z¤€Ð=I
+B’$K)›åô˜I? ö¡í?!Ã1­ûKtÆÛKkN£föð©xbïYʨy5®ößè…‡@þ¸¸d~¹ ¸GÒ¡ø:¿ n)ž¾%ÝŠO¸Ó}¢¼G<é/„›Ž
+>¤öØŒ,„ƒ`.LŒúÌìøès	"LUÒR¸¦çÐó:¸oÄ“fö ¤M¢ÞðÏw
+I_Ä µ"4ó¿
+ü3’®Ij’$™½Äø™À.¸Ê<¯À»¸°Ðwü{O&ôTlkâ6ø%mAÍ¿aêl½€vN…åý[iCbfÃ$}ך숛Ž.5ù1p½¤eñå´
+7ÇŒNÁS׆Fû=ðû. ¼X9åRÔLMÀ奺wñ
+ð¤WSqo}ü¾ßlc¼¸ÀÌŽ ´‚ùwà—øbcSÓ
+MGÒ—ãÜÃð%Éoû°®aɼ’9Cj’$™=ÄÓèµøºÓð§Ø§ñ‰ìË„T
+    IDATq<üqT½±$ê÷&àçÔ²Q¾CãŵŠ×	3±ÈÖlÇ̆⡌õêFFjìðµ/zàBÔ?£ÉQÀùR¹<
+±uÔ5s’”´ Í×Ò¨:QöÇÓŽƒ/l6ÿÌv¤f&zRÒj¸™äÏ¥q¾çX bZø2”Ø
+Oõ<pžìûÀ	qmƒ$=€§øþ(ú]_nüq3kä0šÌ:Ő$Éì!÷µ?ž™É¤MÃÌl³è³Q6Ê
+€¯–ö“ô­c»úÚa²8'¶jÝ•á«1×*ldfÏFu?š¯zÚ¼g¾ôx±_6™ô§&<Œ4³Ã«ç”´>‘ÔK;Ý× ´&˜õÇW&ýbô·"¾HØföHø6Üì
+\$iK\À,-éb`3ÇŸbfoÄ~àý0qÍ~:Õ|¡²ÖÚ͐g7 [\K
+I2'wpŸ3š²œ‰²?ð…ò~´kO6Ê)y…™=ç—¨–ÿºR4wJ,„¬;i®Ah¢uqpˆ¤3pSƸÂí¸Ãä4\ Js–£&d4¢	σQ°‚ùðc¼Œ›6.þ†;Hž~wÄù‹4×ûÐÜGã7¸`tB´ùð]Ü1ö¿ÀÉVZç$Â{ûTןÇ8~ÛƵœ/éV3» ÔßòÑßómÛUI
+B’$s73˜²*D¬ |¦T¶\D(´µÈÖë˜E¶:œx¾$ÞîRæ0Ü„™MÓÆ/€‹ñpÔgÌì6àuIG7K:_{Dfv1®yX¨'ë&àÙÒþ¸£ãõøý^\žŒÉv5bM3{/2q®ÇöÞ®äÜXŽZ6ËÝpçPÜã` ðãÐTÜ‚G‰ô–ôðµ8ßfÀ’ÖF—´.Ó‘ôy\ˆÙ'ö{â‚Ï.Àk’^ÆÓqO®Û…I
+B’$IA8>KóI«’–¤åÚëâŽ{EÙò5'Zõ(Ôá]‰ªJÞÌÆãf¡zmOtf¹9ž>\XŒ’t“™ý°ÎáU߇gp'ÍÛªI²"•µÑ<ćÔ4e­GAÿRÙÀ©À%fö‘¤ƒûpçÏýðUS?çZwÔ|I€;\ÞŠ;_V9
+7má¾x.Á1Þ+qäguŽm¤½ñïÒà43{!Êû˘ÙK­Þ‘¤!I’dFˆÓ“p§ÊºÄSdÙ¬Q[•ÊšT[d«­l”¶ÈVGcf÷àN†å²)ÀΡú_²zLLvÓ|Rÿþ>LÒ©x†Éµñ\
+¯âÖêÀ3‘hê›xx(xôË;¥þ{á”cä)¨×ú=£n
+Ð7îÿóÀ/$í\dfE–ÑÃìpT‘‘²Îu¬…k™n)ï\Q$ø’t)¾–ÆÏ$­¬nfÿiÐß!Ñö„ÿgï<Ãí(«6|?	½HBH€Ð{"M¥(Ò»
+"¨ ¢¢¢"ˆ4é MéUŠ ½HM¡$@HBB’õýXk²çì³÷i95Y÷uí뜙ygæM8ï3«[áÖ‹
+CHÎ’´ºU5óê Ò‚$IÒÄðÛÔ/ÍÌŠö¯éü&[B˜ä™åc[ºjŸIÚO­Üw¼©¬ŸJ:¸7Ä×ñX‚âû}¬J'Ìñ·ÿÑxÚå<~án¨Tkß%iw<ädI?4³kBäõ§éŠ¢_ÁKdYóãbäÇ¥1ïSIó|¸[ÒûföŸpO\Ï3·Tlf7Ås>ƒg\Õ9ÅÝ×71§ö"-I’$]EXZÒd«ã#Š&[ÅvÑd«^\Ä`´y?ŽnIÄ+ÜŸj~ˆ÷›X_ÌO¥…ö›Q=rx¸vÞ¡“ érà‡’^1³‘f6UR‘ʉ™=
+|%ì%]‹[€>m&»eUJÀˆ8þ÷œ†×’(b'~œ)×û˜ÙëòŠ•Eðe!˜Æë—®uÞF¼£B¦9&I’ôÂÄü>-o²U_ a¶FÑd«nÊ'.$>®¾GWâá¦øß.?HÒ¸µà]\<‰÷¦xZÒ`qàIgàe±‡â©Ã✩T:nÖc
+‹@kV¹ÎÄÖxjf1Ïë%ýͬpO¬×w(3¾_5‡÷ðÜ	)’$IZ„5l²õT½qª4Ùª¶HlTú}Yy“­&EîÖèô¶Ò‘žYBÀ̆•6¯+íŸ
+.éHܵ1¹@’NÁëf쌨õ&H!é6àQ3;µÆT&ýJÛoãŽ}Jû¾Š§is_·‚|„§˜,L¤m–DI\à¢eñóhoÒ‚$I2·a-o²µ$ã#ÖÄ+4Û}#-°©”Ï1À{íYH(Ìï+㮄֜7J•Èbß]x7ÎZã×—´%Y‹{ñ`Ébü4IWW†Ù/k}.€¤åñ?ÅëGü84No°øKZÏù}é~µDDGAŠI’$ImÂ÷>/‡]“pkô§qËï-ª¶	zsÕ,'Wߣ‰ùuJ©e3{wCÔ:ö¬¤ù$
+6³7b÷€ñÔÊ1ÀQO¢/pp¦™]"é_À0I›˜ÙSÀ}À©’>gÞøëÛ¸˜ùOé–[1
+@Z’$I’¶nÂjP—Hk¬ñCe·Fq½¦\cÍlZG<Où5¬ø¸Õ| lofE`å’¶ž2³—%<,i8°°WUJã¶x,EG“.†$I’¤ã‰En
+{B4BÒ4«ác±¯¿¤h¾šå»Ñ!*G¶d\ÓQÞw+Þ_¢Ø>NÒ_ð/™Ù,Š¤ÍðÔÍ›ÚcÞs)’$I梊ã4Ìk@IêGã ËM«ö-©ŒÍU³lT§¡+‰K#Ëû"(óLàëœçiAH’$Iz‘a0.>ÏÔE‹–¥±kc]¦}Í·ÛIs=úI!I’$i5± 7z¯FÒâ4«àõŠíe$M¢ùj–ïXÓ-®Ûú,ã[{^¤Tnü£•u-Ò‚$I’ÌÝDa¢Ix¡¤š„‰¿ã#6¦a*è’ÆÓ|5ËNéìhfC%„w•¼8ÛÌêö)ŸÚÁSkR $I’$]J;ŽÏÿꍋÆPh±Vy_ÄQ4)"p·F{4e:·"ì#é
+àt¼³eSMÀÒ‚$I’$íA¤8¾ŸºD¤j1/ŒTì[FÒG4_Ír|Sn
+3›M°^¢"VÎΑt5nU¨®u‘.†$I’$él¢ Ô0*}n¾4ŽØ/
+]l/)隯f¹ð$^±èq0Þûuܪp}TÚì¤@H’$Iæ:­ñN|ž«7NÒ¼¸[£:>â‹4Œ˜ïÿ° Ð+NŸ7>ëâ
+«Î“teOB’$I’ôT¢ Ó[ñ©‹¤hºMôÂñóðøyš¤éÀuݬrå,z5?$I’$I’zHú>ðO¼
+uy]	LŽÏ4¼×mÀà_ÀýÝU@Z’$I’¤M„ûáBà \ |ˆ»&áÕ*ų2^ ^ÞDªæfÖd®&B’$I’´Iý€¿Ë — OáBàÅ”—Î:I’$I2‡2ع
+«2Í1I’$IæDÌ죮žCG“AŠI’$IÒ¹ôB
+„$I’$I‘!I’$™#‘4¯¤ë$-ÕÕs©"-I’$IÒÑHšOÒ¡’.—ô+Iì"Gÿ.êÚÖ$B’$I’t0ç¿ÄS
+wîŽ^ ç¢-sw¡G¤9¦@H’$Iº’ô-IûKZ¼…ç,Œ·ZÞÁÌζ6¾	Þm	GtдÛBº’$I’¤’V’ôçÒv_¼û⁁!’–¯sî IWJZXè7]ÂÌ>nv-r+°¡¤:äaæPR $I’$]Á7€JÛǯ Ûk  §HÚQÒÛ’Ö‹±¿ &F-‚¢ÁŒÒµn¶(6Ìì}¼Êáfíÿm"-I’$Éœ‹¤$
+jãé» ”¶7ž6³iQð
+`7I™Ù]ÀO{%}Ø85΋‹ƒ²u`
+°DÕý¦Ò½Ö¼I’$ÉËπݚ ©Þ:³10ª´=ƒ†V€»ñH[˜Ù•À÷ë€kÍllìŸ<ìY:·7ðYÕýfÐ}‚»Ë<š$B’$IÒV† k‚ÇHZ²|PÒ]¸¥ ½ð…¼à`V`b´A~è_óFìû¦¤­Jû¯ ö’Ô'ÉŽÀcU÷ <ײÇj?$-"és’ö“ôkI×Ç\Öìì¹´–ìŐ$I’´IšÙÔÒ®!Àáñûp«ÀWcì¼ÀÖx+äZ0_iûàIG— õæ-ù
+p0ø§¤=ÌìA<Ka'àmàe`9à¥ydfÃZõÀ-$R*á“kT}Æ°™ÀH`8îîh®ãc—“!I’$©‹¤c€'3õ$ö5³§¡ÀZ1ô·ÀK’v3³›€õ±f6¾Î¥ŸÂÄ˱}'pðyàñ¨~¸ð|Ìc+|ÁÝÅ̦IÚø­¤o…»a'I›Æ9…¢`CàÂvø. V£±XX8†MÆEÀ0àÁø9xÕÌ>ëŒÄc'º5)’$Iæ$Í,ffïµpüRf6!~?ØX ¸ÄÌ®Ža{áßüãë%­†/„KIêcfïK:8_ÒÝxÆ@µ™¿Ìõx&Ãù fö–¤? wJº·D<
+ü/ƯZ,üfö ŸP`fOÖº‘™Ý†g6´Iý©m
+Xwn­†[>þ¿3³Ñ-½Ow'B’$ÉœÃ÷ðô¾½ê
+!08X_ÒÊÀOpýÏ€%³%M5³áV™Ùqþð`Á­Íì>I#p+ÂÍì.IOÅuVÆøz\üRÒjfö
+€™çoüF´8v~[¾&¾‡ycŽµ„@‘1xÿ¾®ˆŸÃáQo¡­ôˆ4ÇI’$scM$‹ÁýÄÌ&Vù:ž"øs3ÛQÒ‚¸…`k3{NÒüx,Á‘@!'›ÙTI/á‹ë}xÂZÀcÈ1T‚O¯7Q3{GÒ€‹$mS· ·´ù¨"'7 at Y¬Le
+‡/üÏ×Rq¼•;‚I’$IûûÎxý€S€½ñ¿+¨*3ØÈÌ.‰íŁE“%­„Ó½
+Ü_ÿ«²;“â÷Y™ f6FÒ©x@áM=ƒ™ý#b¾ˆ‹6™ƒ©m
+èÃ>^ÃþQÃÌlKHsL$IÒM‘4 ÷Ó÷î0³§b*êÙÀBÀÂföMI“€»Ììµ:—J”%>ÀÆMÀf6£jü`A௒΍ù,Š‚ÇlTuÎXà‘×j„™}¿¹1¥ÒÊÕB`U<v<
+²Xüo£08Â̦·ô^@Z’$I’úDŠÜf¸9{tiÿ瀻p“÷àvI‡šÙÍx¬Á‡Àk,ÂÃð7ú¦Šņ™}"éJà(à^`´¤ñ¸„cðÚŸà…£qAñ%3û0οïuPÌ{í×昁¨ÎXËPTmœó܃‹¤á¸5àݶ޷IB’$IâHê]^Ì%탿ùÁ¯!éF3;&†ü8%:"iðkàf<…ðÙ:oèCqpkcàiß*—ÁÑxËä’>Ãë\L7³™’†#Íì›-xÔ“€€45(bê¥.Ãê¥¾V¤ö`Ò‚$IÒ“	ÿö¸|ѺÔÌÎnæ¼ÞÀ/ñ΂%=ìņŠãû™ÙµñÖ<DÒ©föð9à9IgkãÅ>3û‡x¾-îN“´€™}R>hfS"`Bìûø®¤Ã¥BECñÅû®&¿,¿V¹ä1’úQ;Hp0•”ÁQøÂÿ(
+SÇ4w¿Jf1$I’ôdB\Ž/h¿Â£óû_)Y¯"ø<pï43{ÎÌfH:"ƈ¿	ßü_t{ã=0³·%=çÿ_†‘¥«âše÷Ã-À
+’N1³7cßêf6sÿ®¤7bÿÕ"X­–õ¡	ýExÊ_½ïiê§å—§âÝ‹”ÁÂ20Ü̦ԻöJº’$Iz8_Ã#ìW¦@ào»O—ÆÜ„	ž
+|	x@ÒFf6/™YQ
+ð<¼Uñ_ðűúMò%*ÿŒ{·XÌ%m¼bf·H:uæÁmgfŸÛ4õP-	¬_Ü	ê§%‘Çų•S‡oÖ°LÌͤ!I’¤+ˆHÿoãØò¸_{þ~u¡›Hñë¼Pê7°'pkITßc
+\,©r·KÚ88ï—NyXKR/3û8ʯ…Wã#Æ-~?Ïx#ââ®…½Ììè	ƒÑ¸¸˜mÂj²µ­Eã¤iÀë4NÞ)ƒ=‘!”R $I2§2ðG¼ªß¥øâº"î÷ÿ²¤¯›Ùg’Å­ «àouóIÚÉ̞ś	5¿$0¥jQ¼<_ðËå€Gáøƒñ@À" °,Ž0³€m$mŒÇ¼jfåöÈDó¡65 
+×H­”ÁÕ¨¤N b¸ŠÑZ+DÒˆ´ $I’ÌÑ_`|!-Ž6³;띕ú& /šYQåïIáÞ®x´ýOñ?Öë˜ÙdIÂãÖÁÅÁŠ¯>‹7ÂÏ_,ÔKPùã?·&s2IEâ<­°ÜTè±xÖòs”Ý­&:ÖrŠyÎÀ»)ƒçP	lQO‡¤Õ¤!I’¤XxOï{¸_x_)„àhüͽ7p\ˆ‚¢ÊßíÅØ· »áaKàß%7ÂÀQár¸o+¼„™}Pž”¤~Q5ð!¼§Àÿá…]q¾Ð._•âx$.0³3Ê׌ ÁVó‰”ÁU©2¸hûÆ)ƒÃqËÄ4’Î&-I’$³ÉàSàfÖ¨;`øÌÿ:xÊ[y¹q™—©øú?ÁËðŒÁßðúᣞ®’t™½½ñÂB› ã	ßÅáë?˜Ù›!.f™ãÍìñV>ùYûR?e°7M§vûöÂs™æ˜$I2»Dºà+¸%à±°¬ÌV‚íuñRÃÕ¦Û!À>5.;•?ЇH:-Έÿm÷þ^ð
+IãðÞÏá©‹Dšá¦ùIuÊ^k}õ‘2¸µ…@Ÿ6· Ç-*ElÀ+saÊ`O$]I’$íÄÜŒ2nÆŽ›ÿÿ,‹WÖ«õG·œE49ÚÏí/bô=àIw?þ^FµÁ=ãí}a`b­H}3{¿z_SHZœÚ"`*)ƒc©¤^GÃ.ƒ=b‘Iê’„$I’v`(nFßx»jq–Ô§Æ"=X,õ>‹ý.¼ \ HÚ8_ n¬ž@ÔøoUÿè³°µ…À21l»}>lÍý’Cw)’$é	¬NóÂîßHú%^wàÀCQp2þ>)8¸¦,2Ìl<^)±MHZˆú)ƒÆ°"ep
+SGfÊà\IZ’$Iځ!¸•`è>Ø÷ÓÏcfC%í„×:xR|x8Îý"0*DÀl!iYj[–£’28· ÜKÔÁ	µ®™Ì•db’$I;ñ*0ˆ×&÷,øMô Ø<Òý¦We
+´ªŽ@d)¬Jc!°:•IR± ü§ôûk™2˜Ì)¤@H’¤Ã4_{,˜f6MÒqxÿ!xIßFí~[ÓXÒÒÔ¶¬H%eð-¦±™2˜ÌiAH’dîDÒ€ÃðÆDoµÇ5ÍìÏm˜Gከ%–ŠaEÊà0§Öí`˜$³A)&I2÷û»âMŠ6ö0³v-¸÷bÔOœ/†Á- /Ð0epT¦&]@Z’$©¤-G{úâ>ûpa°Rì¾ÐÌnhçûïÊXKˆaÓðx…ax¦r—ÁLLº=âÿùIÒÁÄÂ6øÀÌ&–ýð9à쮘×ì…~~ŒWøþ‡ï5¼/B[¯»žX-VŠaïÑ0e°è1)ƒIO!-I27#im¼øÍ’À¢’Ž7³BüøŸ¤ûÍì¥.›d+‰T¿c€ïóã}Ÿ»·Äw/i µ­Ëã<§Sé2XNž)ƒI'ƒ“$áb¼Öÿ÷ð|üÛ$=dfÏEãŸ?§;uá[„¤5ãpw‚Q)\æ3{±tÎ|x@-!P¤N¢R=°œ2øz¦&Iב!Ij éѨØÞ_— ®N6³Ïꜻ^°g¬wX˜½ï•ô0n–?<†ß ü¡N™àn¤-€ŸáݧSûïÆt¼%ó§’N£"V¢’2ø&¾ð?\B¥€Ð¸Ž~†$éf¤!Iz"’>œ|9¶7Çsà&¿>N
+—€óÌlzŒ½k^è……‚kñÅ 3%éàëÀåüh-&â&vÆ?»Dm«øß’-
+h˜2XÄdÊ`’ô0R $IcvÁkö|¸ÑÌ®€Y)uçHú#^Vw'`[I{¿N5³©’¦ão
+eýKxÉ`•²FKw赜y$}1ËáÕ¡¾0(˜|
+ÜÞÙI2Ò#,½ºzIÒHú©¤o·ñôpsyÁ <}®àf``Ëx+ޏ㖃Âñ"a‰zã*íëQ÷Å|þ	üÐò¿óÄ5®—ô×h©œ$ImR $I2°Y½ƒ’¶—´uÃ}p“zÁTÞ¤1³IÀsÀú±ý)Þ†xE`,
+-s÷ {•¶Æ™ÙÇ¥}½ñ@½®¤WáE„nžÁÓ	Ë9Û3q±4“Æð¾<+i­Ž™j’$Aº’9•¡ÀŽ ’ö–4³óJÇ
+ü®‰óËnáÀ!UÇ
+X´´½Þ#`$p‡¤¯…88TÒ¹À­À¸o¾ÌÆÀ±-y¨Ù!ÕkBT<˵fö`ó–Çk9”?«ÅÏ¥¨ˆƒñûx
+ç‘fva‡<P’ô\z„!BÒc‰@ºÞÀ¸[àuà3›Ž/ÖkÆÐ'€g$Ýmf¯Eê݆x4}-&ân…‚û€?KZ=º÷ó˜88OÓ»¸[ÒWÍl¼¤m€_၏(=ÊÀûfövÛ¿‰†HêKÃÅ¿ø}0á3|Žœøc­ë……äÕøÔº_SâdIÛÿ–—$Iz)’¤õðÃ'JûîÆã¦þë€#¯ ß³E%õ7³×%W,Ü	£Ìì½:·»ï)p%€™½$éßÀ)’~lŽ‹ûbü··Ì쁘ëwð”ÀE€Éfö<°[{M§±u¢%ßÇ<TšU>1¬X؇ᩙE­áf6¹êzÛ¶v-óá1I’8iAH’I[›ÙŸš7/°pþV¾(p'î÷îô‘´™½‰gì,cfŸHºxCÒ¦fö¤¤WãZãñ·ö$튿ÝÖ³ \/i!3›û¾‹¿iÄ[af¯Ä±›ñ4H ";á¶|-˜Ù(`TßÇâÔ«PÉ,x_ü_n¤"FšY­XN%ŠeÁ£$éa¤@H:‹…ñ:’Ô˜T²  éR*.ƒ³ñ.|ç·˜Ù/b̹À¸•`(0ÚÌ>0³1’n¶žÄÝk˜Ù4IGà•
+Ÿîª7Q3&éj\ ûÞ¶‰7w+×û7³ñ³ñ½®’¨-–‰aÓqÊp<–¡¨68¬ª¿C’$ÝŸ´ $s7Ñtç³H÷ÛX5ÞêÇà‘î¯Uò:p
+ЧXô$}¸LÒ·ðÅ~U`I½qÐGÒ¼¥ª†½©¤ì
+¥‡€™Ý/é`?à—ÍLÿXàiI×›ÙS¥kLoÕ—P"¾êàÀ¢	Q‘ø•Åÿn–®Y¹1I’G
+„dîDÒŽÀoñ·_‹ µ¿ãnƒ]ÌlhS‡ãk¼<Š/ø7ãUùfH÷ظ",ëà™àâ°ªký¯[Ðds$3›îˆæ
+5"šÕ²,‡ÿQ˜I¥ìðýx݁á¸5`¶¬I’$íE
+„¤MHú)Þ®xY¼@Ð>aâ_ˆû!p©™™¤^f63ô5ñ…¾Ci¼ ߏ»N*Ý{I¼
+|ÕÿVÄ#ÝCï©q¯-Û[â›7³šAw1‡ù¨¤V"eðc*¥†/¢b
+xµp‹$I2W’„¤girñ¬ãðb9W˜Ù¿ãøáÀ7ðt¹3ðæ;_öž1³KŠë•ã&ÿ¼,.i™RŸŸ –\
++áõ
+¶6³7%
+ÃË¿|jf³ÜÑühV¤h"´/°g+¾‹¥©-V¤’2ø6.žÄ‹Ø€vK]L’$élR ÌHZXOk{ÐÌ&´àœyp»#ž&ø„™i{Ûá± cñüý5K%­éóÖÃcÿB¸ù¼/[Õ›SŽÀc
+Æžç¢"߁x ãƒÀñ¥œú¡ÀêfvssÏŒ[6~[â£^ÊàR1ì*)ƒÿ b
+nfµàÞI’$iAH:I«âµó{ãi{Kâ>öUJcæÁÀ§fVö»¿Š›ï—Ëû\*éP3»_øVÇÛ?„¿ÁCš¤Û    IDAT„g\ç÷ÿ4†/Ò»á&õç€ßW¥\œ(é'qÓkÏ9•f6ï X‹!¸›£%¼¬!©Z¬‚gL€·i.§.‚7ºCÊ`’$s)’ŽAÒ¢ÀCÀifvfißÒïÛà­‡ßÖ”ô °[Dÿ¬ef›ÇØwñ”¾»pSÿÌ8¯à!¼$ðÕxšàL3; jN½áâáo’® ¦â4³	ø·.^­°\ã 3»´5߃™5‘2¸<µ­bX‘28Œ†)ƒÃ3e0I’N Ñß¾îH
+„.DÒ2¸/{üÌ[¼¶/0±, Ììݸv/üýd3;/Rì^ŽÆû£aGÁ[s%ÍE‡Fâ¹ùoÄñ¡T|÷gÿ‘ôîw_›ÙÍ‘µpîžx¸¶4¿GñŒ„Ù"žg5j§Ï5‘Š :e°ÍéŠI’$³Iº’ÚHZl›Š/XàézkK:ÆÌþ^»1žæ7_XOÓýZ¸9¿Ëう7ì´½sñ¿ÓñVb3+i
+nn/Ükáî(šÙÓ’¾ˆˆKð€˜Ù[¸ûa¶‘4€Úր婤¾s~ /¬T	¾ÓsH’$™IÐNDÚÕðEôÅ&rý1³$M/×IÚ¸QÒP3{LÒ†x½ÿÓñÅï|‘ÜoG¼Pã«Ï¢°D”KÜŽúÅïCqkB™¡øâ[Cp÷BñOà™³M¤®Bm!°Xûˆ†)ƒÅï™2˜$IO#-s:’Ãú¬‰û½‰/¬¦”ý¶Ä«å=n€¢ð,`f·Jº8 :ü^fø×qW'$‡wá;¨¨1P=73'ix\£hk¼"•ºÿC•$Í_*y|?•:çQú÷af'´úK*!i)*Y¬„Z•.ƒå”Áá™2˜$IÒ¹¤@˜=&ÛG ×D
+`$퀿y¿€›Â—Œíê7ô‚»ð®„ÄØYc4 ‰ށ/ª‡ã•øŠûõ~bf¿NăûSpÄ.q­±’NÆ£÷?}?/Ý«^ªb“D âŠÔ¶,Ã>Áã!†Ó8eðã¶Ü7I’¤‘„9¨8X Ž8Xïø=3»ºêðjûé'Qiû°IÕñ% ™ÙÇ’ön’´Ÿ°n}ó»^Ò8<=±7°Y9ÕÑÌ~Óšç­z¶Å¨ÝW`U*)ƒãñ…žŽY73e0I’¹œsC€í"¦`-¼`ÑgföM`3Ü­pmó†â9ùŠöÀë<pÞvø+fv·¤ýù‰ÀA3»7J|	?3³{‹‹™ÙÃÀÃmy°H\ŽÚn¢ö@‘2Y¤±ÃÌ샶Ü7I’d'Óç†âÑüÓâ÷‹ñ"; 3€ëœ72œ•J(éËøb €™=-Š¯•ôîÒØ­¼ðšÙàdzó ’¤vÊàê4L¬î28œLL’$iiA˜L2³k{_`÷Ãî Z4³ñ’ÞŽŠÅ /p€™ÝZŒ5³%]Ž7 šPemhQw¡–5`*)ƒ#ñ…¿:eðݶÞ7I’$i at Z憃$-R]“?jü8CÒ–ø»;ð|¾Oã{8ØÌ^¨uƒÈ2ø´Ö±j"c¢^Êàâ1lrÌe8nñ(wlÑ}’$I’6“AŠs	¯á~øÂP,ÆÍì3;GÒ³À×p+ÀOÌì¿ fö½¶ÞTRê§˜Þ¦’2xkÀèZ×L’$I:s:f6#2NÅÝ
+Cñzÿ+yx¤µ×Ž”ÁÁÔEÏ…©4î28œLL’$鮤‹¡»%Ž—hï¢;f¶þ윍—ê¥ÎÃÆáuÊà[™2˜$IÒãHBw at Rà(àÀŽ]4áýjYÆ°Ïp—Å0à6*"`X¶ÈI’$IÏ$-]¤UðÀCð”ÃÏutÝ~IP?epáö>•ÅÿžÒï#2e0I’d® -]¤M€Ÿß òáЦ(µáý©Ÿ2Ø$oаËàp2e0I’dn'-¤ñ†B[áæzáõÍfvQ®7/°2µ…À1¬HFÔÁ×2e0I’$©A¦9v’æö~†—:.Lôóââ`<µ{”¯±$µEÀÊTRGáÿS4LÓ¾O”$I’̤@è(¢Òwãx@høLö0³¢Ëá`j~1~*Þe°H,,ÃÍlJG>O’$I2א.†Ž ZýõÂ…@瑱<+é¯xà`9e°Üe°oÎN)ã$I’$i!iAh/$­„g$|ÍÍ]x‰4Lž)ƒI’$IÒ#^D»½@´ð+àóø—Ú«…§^_à}à7é"H’$IºÝÞ‚ÐÒŶ+XØo-¼•/³¥Ê«ðœ¤uÛwzI’$IÒ&2‹a6™
+<Œg'Æ­ƒã³*Þ”h*±3ñ†Þ4ŒG˜ÏFxZÒ1fv~ÇO=I’$Iê’.†vÀÌl0¢ÖÁÈL(‡âS- zó‘ô%à»f6±c§ž$I’$uIBGMŠFÅçáêãMˆ3$lfouÒT“$I’¤ -]Ms"I’$IºˆnoAèÎAŠI’$I2'Ò#,)’$I’¤óIB’$I’$
+èiŽ)’$I’$iD
+„$I’$é\Ò‚$I’$I#2H1I’$I’š¤!I’$I’¤‹!I’$I’žI
+„$I’$é\Ò‚$I’$IÏ$B’$I’t.iAH’$I’¤™æ˜$I’$IMÒ‚$I’$IÒŐ$I’$IÏ$B’$I’t.=‚0OWO '"©/p+ð60ºôó¿föVWÎ-I’$IÚƒ´ ´å
+k7€þÀ.ÀZ͝(iIëJZ´Cg˜$I’tWÒ‚03cf×·æ$Iów/}%Mþœdfï´ÿ4“$I’nHiAh÷$-\ë ¤å%'é~I7JÚµtž€-Íl ðuà3à%I«¶äÆaø¥¤ïHZ¿ž%I’$I‘¡mVÞ–4QÒË’.´ð °8pð7àóqÞ@àC3›`f#Ìì1þäò
+äÌ_ãÞ_ÃÝWJzBÒ&íûxI’$I’„9˜ÀÅf¶dü¾pvÛXø¶™Ýnfw›Ù	qlÌXÍ­ø‚€¤_S€qa…X¡4vp‡™}ÏÌÖ† ÿ׎ϖ$I’$)ÚÈ <s3›bf¯šÙÿâØFÀ-f6­Æy©-fHÚ8Ø4Æ¿
+\Wuï1¥íáqOâü
+$m$i)I×±B$I’$]G° dbÛH„|¬YçX=ºÀËñûÞÀfö"€¤3¡’–1³qqïµ%} \PºÖÁÀfÀ2À8`%I_)Œ¤y½€•ñÀ
+fö^³Oœ$I’ÌU¤¡m,\&i¤¤ÿJºVÒaqìZ`SI{ƒ#{jX$-ìÜ»–ž)
+)¬Iê/üË?Áã®1³ß–Æ V3³Í€‹€?—æñ_à8`~`௵PÒ¾’v–´½¤HZ®t,ÿÝ$I’´´ ´’Vúâë83›ÞÅSÂÌV´ ¾àŸ‰qì’¾üNÒi at oà à|ñžWÒ¾Àô8ïP`pN\~< Yðu`2ð&.zGšÙXI[÷H:£”&YÄG.ŽÛãã÷ýqQ0È̦B“‹ýN¸%b8.X‘´.6–‘48¡œê)i0°ðxZ%’$Iš$B;°pþÖ¼´¤	ø[õ\44úÙ‹“™}¼Ÿêc×ׇuà33û8¬l‡ÿ㘜 ÜV>Α4Oüpž™Í4ãã>Hºø>pRœ?[šÎGÀÌ°>l»/¦–æ:³Î#ž0³ý`–P»Ø¸
+ظ]Ò³föº¤=KÇ€5$]lbf_ŠïáL<pÓâzËï›ÙGuîß,’Ö Þ5³	m½F’$IÐ#Ú=w{`f——T™ØÆÏe/”÷IZ_$ëŠ\H´yqjáÜ?¨Ú¾ªç\/i&ð]<pñ2àOqx >ïò¢þw\PœŒ‹Žeh±7ðT‹´púß•¶÷Fáÿ°7 ^ž¾,émà|à`3»NÒR¸ÕaXœ»°s!‚qAq
+€¤Õñl·šÙË4ÏŸ«Ë›$éàn3{¤×L’$éhÒÅÐÞ˜Ù|
+<Uoœ¤©ˆ‡²Ø¨¼_Òg4#"€±föY=RMÌìFàƇþ›þË܉»ÖÞÁ3"¾"iaà@à1öAàg’ú›Ùøf¦±l\·`UÜr±U?g ›Ä}ÿóŸ é9 x³HÃÌ‹âú£Âuq¿ñð ¤CÌ춈›8Xÿ÷ú p
+°#°6þßqm`¤™M©~I[੧§Äv/àç¸ ›œkfg6ó]$I’Ìuô(ÐR„^Óü_&Lße1÷ÿ±´¯”D®%ÊûÞ«zCnwÌìC*Ùžπây6Á-'ß¾ƒSîdfÆð+ãÙ^“t-nMø™=_¾f|/ÑpQ¬bfÇUÏKÒ.x¨²šF%Óc–(QÞw6ð33»(®÷*p"îÊ8:Æ„_~WßKá.›M€+RšW/<Ã㸒çÛÀ!¸[æSà’Þ
+QÖ$!dÖÆ]?×”E–¤Å#Ó$I’¤)Œ$0G
+„–.€¨ZtËÄ"ӏÆBâóUû“TíÖ¨1¹£ž‡ˆ?ŸüiÕc?@ÒŠ¸›à#`hë,
+¼Rµàÿø®¤?çâôÚfv?d9XÒ¢f69ªI~·x€gL|X\(\K£#;b%ศ1·F,ÃÀ«RÎ4³áÀoãàèÈ&¾ÓM~fvGißqÀ_Í춸ÎÅÀ¾À’–¦ÕŠa‰9Ÿ<̼ é,3;5†,†„®Wg.I’$eÒÅÐÓ	ÿ¸ø<So\$@c!±nyŸ$£™ K|‘¯Uh©9&·´à™F#›8þþf^Þ÷¶¤ÍðôÊ›põû(p¿™½$éfàIᥠË„—C%õ7ÑÑÀD3ûDRñop[\Uß]±¨Ÿ…/¾/Ç=~jf£cÌäf׎¸[˜µÈ¯Ü[3‘ X7KZÃÌ&IZøpTˆ†rµË+€;$ýÑÌ>3³Q’¦IZ¿Ú"“$IRE)ÎM˜Ù§xëç7šo×Õ±«àže$M¢ùøˆwÊn
+3{Ò‚ØÞ˜Ùê—uÞØ_dÀߦ³ø|‡DÜÇèÒ±·ð€ÇýÍ쏸{¶tÏqë©Ào€«p1Q¯*e™M€ûKÛ«ãîçJû&Å>ÌìII·¿–tÞyóø:Y1£€>xPè¨ØwnH$Is¤!iH,xR‰ðoDdô¥±Ø;/ö-õš£ãžJX<®Šù÷Â΢õGÀ×åÝ''⁍ı’öþ%ioÜ*±žÝðpð73{OÒcTÞâ§Äušb
+
+ÿ'œ˜ÿw_¸O6 ¡¨;ïoñ
+<>ãÊê‹ÆóÜnf£J‡ÞÃ…^’$IS¤!iax'>ÏÕe“‹l‚²X«¼/ÒC›²Vö``zu}‚*ÓûèÒþ§".bó˜÷»x=…yâù	Ñ48<N,Á–šÙù5æ1	S((ŠI-F%ÃbG*i¤à"â<èòªˆìËcžÕ%Sñx‰$I’¦È4Ǥc‰ ·âSISÅÏ€-¨ˆŠ’>¢™ KÜ­Q¯¸RÁ8ÜmÒÚgy¨Æ¡£êŒÿ8Š7}7õ×âJqf6DÒ+À©’Ž¾‡gru6ú ÷àµ%v—´GU¥ÈxüÅ«ÀvQ,«ÌÂô7ƒ$I’æH0•_‰O]"ˆ¯:Èràk¥}}$½KÓñ£#°C‰€Ç{›r-p‚¤^%Qó-Ü𞺻™MËÀíÀ=fv²¤ÿàý6î1²^›â|3ûMûm…×iH’$iŠ´ $=‹p	L ^¨7&²úÓXHlKÃlùi>ÈrL·ðvÃÌÞ—ô žîøxì{ØPÒ¼UiœýñrÐ×Ǹ$݁\þ/3=?°–¤?Æs<UTgÈÖDf’$I3¤@Hæ,¢àP9¡&¥j–e!1_¬‹}$}B3A–Àø¸5êÍ÷À:û?«Ún”úif‡—6·ÅÓ!ÅüWÂcŠòÍûϛٳ$mFÒ
+ÀŠx€ëèrߐ$™ƒè®ÈI‡ÐŠj–KÒXH¬|¥´oiIïÑ|ª‰ò0ÌJñQç›e}µ£î?±;ðKÜ’5PÒǸXø’™½Û¥3K’ö%-IÒ±¨O¤ùj–ýi,$¶¢a¶Æ‚x\ASA–c:à­tyà'föj;_wnd p“™ ©oì{¿©“¢çÆïñ€ÝáÀÀ£ݐ-IÚHZ’¤=÷ÂØø4WͲV“®ÏÑPHL£™ KÜ­Ñ\…b~Ãh¢®EÒ*á…³ «AËA4çê7³¢_Èj±ïÏxc±cK%V”ÕnIÕjø•$@)&Iguš,#
+³ªYVY®l_ÚׯN“®ê"TM¾Ùv6’¶n+5¨êI–“ôk*±./šÙa!º
+Ø¯“1XÒÙfvvœ÷Š™ý3®óI»7HZÝÌÞlÁ½•´jÜó.¼gǐö}¼$™E
+„$én”ªYÖjT4¨fY-$6§a¶Æ¢¸e£© Ë1øfú ¾ˆ^,é|‘k²NF7cÞ•ó#¼à×—ñÅúB¼/Ʋ@3û4þ-[:¯AଙÝ$éI¼ƒçI ’6ʼn}\±%å{(vþ'iãÈ|I’ö$]IÒS©ªfù¿zãJÕ,«…Äú43i¾Õ¸Ù}ë7³™’ö^Âk+é	ààŽ–ºMº‚Ò‚•™=]cÈÎÀ9EÅÏøoTˆ‚À“5Îy›(¤%iOà¯xkðþ¸ ørôàX oþFd´œ.iW\ ¼ç/L¨Î€I’6’„$™“iE5ËEh±*°Mi_ÿhÒÕ”ˆ]]ºƜ&IúðînØØøLÒ_€Ììí¦®ÑEôÃ{eÔ›Ûâx¿‹Z–‡júP§¿2³³ "Câgxߍ1fL[oîUr¼¸+„ÃÂx_–oýFú /›Ù;$ImÒ‚$‰Ñô-©f¹4…Ä&À®T‚,šjÒ5_d÷Æ?-„€?ŽÆWg w¶µÆD0(~î/i•„·Cˆ
+Å㮫qn£îž±Èoœ+i ^^üêҐJç<±'«â•5¯ªºÇÊÀ–x¿‘JnfWIZ¸X/ʵª¤ë4û ¼ÛCcD’ö#-I’´œh-ýÍW³\†ÆBbíª}¦ ½âôâçv¸ðøDÒy„½‹…ÏãÏ1ø9p%^áIËáe´WNÇÿŽõ¥$¢¾Æ¹¸PºX"ÏOœSt:„×ìØÏzùðH”)'bM~ofã€q’nû«^…WÐœ,efŸEƒ´~užóIàI{šÙòQæ|ÿ˜çCf–%»çlÒ‚$IûožoS߀¤£€?PÕ,Ÿ“Jû><8û³l=Ñ¿ãMFÒx?m·"æ¢/0xHÒ8üïÚ²xÀæÎf65*vŽÄÀ…!²Á…¸@x«(ˆ%ip›¤«ÌlrŸ‰»m
+Þ¤Ò”lgà¸">!b=ÆV?C©újx|Ã$IËOãÂ^þ.ér3++7 NÅ],—àA”ŸDÔŁyšs;%Ý’´ $IÒ¹Äâw>îbX°êð<‚¿7.F ÏӁé–„º˜Ù(¼gFyßh`ñèZºþŒ™Ù¤Ò“tpc+®wåüCHIp™Ù#’^öþÇ{ƒ©Ôiø*•ºMÅG”é÷¿,²K$…Û7 /J:o?~/žÅqpð‹˜ÓSø³mñ¬âük€C‹"Qá¶Zwk´¨^‡¤Ûý›«N*iC`H;¶ŠŸ[È:I’t.ѲúvÜ0³^Yx¯ððB¹6€¤mñÅfŠ¤ë¨˜ìke^ŒíŽB¸>nâø¿%-‹§ª~<™àB©úÜˁƒñŸH£<KÒÏqÍæx3/ðøˆÏãŒ2³r,Êñ$ŽG©Ä]n“ñ¢]'àƒÆ+bfYºVú { ûÅöþÀY¸ð[^Òà[föI¸a¾‰c¾üËÌ^
+wÇWi ÙIŸïf£Ò¾
+ð6ò¯÷u笙.&]I’t’ÖÁß4
+8»}ÃkM×Ìá壋x†x“­b»h²U·œuüþN7
+€f‰ˆ×ØVá— ¯…[` pð(¾(~ìRZè
+Ü"iuàV`93;³Æ5X*‚y€ïÿ¡Oò^Ar\ðóü@Ò
+„r=eñtÙ™‘–y°£™=,i>ÜírPìÿSÜûÜ2òcàÿ€ÿâÿ†î`Ñcª]a¥º øq!$íßÙMxÜÈc’ö(‰°¤!iAH’¤ÓxÓÌ6ŸÝ‹„TScÂ÷]]Öz<+ ÜdkÍ	3û`vçÜ„˜¸@Ò Ürr)pi±JÚ#ß–úE¸j	„㮌ÛÍì%<¸ï4*ÙHZ‰†©›hhµ([¾Œ»Žö”´%•¸•
+âø–À±fv;
+ùžº/ÞÁtrçØwãÜóZwý`f×E¦Æ‹¸•åÑ:ßEñLÛàÂv0×q.pQ)@t?\ô4géIôÑ”!Iæ"˜®³î5	˜DóÕ(ûÑPD¾@Ã"RQ©FYOHtD“­Ö0/¾xÕÅÌ^ÃÖ¦xŒÆ};ŽÃk8Œt3^ca¤™ý
+·\,ic<Eöüͳãð@Ó‚¨„¥ãœ[ñïzyÜ*ñ|ÿy\ûyà$3{<öÄSK‹ï¾_ÃÓ:¶ –Ä­˜ÙXIo[ã%¬
+¼TôÅ÷Fß°ÀLÀÅÈKxÐçßã™~׃[µæ$ iAH’dn%LËããÓT5ÊùhX²ø¹!
+…ÄtšéÔ‰¿i¶»ßÛ̾ÛN×iô=˜Ùx`IëáÁ„ãÝ(1³;#
+õNàS<ëbRñv¯ßŽ€ÊÕñ˜‰+âØËxêëõĕ™]/éà <xó‡fv-5jJ”	á÷e܍U°	ÓQŽ[˜ˆd‚™ºYÒøÂX”ÿEXM
+^Šb^GQ×Hê7ŸÊ Å$I’æ0³iøÛy“oèQ‹ ZD¬Žùûª›lÕkùÝíÒÍìjÔ¿0³ßJ:521¶¾R:ügü
+üG¸)ÿ|"½ÒÌî‘tðrdJŒÁ›’»&FÈ_cáÞ K⢮)– ¡u¡.Ê,@¸'¢œõmxÝŠ5ÇÌìu®½
+¥†kf6CÒPÜuS«HVÒA¤@H’¤G.”&[kÇÛm_ÇGlVÞ±1Žæ…DݬˆÎ¤è× )Uì¿<>µÎÛ[Ò×ð¬‹5ð삏qÿ’Fà—«ãYà_•Ô×¼Ýv£¹H*²cÊ,Vü1*›â.‘‚_oàî”ïך¯¤Ÿà›TšŠ—9…´ $I’t&±`M¶ž«7N•&[ÕñëÑЭa4Ÿ­1Î:¯ÓXàÆÖœAˆÕˆ·…{aU`rÄÜ€IºÒÌ~KcÆÓ0öáqà›’2ï\º#ðQX*¾ïp²xuvKdEœ™-#P¶Ì4¼ÖÄœB)&I’tG¬íM¶âtÛP±R,#o²ÕœxovSþÌìAÚ©Òe,ÒÃkì`üy§ÿ7ùwÄøG¢ÏÇ!À÷ÍlJXu.ÃX­<é×ìÚ
+×ÅñÍÊ®J¬Eì‘NZ’$Iz*Ö‚&[± .Eãøˆ«ö-.i<ͧ}vZ6Êlpžmð{€(g½=°'n™ÙÑÌþcÿYØ=Æý ¸4ª5.„dŽÆ,§Tß(Š[
+ÆçÒ‚$I2§V¢ÉÖóõÆ…½Ú­±,þv\ŽèMóÙc"¸³K0³!’ΗԻȉ²ÌÔûW௥íû%‰JNÃ31â…¢úKz8ÄÌîŒSvî5³™³HB’$I2«ÉVKŠP-Lã ËÁx­b{€¤h^HtX5K3»l6ν¥´ù­â—R3«É±½^¥rǶޫ›’AŠI’$IëˆÌ‰WãS—è™P±^Ĩ}$½KóÙÝ¢šeˆ™rÀäËͬQ¬DÒñ¤@H’$éD-‡	4с3Üýi±%+E«ªXY-$ZÓÓc¶1³S"ÆcN#-I’$I×n¢Cd]$-Hc1¯PnÒ5•æ³5Æ·g5ËlöÔu¤@H’$™Ë‰R̯ŧ.‘’Xd¹.^ݱܤë=šÏÖx¿C¦g„$I’dÎ!õ÷)uœ¬&²0úÓ8>b«òvX-Æмh”úØ]÷Ç`3Ùìà†¤@H’$Iæ.½P,ðO×'i‹ˆeÏZ”Ä´  nIDATÑ0>bÍgkŒ
+wJ§e§·“t9ðàŸföigÏ££H$I’t:ð8">u‘´EÄšÀö¥}}[Ò¤‹v¨fYã9þ.i3àjàcI—g7“y‘„$I’$™"ó¼}uM¢~Bµ[cY`óª}‹HjI“®ÖV³<ïã±pp°¤áx÷Ê{ªU!B’$IÒ£‰ú	cãóL½q’槱ˆˆ÷ˆ(7é*ê14%$ÆÕ,Ílº¤¯ã±ýðÒâ$/«Â¹fVt"MB’$I’tâM~d|êíª«ã#VÅT•›t}@CqÞSbþ¸Ô¢ñó0àI¯ z·×3u$)’$I’¤Dt”œ­7&Ü}i("6zÕ>o|6 .Á‡’Ö6³º®“®¦Öƒ$I’$IÒf6ÓÌƛٳfv¾èZÌÀ»U¾ö.
++iÃN™pHB’$I’´Ióû óáàc\,¼‹—Ã~ïöù"p8°±™}·+æÜRR $I’$IÔø'°%ð!. ž žÅ…ÀËQ¥²ú¼™db’$I’ÌyDÅ­€“€Íì.žR»“!I’$IZI\º±­§Ó,¤˜$I’$O
+„$I’$IÐ#ZX§@H’$I’Î%]I’$I’ôLR $I’$Iç’„$I’$Iz&)’$I’NGRhXÔA¤!I’$Iª‘´2ð‚¤Eºz.]H
+„$I’dîCR?I¿“ô„¤Û%ý>: bf¯7 gwí,»ŒLsL’$IæZ®ÆÛ!œ|8ºtüT`;I_삹uº½!K-'I’$
+4Ÿ™M+m_à?þhf£Zp™}ÌìÝÒ5NNÎ0³O%]Üßžóï®HZX
+XXº‹§Ó,)’$I’YHúÞ¦øw±}0p>¾¸o<+iM3{OÒŠÀL3{3Æ~ØÅÌv-‹ƒ``hÕ¾wIš×Ì>ë¨gêl$-¬QõYXŠå࣮™]ËI$I’”ùð³ÒöQÀQfvpº¤Gãø€-€?IÚ	œìQ}Áh‹ü`§ªCÏ Kஈ1íüŠ¤yqÑSK,æ¯ ÀËâçp`/`ûNžr«I$I2‡æü3Ílb+Ï[Øxº´{m`|iû:àHàGfv•¤O»€Û€çÍìÑ—¾ ¸Ì̯Ú?£5óë
+$õ¡¶X‰Ê:_øŸÅc/†Åç­èúX}ÍotüÌgŸI’$s{ÿªuPÒzÀH3›\uhyàS3›^Ú÷
+ò[3%õ7³ñfvCøÖ/­q¯ƒp¿û>ÕÇÌÌ$ХÉ0˜ÚB o›¼†/ü7RÃÍlR[n;{³îxR $I’ÌyÁá’t p¯™´(n!èSçÜêFoã¾ó‚)ñsq*–…õû€ßIif÷ŽVÎ v–“´6°¤™]Ç× †ÕˆWèâÙW§±X˜?†M ²øߌ[†#̬½,="Í1B’$IFÒJøú“fö~쬿ø
+°lo1³ZArÓ€…ª‚ öÄ¡" ¦ÇýßÆ]«×KÚßÌî~,<ˆ›á‡O–î·pK».’¢¶5``›ŒÄþ»€?BÀÌÞkÏù45ÕNºO›I$IÒдð/Üܾ°”´ƒ™=ƒ„ƒcøρ¡’¶6³‡€ÍÇê\zðž­poì»
+8RÒ:föh8ÞÌFÄñ_ —˜ÙX`¬¤Ý€%Ýü	_|_1³OkÜïcàÒ6|HZ FÕB`5<àC*€û¨X^+§qviAH’$IZ‡¤þÀ:fvŸ¤U€óp+€€Íìl`n	 ØÈ̦Hú
+¸1þ¦¾&€™M’ô#à<I›á†ˆ˜€€Ý`fOK:xNÒÀ†D<A¼­ßGEL`f ÄæËM=«™]ÞÂï£^Ê`/|±}_ø.Œß‡…héŽôˆ^)’$Iº˜Xhïþü
+¸ZÒbßYÀ×ðEñQIÿ3³‡%
+ÃÝ
+ELÀ¹Àñ’–ÅÈ’7³Ifv¤oã)‹›Ç61s‡%ýÎÌÞ0³“$]
+¬HÉ•ú7´ÃóϬLm!°D›BÔÁÂ2ðJé;èI¤@H’$™Û‘´>°+ÞÌž*7÷åïë™ÙI_ÀûÆ痁}ñ7å¡44U¿ƒ/:}ÍlŒ¤7q+B‘Zxð0ÍÌ^«7W3{]Ò‰¸5âk¥ýÃñE¹ÍDe-°2
+S‡Ñ0ep8uR{(=â9R $I’ÔAÒçðžkàQûïÿ5³Kczá¦î­ð`ÀWK‹ˆ÷0Gó¿,ZçvC	f6!¶‰{>‡›Ð‡Q©Q08JÒ/ß^de‹L†ÇÌìUIãÅ}šÄÌ.–Ô_Ò€ÖšéãûLm!Ð/†5•2øakî׃IB’$If°°²™ˆŒg$íif…ÿA|_/|,^%o_IKãcs3{¶™{
+¥\ðþ7z3›åˏœ}p°8p‡¤pÁù¥L†¿áV…2ý)Å4…™ÚÔñhÕ\2¸
+Sߣb¸…ŠÙŽ)ƒ=‘´ $I’t%‘‚·.¾-‰/À/ ·´°¸Íp`&°@ˆ„‡ðÃ…@xø:0(]¼.é4Ü
+ àùÿoïÌ£íªŠ4þû!F‚@À Ì
+¢ˆ
+È`K«8`Š´¨iµ‘F#vÛ-¢¤é…‚‚B+¨Œ¢
+ÈŒ"‘QÆ÷’ D†hˆ„ê?jŸÜ!çMäM7ù~kÝ•—s÷ÙgŸ›—»ëTÕWՏkuӐ"V׺8SÒ‰d=‚=wo-ã— G{ Ÿ.o:™|°èÿ ë4wTìI=I7-C^ î%7þ+HÕB•$øørš
+{Œ1f9Ž”ì]DƶÿLôÙ­©ÉÐx²WÀndᄈ¸3"IºŸ¬)p›¤=]€Ó›®Ñ
+ìXÉø"â/’®*×½ŽÜ@×!ðôF7Ú‡ G–×"2\P…7æ9
+DÄÉ}̽”4&vªÛ´‹dpKê%ƒ/-ò¼dp&#/ìD¬b0ƘÁ¦<ÑnŒ‹ˆ‹ûÞLŽˆiMçŸLƽ@£aίÈ/ìãÉ'ô$í”9Ž—t°ðgÒQÑ
+L4¶Ém>¦¬ïI Ó(
+J¢Þj5Õg 3š[-£ãåÕBD,‘4‹ÜÈ{mtÏ _—ô
+I{°¼!ÐÉà#½]Ã‡Œ1f04¬æ·
+ù$ÝMö¸¸mÜ6dÞƒq[7­yLQOJ' Iý¸"—»\ÒîduÀcÊãÉ.‡ Ç×JÚµÄû»Wû–V¿Û‘I‰}.“t@»S9Öb ”企vøû ¹¡7«Ñ³dpÝ2ìYòé&.ƒ•dpÑ ×`^ö cÌ °)° جù:da[2Jè64¡­„î-¤ëÿÕäÓÜÂ6-ýÀîåç.à=M“t	éxŽ¬AðÒ-Ù,‰ˆøƒ¤Édøb1ðÇʈrÏãý‹aT½6V/ÃæѐžGØ»I;‘Žøìm c:nà-½$½}ô,lÓÖ¡ð>ào¤ápcu°xž'¿gã%msʐuh<áuSÚúLîôéˆø®¤™À—I‰á¢¦yªë=\5Л.’ÁWQï
+Ø°{Ž†dð"¹3jº5šÑƒ=Æ3tÛHzé¾ß¾¼‰ˆ;H)âñíbD,-›÷v4’v%¿ÿù’nŽ–tÙÞ÷Ýd¡ È
+÷²òœ2ïc¥øQ¥ÙﶊˆÊ{1 $£gÉàKÊ°J28ƒVÉàý«¸d°±Ác‰.`màsd¡ ë€ï’¥w!³ô{*°³¬³a©!ð6à€oFDÕ®ø#ÀOɼ€§Iwüw s$kß„Û’»ht
+ì‘"»l7¶)çŠTÜKz ª.ƒU’àusšŽÅcŒYQJéáG#â×5Cn eŠËš5…º©’¶^Kºãl*tDéLøzIë϶'êõõ„_kºîšÔK·¦U2Xy ®kúyvSì¼XæhŒ1ƒHU:¸Î@8¸YÒeÀoÈD½µ€—‘	Žw·öVÊw …}$m@½7`2)\Êò’Á*7À’A3걁`Œéº]$íMë†<µ'ځ,,´.ð{J—ÁRⸯ2ǵÉàæÔ{Ö+Þ¡µË`å
+˜eÉ é{Œ1fé"ëlZ~î"½Ã²œ€o¾˜‰‹d°.Ip’Á‡HÀŸi•>hÉ  ñûbÁ3$HÚØ;"ÎŒù"âà”XÏR‰Ph–΢¾Ë %ƒf0±Á³j!iK²záhÎë#‹ÕI×*Ã¥U2Xõ¸/"–÷šÍ*‡CƘUI»ýö#¿ü>]Cx½‰Ô{6¥U28ƒVÉàLKéƘBÒ¾¤a°;YPHÀÏ#âŒA˜{M²·B]’àø2ìIÕ›%ƒs,4£{Œ1+'%»ÿ Ò0Ø–|Z‡üÒ›G–"È|èY28–”þ…ÜøœI£€Ðüš)1+ˆ
+cL¿‘ôR²	ÒQdëã*»ù»äñd͹«›Qo4K«|€³›~¾'"þ6Ø÷cÌa‚1få@Ò+ÈJ…Ÿ!K!¿àš¿ä–Gw—|„:ÉàeìCäÆß,œ‰%ƒfÕ #~Çm ÓD)µ{PDœ:Òk
+Hš|ø8iôô±”ìað¯À±åØsd¡™,/\ávÇÆt8ö 3)®òÝÈšø³#â1XVóÿÝ’FďGt‘#ˆ¤ÞO&öõ]!²ëàO_Ðè2hÉ 1Ëãƒ1£IŸ N n'ŸŠß(é­1½9˜.éƈ¸„–9R¼AÒÙdA¡Šþ|Oˆ¬88•ìªxc:›1#½ cVI›HÚh §°GDì{’qóï-{3â>àೃ»ÒQÍØòçAdÂ`sŒt)°˜ô$ôF•—ðYà%<aŒYžŽð Ø@0ƒ¤É’lúûxI×·ó$ý°”Ó­;w‚¤OKgFÄ]MoßBfä7ósà I£þ?ñ‹AÒê’¶–´Ÿ¤/’•!Û '½“€=€"ó
+Î&»>D«±Ðn@Œvn—ô᡾cÌÐàƒé$>F&ÂU|•,»¹Áÿ
+øð½²1í‹I/ÁØÜÞSsÛŽ]O>IoܵÜ‚¤ué¹	Qõÿÿ¯@Kûáò9Í-¯kælBÖ)h~mIv?܈T;üDÒ>ä¿Ã3ƒxkÆt2áA°`†Ik K#bIŸƒ—ç=¤PñVàôˆX ,ôà02\pp p±¤Ï¶«YÏ^ÀÛ€×4ˆç%=M&ލjÊfý*êë¼¢[Ì!“/¦UQ° |×÷÷šý0 ÆiûJºÈFc ÆÔrp$pí@N’ôràõÀM‡×¦ÕÕ}!p´¤#âaIû“ž[3"b^ۜぇ–VÁíôsVŠò¢§&D•!³€Fq¡Ëi-;übŒ²ED¼@/„1fôcÁ73ÉÒ¼µ‚¤ï§FĝmoUvš­î4ýGÄÝ’‚¬Ö÷pñ|ø`gIãÛZö~¸>"~Q³‘á‹twƒ€¤Mè¹	´–¾8•FÙá¿÷z1Æcj袸ú%ý¸5"N.9™wd/珪<öN+çW•ýÆ5?8‚Lš»RÒ;"â)Iï>œPd}Û¯Œˆ
+Ëy; ³"¢%6?X”&D[Rß„è¥eXsÙáßÒðÌrÙacÌPcÁ*e“Þ“ÜȾ¼Žl®stIRë&“þ¸^Òñ0°pWÉlO–׎Àÿ–cWç5yÖ.Ç电켚ô <O>i_-émÀ†À¤vÿ:à;eÍ{—¾øO")%Šë’'ÓPUe‡o΢a<䘽1+%ö ˜•I;ï$ÙGDHº˜|ò½ø%Ùñﻤ
+¡‹1·K:88xðûºk•pÁ%Àûh—wHúYùozDÜ[ÞŸ
+ü{Q1 &éeŘ8­¼z⇴*&zûV#3÷ëÂë–aϳȍÿ\\vØ3ʱ`úDқȧò#7EÄÞ’þ“|*ßø³¤#âAÒKðHDœTΟüQÒçÉÚüëKZ?"'å‡Ý’ö 
+„szYÊ9Ài’¾K"b©¤wÇ‘¡„[iô ">Þ>AD<ÕŸ{Žˆ…5ŸÃ:ô,\½{”Üøï"••!à²ÃƘ
+{LgPž€×ìE§~&ù4=8´ä
+ì³ËþŽ"
+„窓#â6Is"âjIsÈ<„#âÿ$}–446!›ýÔRν™ô[ŽÍ'Û
+E28‰zo@•Ÿ°¸—Üø/¥aÌ(’KcŒéfh(In;’O´Éb7Ýqó æX8x;ð”¤K"âó5Cg ›TïIz#iï'i;r³_T@µÍ±.™}_½¿-Eþ?—4Ø ”9îÃÈ2¾?‹ˆîþÞk;’ÆQ/ÜŠ†dðII‚¿¦U2ø|ûœÆÓO:"·ÈBç2…ŒÅŸKÆáß œ.éµÕÆY6ï§È‚Aûó€/EÄ=eŽËû;DÄ#=•)&7ôf÷øÓ¤R`	pi˜4»ä»€$}88„ü1½éýÍÛ®q	Ðgf~D,”ô:àÙ¾ÆÂ2É`]X`SÒ‚_
+<@nüב¹•7`~®aŒ1Ä!3¤Ì"7è“#âÈ~À	 _"å{÷ _ þ‘”úí@nðû ÛWR¾^bäÝÀ[ª¿DD—¤™¤,ð[åÚcFÄyeüR­p<éYØ?"•)¾\
+éPÎ]øpzn¼=R¼)S¨—Ž/Þ)ŸÃ2dÒ,\„1Ƙl Œ’vÞAndë“ölଈ¸ªmìêd8aQDÜ
+‹›bù·”¡«O4Ú
+|x]QÜ¼‹TÜTÆü¥Ëífù2Å—IÚ¸¯¬ïjÒcp?i |­‡DÁfã`õ²†«I/BHÚ€ž%ƒU7ÂyäÆÿàG4-4ÆŒìA0½²ùÔ<¬Ö·˜4.‘45"ΐôwd(à>`{IW’Oã/®ú·—$ÃýHoÁnMרÔ¹1Kú%°3¹‘/ >@jï{c&0AÒ„ˆx¬Ìu»¤ÍËõ^ n«E]0“ÜÌïïmâ"_Ü´2š$ƒu†Àzå´çHcjp>­’Á~I1f„±°²#iCòéyÛ¦×:±c§v/‰ˆ‹›ŽÝ!éYàä¢
+€”öý[DœQjñÏ&õ¾M Ÿ"7úÙdái4Z÷v%MŠˆʱõ€¿FÄIÿ
+SŠÝF6-º7"~ּЈxVÒ[h«PêôÔàçôÒË (!–’*#`
+
+ÉàcäÆßE¶_n–Žª>	Æ3 :›iaÅ™F ú¹‘]DnÌː´3¹©¿˜ï-c6)…{šµù?Nvæ“ÒºK Š$ð;À{I¡x2"+×9¸IÒýq*i4,%€#ÉÒ¾{•õÇJz¨Â Ӂ×ÝdDÜTw¼'"â«J&Sï
+ب]BzGfíš›%ƒO`Œ1+'ö ¬tó#âк7%í
+\FÊ	¿¬WžØg“å·#KìYȧÔ˜D#?`qÓ”ÒháÛ
+l&é%ñ·ˆx@ÒÁÀå’n,a€9d££»H«õÛqMÓõúª(Ø'’Ö¦gÉàZeØB’Á«h³-4Ƭb؃°ŠÐl)il‰ñO"7ý;J{á#È2ÄG—ñ•«ÿyI³ÉD{í‚5 •
+ÿ>²dðIå½ÍȺ¬È'ôÛ"â7’¾HæÜ^Ö÷ûˆ8˜DÒD꽯,ë’ÁHUBå
+’¦GÆӁ8Iq¡X“,%¼9§ŸAÊ
+ç‘EŒnèáÜe
++$íL |8EÒƤÇáp`_X–ðŠ(ÇOm[ß6ý½™"9Ü’å
+­—•aÏҐþ€†7àK1fåÀÂ
+R
+÷Ì~œQSë.ðúNïªÞ“´5p ™ÓpxD<Zæ?GÒCdGÂÅÀ.ÑÕtý“–›µ•›€Ú–š	uÞ€ÍhH&7þ?–û«¹–cÌ‹Æ„Uˆ.`l€Î&¥‹ç ¿%ŸÂ÷‰ˆóɧû£$- ]óW{DĝÍDÄ
+ôì…è‘R¼h60VÒ4Z
+õË°Å4$ƒÒ*ìWc#cŒ1ÆÂ*BÕ[  IãÉMøžˆ¸¢4#º€LØ{ŒT @o&K÷Yf¸'$½ŒzoÀ2ŸrÝ*Iðb†À}–cÌ°ÒXƒCðI×’óxróý$Y@è4IßV‹ˆæ.‡OÐZù°GŠòaõ†ÀÆeØ4$ƒ—Ó*||EoÒcÌ aÂ*Âõ¤w 芈¹íÊSzŸOê’Ö"€vC`+`í2ì)Þ€kh•.nŸÓc̨„ÑD‰Ç LŠˆsInØYÏÆÔ{&Ñ*œIæ.|Ÿ†7àáA[¼1ƘáÆIŠ£òD~ðEò¥¯ȃyí5È<€:ÉàËË°E4$ƒgÑ*ìWKccŒ1‡
+„‘BÒzdyã#€uI÷þ±p®µ>¿ÙØœVÉàLàOÀ¹4,4ƘUŠŽøÎ_é„RÉðà_Èû«îñ˜ˆ˜¾óŽ%kÔ…&”a‹9äÆ­’ÁA7LŒ1Æt,ö ’^M†"U—¥Œ¿ÞÏy*‰b»!0…¬˜ð8$ÁKi÷Z2hŒ1¦ìAJâ/o'±4ÜúKg€EÄÒ¦sDö¨óL,Ã*ÉàLà×´JÚ»2Ƴ’cÂPP6øýÈ~;“=
+DÃkP18ØMR»dp\ó4
+oÀu´JŸÃcŒ\ìAlŠ*à`Òc°ºí†AE ß*Î%
+ßgÒðÌÊ5cŒ15؃0”RŸ¾@**ÆÖŸ4,´³€Ï9IÐcÌ(¡#ê ŒéôÁZ’N ËXüPûóÁVã>\'i³![¥1ÆÓ:"Ä0š
+‘òÁ§€édH`>™ˆX¤´ðù^漸SҁC³TcŒ1f@ŒzÂh107"ŽŽ«JC6'š¼ªéÏ-Êk"†•1†LJ<_Ò߇»J¡1Ƙ¢#<£Ù@¨¥È*¯›Úß/
+‡
+i5 &“U
+§uÞ,éÀˆ¸sXmŒ1Æ´bÂpSÊ?R^7׍‘´°±$¹Ì±1Ƙa¦#’W:¡?DDe@cŒ1¦†Ñœ¤hŒ1ƬŒt„Á‚1Æ3¼tDhÛ‚1Æ3ü؃`Œ1ƘìA0ÆcL-ö cŒ1¦')cŒ1¦3±`Œ1Æ/ö cŒ1f9œ¤hŒ1ƘZìA0ÆcL1cŒ1¦3±`Œ1Æ/ö cŒ1¦3±`Œ1Æ/ö cŒ1¦3ÍÂãÀ“#½cVó˟Ƙ¡¥#<Šèˆz
+ÆcÌJ¤M€Ý#â‚‘^Koü?Ÿ x³d­    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,35 @@
+‰PNG
+
+   
+IHDR  ó   w   Y©1   sRGB ®Îé   bKGD ÿ ÿ ÿ ½§“   	pHYs     šœ   tIMEØ6ÆRŸ   tEXtComment Created with GIMPW  àIDATxÚíÝy˜åÇñoõ1÷ÁƒJ¸ÅD0ȯU‰LŒ®Y}6n²OdñŽñ@£ÆÅh6›Ý51Æ„Ä ²
+‰GÆ›ÁP9<ð æ¤gºkÿ¨é™î™îžêkººù}ž‡‡îž®îª·Þê_½o¯±~ÍJÉJóæ_çè‰Ç«$DDD²ÐÂ…ð lX[«ÉRžàƒ©ç=ÖõªFÈã®=†ÑóqçäF”ÇÖ{#?î|w×c#döBž„?îúâ®—È{,câËkëûâïHešÌ|G*ÓdÖSÒËØm¾ã©væ;Ê÷%<ßñÔ};ë)Ë6¯ÚfµÍj›uü6:Ÿ©0!ïÃÎÇ.íψˆˆäHË\DDDÒï‚)å	O[]]ÍîY¦0É´DÎU[ºlEn·Ì?ëgzCÒŸ·íµÛ;úúÍl}uaçóÑ3oql9¬ù˵ T;7áÏxë©+˜:w±¶6‘,Ñ#Ì›6ÿ€’±óz¼¹áÇ (;òröðs ʏºÜA>lÊõìXe=?ìøè¡þÉ›wôxmÄŒ› ØÞä#O¼ØöêmV¨Ï¼ØòŠìcNº5%óÿÁó7öxíèÓïìuº÷ž»€‰gÝ£Z,"’Å*«¦°~ÍJ[¯Gõ¸ÆM‡ùƇž—uyƃ<Á >ýF¾6ý'|múO¬ýv[ӏžy£SäãO»ƒñ§ÝÉøÓ¬ßð·«v‹ˆ$‚aïxƒ<b˼{ —Œ›GÃƇ{ü­{Ë|ßû†ý½å|ö®·ºjs%{Ö=ÀÀc P÷Þýaï<ñªÎÇ;×Üö·¡Ç^À—ï„·@+&_×£…~èÔë;ŸV{WG=±`ÜöÚmŒüú͝Ϸ¾²Ñ3oéÑ2ÿ¨&¼Ûýˆj«%¿é¥›Ã^÷Ûã_Á+¬Þ…ʲzÖýÕZ¾	gÞÝùžµÏZ]ëÏîÙB_ýÌÕaϏ=gQçãw–-ûÛ”9Dœ‡Ú'çpüyj‹Ic WVMt»A5Ì‹Ç^FÓ&«»½±#ÈKÇýGÖyP}G÷EkVö¬ë
+Š`š° ƒÝk±kí"W]Í®Ž 2éjB¯Õûê]+¨9îÚÎ`ÿâí»Ã=ØÍÔÕÍžØu}Ánö `7{¨^¶}̬…a×Bƒ|ìÉ·c°ñÅ›ØøâMyÊOS^:»ÙîAníMúæ}À»Ë¯æÝÿ»ŠãÎYÄ;ˬ§ÉçÞ¼ýôÞzúJ¦|+<ÐW)ÈEDú<Ðã
+ò˜-ó’±ó:»ÚKÇÍK8ƒ-s¹¿;W[¡>tÒ5Y½b6½tSÖÎ{gÏ])¾ÑˆˆôÔ½›=é–yh w»áTZ…¶Î¾Z}og7{6
+¶Ì;Ûì
+E‰ä¡ÇÏã	tÇÝnHÕÕÝì’IÁKÓ‚ÇÌED¤o‚¼{¨'Ý2·«|üÔ¿ÿ`ØIpý+#‡ÀÀ	¨{ï~v‡œ7xâU`a­rèèf7`è±×òÕ»÷„×ý¸ C§ÞÀŽUwE=nø	7òÉ›wðÉá—§/M‹Ç˜“n壗o
+;	îˆêÛ{òmlzéæÝìݏ™uê|ðü¼ÿ÷ðËÓŽ>ýN0*ϸ‹õ+n`ý_¯ïñÝμ›÷ž».ê	p“fßËêg®aõò®£cÏY„w®uÜü퐓à¦Ìy GÌÔ¹‹Yõä|j—^¡ãæ""i­õO7»aš¦¹am­ZÑ 
+´!Ö|k m³ÚfµÍ’šV.˜Ržðàjjj:oç:!ïÃÎ×t;W‘>ëÖ¬‰P˜‹ˆˆô¡êêꔦÂ\DD¤Eõ,YÏ\DD$Ëu¶ÌW-ý•†ˆHÂÌ(EÒO-s…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDDa.""¢0…¹ˆˆˆ(ÌEDDÄYaîr5SVþ†J\DD$ÅúdToþ§Œû}\®46T±éƒûÈÏ÷ªôEDD²¡ení;ìÛ´ùö()­¥‹ùËsÛUú"""ÙæÝCKxÝn €©S·RûΖ<±Yk at DDÄÉaîr5âv-Ç0ÁpN³€k¼Áþ×û|¶c¿Ö‚ˆˆˆSü_ù#´ù ß†Ë jÁD[3œ0}'LÛ̞بµ ""âÔ0w»–àqC~¾8 |äãq[¿fþk,}úSvïnv\ÁTVM;¨+F´åOw¹8½ÜÓ5©ú܃½Þê7!¾åé«eR½Ìâ0P¾˜@;x ¯¸hZ€FŒü!гNù’“¦oåwK¶d¼B‡þËäÄÁPésyûòÇ1“õ6Û¶‰D>#•ei…¾–‰ßõkV²~ÍÊ^¿?—êšS–#ߝ¦KÓüxÜO` ¬Ô
+x1[›xýe'ž¾¨ Ï.0L.ûa-ÿð(.úîH.éóB
+­ÌÁÇ™ä„yçsZ½Õ6‘Û˘ëÀIÛJ:æ#-aÞ¯ôÚ[”• EÅüqI€. &àÓOà°Ã௯㬳?å˜ñ›ùóÓ‡ó£Lpl!´ð£½žè´Á×Ö¯YVáb½7‘ïöZ÷ùëþ™½íEÆš§ÞÊ!Òü§ºÜí¼Ö}~씳Ýe³³<N®·ñÔÃdêB_m½­—D¦±óY¡Ëú÷í.RÝ´Sñ¬¿XËf7hbýv$2‰Ô£x×g<ÛL¤uïòFšÎδŽ	s/¿ÆpCq‘Õ*¿à €"ÆÑŒÁ
+—ùùÝò6Üî:0aÁ¿¯äâËÆrÑc)+-päÞ¨ï´½E´ï±¾½½fw/5Òt©(«Xߝh¹Ç»Ü‘vhì–s¢ë'ÖòdºÞ&Z~v^·[éÚ&â]ŸÑæ#™ß„dZÑêh<¡ÑÛ6kž#N¬xÊ?Ùzdw}†î<ÙmÐØY—ÉLŸÊÞ‚”‡yÿâ_á÷AQ!P^Œu¬¼
+(£ŒA4cÒ¸÷K J†@ÝNfŸµª_næ‰'Gqé%GfEwM*Þ#©/w'ΏSæ;Óó¡s%ˆ¹“ŠnÙtu%ÛémÈt½°ó9vZÖÑÞß[+=Ñõ–ªu–ò0÷úÿDÀ€¢«Uô+ò²¯¹?>ÀÍá-À`$;Á—^ô×Þvß™;ÂQ­óDVP:[]3§·³;?¹|œ.›×_®-[¢Ýå™Þ	JÕoe2Ë›lY%:}*×YJÏf//XB›¯™B7xËŠÁôÎ<%@aA	Ã\yL;¡ð>(Lû¸ðüM¸g²ì6¯
+j•{ª[é}±lj¥gnÙÒ²}âݏýçÂïC¬iíôD$òÝŽk™çµÿÓùEðzaÿ>(‡¿ÝÄ–¨¨N^ÞÌœ¹×ê}gTàqíæ_ú&?¾ssÏEAAžc÷À{;a!ZåŽ4m¤“¯ì~O<óíózÛ“ÙPí|§ÝË)÷XËïFm÷ø[÷eK´ÜPo“-¿xË«¯¶	»ËÕ[=MÅ|¥j=%³ÝÄ»MF
+µÐçñ”G¼ÛA<¿­v–!ë/]¿1ñ2LÓ47¬­MúÇ¢,o	®Ö)̇¥P ìo€Á°öPuÊ(Ν5ŸÆúx¾v94 íÀáÐÜuuøL8aÎ%|sö,Λãücç’Û-]&(¢íÔé–.[AMMMêZæÞ¶Ç0<ùnhl‚ Ð+aÜP‡I[¿G­óáÚ±þoÚÅýhûªŽ¼þðýóßeÑ£#9óŒ1zT[ED$-­Ù\’’cæ¥Þgñ؋ۀ’|ðûÁ×f]VÞ…IÇøøåï_á´êϬóâüXo°nåê)*àÀnøÑ…ïá
+|Æ‹/mÑÚ‘ŒÑ„ˆs·Íл×I
+üȿØ
+ò<p@k›Õ*t´ÀM˜|¼	ìaÌáû‚÷Ž±þùÚ¡µ£ÿ@Œv üëJy|;€©5$""’î0/ó<K[k^•äƒÛ€–VË»½£Þ Ó«ö’ÏÇ?¬š;^†ýÞzÈ+$¯8á{g¯#ßý1{~[ί€xï®fw:'Ì{ª§sÊügó2çêvr°Í«ê“¤<ÌÛþ—	ù^p—As+´›VP[àpleCúµ2ppÀ@-æ Í µ	†¥­J¿·šÇþ´¿? §4ÎC<dãH.]2£zŸe™ÎA_ÒQ&ã`P]˜—¹–ãoý
+¯Å¥%`V˜»ÐCºÚóKý<öÀjÈÃ
+ó@H˜·»ê ¯o¿bü{àŠï­¦­åc^øÇÇ9Yð™>Þz‰¯ÍU:Î'Ù^¿T‡)©ÓÅšîÅ€¢BFi45Y­r #dw¡Øz>ë;{¬.v7Ö™ìÁ–»4ù aTÃØ·¼pí%¯sÇo†sêÉ#p¹Œ´†Z÷çñ‘èMø£íñÆ3ˆC¼gwƺo±ÝR9ï½}V¤!࡯u‰VN‰Ô/»ßë¦NDÅî´½µ<%žrÈÔ`<ñ.k<xdzàqH˜—²_kù_\ í~hnéjmA^«^ÈãøïÍŒ«¨`ÃÛq—`Ý8&´;~çNQ‚«¸ê›9ÿÔxàñYöÜF¾uvß_wžÌ v>'ß—ÊAÝ+g0‘xË"ƒôÅ .‰Ôt|·:’Y†T¢’ì@4ñÖ¯lŒ§·zœìï@¦¾‡„yaëoi7Àë£ ¯£UÞÌ®ÿðÏW{
+6~1€›~fpçCÛ¬VºÙñà€êöBy|uÍ
+†óO_Ç—Ž`öéGàõºQh±î@”̈XÙ~BY2="NûÜL–i¦îO©yÖ ,é;֝êÛŽJŽ…yëhkځÇÅù€øººÌƒ­ó€Õúþè‹` “†A]}ïðoëj‘èõõ0äÜEyøë|\>wþ~¯¾¾“gv\Ù9ÝÎû“p ÷zS1ÚR¬Ö|²å’É2ÍÖõy0-oª—-Õe`ç°˜ƒÊ-	 WÔöwümà2Áíîè^Ç°.Ks…ü3ȇÙÓ>ßåâÑ%‹™1c¿ÕÅnÐõÞà´íí°o/nÓà€JûÁ7¦lgÉS[²bÃÍt—RèF«k2Òª}=ßé:ñ.ÕË‘­­ôlœgµÒÓ7¶}¶×
+ICË<кšv?ø|°Ÿ¯ÛÄÄèÚ5X»	.
+Zaùo¾ä§‹GÒØÚ@ÓŽ™œ=ãU|Ÿƒ?ÐÑ ïx?&˜ûñµCÀEí0ùÈ<õ«ÑlÙº—Ñ£úg4PÒõþXïKdÀx¿/Ö€‘^·3 F<ƒF$3L¬rêËA]ÒQSõÝND%™h’<%åÎÁxìl{‰Ì—Ým<Ú:K÷6 ‰Ih •ò–‡Ùÿùãx=àqƒãFm.x¼0¸ŸîMÍP߁ ˜¦3;ën”@¿r˜sý^^3œ«æù³+µÖDÄ­L˜dZR­ÔΣ´ÿF싺z.Ó´úÜ»ßߥã8À»ÌŽ÷˜FH+>ä½`½¿À>Ÿ‹Ÿÿy2/¼5ŠþeÍ”•h͉ˆˆt“ðÙì
+bÕ֏øßÿyƒ–ÖfŒ˜—Gjº1ßíqùñµ{ØöyÊŠ[8®j3fŒÔGP«\r"̦NÃðáÃX·~gÇùoFxN›Ý2Ûìö7¢<7C&0ý{9nÒ¡Ž¹4MDD$gÂà!Erò•¤ˆˆH†¸T"""
+sQ˜‹ˆˆˆÂ\DDDa."""
+sQ˜‹ˆˆˆÂ\DDDa."""
+sQ˜‹ˆˆˆÂ\DDDa."""
+sQ˜‹ˆˆˆÂ\DD$gyT"©QY5M…`Óú5+U"
+sg2MS…Cuu5555*…¹ˆ³mX[«Bˆ`é²*‘4Ñ1s…¹ˆˆˆ(ÌEDDDa.""¢0‘¬VY5­ó_÷×c=‘짳ÙEr$ÈC¯Ýîþ¼·×ED-sqPƒuS–H-r¹ˆÂ\Dr(ðEDa."""
+sé+‘ºÝEDa."j»ÇÑE$7èlv‘ôhÇǃïÓñs…¹ˆ84Ðí¼® É=êfQ˜‹ˆˆˆÂ\DDDæ"""+ '’bK—­P!ˆˆÂ\$[UWW«DDa.’ÍjjjT"¢0ÉVº~[D2E'À‰ˆˆ(ÌEDDDa."""
+s…¹ˆˆˆ(ÌEDDDa."""
+s…¹ˆˆˆ(ÌEDDDa."""¶x.\¨RÉæ0×(O"""Ùíÿ¿ˆáÓ|ƒÅ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001_fix.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001_fix.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_001_fix.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,43 @@
+‰PNG
+
+   
+IHDR  X   í   úm2   sRGB ®Îé   bKGD ÿ ÿ ÿ ½§“   	pHYs     šœ   tIMEØ
+,i+/Y   tEXtComment Created with GIMPW  ÖIDATxÚíݐ$e}ÇñïP[þÑDJ£b´Ät—Û9vÃíVŽ€p§+r€$¡!ÜÁÁarÀYÃ$¢î„å‡Å¯r‚ºÊF.pÖŒ§è ÜÉž©h󣢩P‰š¿'ÌÎ\OO?ý<O÷óôô÷«
+vo¶§<Ýý™ï<=ót­Ýn· àD£ÑV«%ÍfSFDDØG« €c#Ý_N™}¸óKM¤Öù_ৈÔjŠŸQÓ‡ž·2aç§Hmå—ÁŸÁéLž¿^Öó
+Og³©ÚÄ|½Œö‹Í6Úî—Äm¢~^oY{{{Ý帲êU‡úþ}¯1 โ€ªÚ°úÕ‰Ÿ;33#»e‘€ •$×¢—Ê_Áþì;ÕûýØ57e¶Üýßø„ˆˆœxîg9:èöÿþá.9ò¸MÿïOî‘×¼ójùŸƒ;EDä·Ç¶uþi%\ßvz]j"òÓ=
+yûttоü­O<öŽ÷Ý\ºû­‡.x쌍pÄÆ&¦DDdyÿ^£Ç­+Øß¼</G·¹÷ï_­„k×kF·®˜Ïñïý”ˆ¸¿Š˜§p}ï¥÷÷mc	7ðbyÿ^›˜’±‰©^˜Ú†«¶‹à×/ß)G¿Y~uè΁¿…+ØW^ÚÑ÷÷£Ç·Ê¸MDD^wâuòËo•×ŸÔyKýŸ?¸¥oÚ7®ÞÖûýߟûLßßÞ<u£ˆˆüüûýUæ[Oë¯D¶§!Çž^ïýû[
+ö÷gF
+ñã§;Ë=óӝF\º^DDN8kNDD~ôä_öM?qέ½ß_üúu½ßßuÞm½ß_xüÚ¾çœòÁN›í[¸z`ù§~øp?ûØ໇Ó/º[DDö<rEßãÓ—|Þúàyê¾Kûþ}ÖÇÿVDDž¼÷ODDäì+–'î¹DÎùó/Èßßýyÿ•ˆˆÈ×ï¼HDDλj—ˆˆ,~î¾y}àšÇDDä«·XDDf·~Y¾rÛùò¡ë¾ÂY‹Â†lð1‘Ó:òŸà¿^	×ßzÇUÊ™¼²Ü	×מp­¼vÕµrôª­}ÿ勇û(ñÃN0ýî»þBÞpr'´þãù¹•píü<fòz9fòyóÔ
+}áú–S·Ë[NÝ.""ÿüì_÷-ãmpív¼}Z®‡vo—C»·ËOž¹QÛH/=ÙyXuößÈøÙ·Èø9ý/'žûY9i¥öwxÛO^»¬^¿CV Ó>Ï}µ¿;eêCwÈ»Ïï¼3øÞ—6÷…ë{6Ü%ïÙpWßô{vuÂuÍÅ÷ÊšÜ+""­‡?®\ïÝn”Ýn”g¸¬÷ØÓ÷wÂõÌË’µ{HDD¾ùù?í{Þ÷\btð,ÞÑ	×õW?*ë·<*""_ÛqAß4·Ï™ŠB‡lÒp­`<n“üæåùN¸¿9ÕûËםx?T¬óoû>³R½ÞYÁ;ϸY~üôrð©ÃË;k.UH¸‚uåۏüYìßÿè£÷
+ôÁ>óÀe}}°OÝ÷QåóϾâá^Ût«ØoÜuqïïçmÞÕ×5ôøç6(ç5»õ˽{E¬^ƒÝNºŽ:n³¾lãÝ›NÙÖ«bEDþuï§{]EóÂb'\W¯ß!Ryþk×8›÷š‹ïüÖJDÈv_<v?¸qàïg^þÐÀ·i’Zõ£ƒß¦J®Á>XېÍÝ7¹ÞtÊõrÌäõ™/7Ø;zf§‚^þæ6Ž2yÿ•_èý~îæ]4*®á uRÁšú±kä•åòß/ÝÞ{ìèñ­‘Ó¾þ¤OÈ/~xkß…®îE®`õz¸‹ &¿÷îåçß¿Yþå{Ÿêýí­§}2²ò:vÍMòÓoߤ½Èuh÷öÞﺏiðÇsòÒ“ÛäGO¾Ð¼Èåäu·Ë‹×ÊóÛU®§]0/Ï>¶I¾ûè•;ý¢{dÏ®+ºfBº¢>¢õ¾ËZM䌍ÊÓ÷_:ÐEнÐecÝU_”Å;.è"øàÊ…. ¨TUªmA­Ýn·ØÇ`/9p£´O0Øǃ½øìeÃêW'þ&W«Õê}UvÕ«õë
+Wˆ|	Lë/¼›kD€gº¯½&AÀæÐi̼‚ðgffÆË|	X •§
++-ƃ Ozìs—ÐÀеC?QdT° @À   `€€  @À€W|“«ÄFÇ'K³-Iâ Xx×2…Ò¦-Ûd~ç;åØ"VEá )SeW•ŠozzZ6mÙ&Íf³’'já2çV[Ôª(Xý”­²+{× ]Õ<†ËòÎ曓¶¨;µ[ýp`¢è<Çpt»>` ,tïÙýÏçr‚?¶À¡Q†eø^—î­‡ƒÿùâsÞ¨VAPé€Íª"Ê¢ª£²l‡ðãQûn_Õó‹~ü¹Þ®<n’ùÇSeÖ®W
+N¥RËû÷ö¸Áû½÷c÷߶ûW5½¯c$ÏÇ_–ëµïÊp¬V:`u;Ru"Ǫ?¸¬¨é\mGTÐè¶[·nI¶Y7­“ÑÅüMöGp¦	—ÇŸí>ÒÍß䘍[¦¯ªSµ>Áõ6Ýn›ó1jŸ‡ßáè^ô+YÁšüÁ›TJq¡—Õ«µIØš†—iuhZIúxûT¦w"¶ÇŸíqiS©'Y—,Û!ê\KºÎI·¡Œøˆë©{…NÚ¿Byx›í+øòÐ÷äû O[½fÝEZǬÏÓùÇíó2^ÿq}¤}ûn2½ë@S]Irâ»Z7Ÿ¡£z[ªê›z<ü˜é‰UÔ*¹ëWÔø^ÿ´óÏâÝY!Ö¦
+qu±$‹Ä´+ ‹ut½Œ¸yÅõŸ%yLÕ­ãj»†Qç½êÖµ‰ïõ×Í¿JÄG\îPÝ㺆5Þ¶zò±m¾¦ªU•$Ôm׎içoZÙ‡_\\_˜5
+Ù¤Ë6ÙnWí\Öc»Ön·Û&ßm.òw —¤ÕjI³Ù¬Ä÷¸Ëø}õî>¬ê…U;†‹|\t×izzš¯Ê€õz€ ØGÀ€/Ú>XFN/î«g™û aš™™‰íó
+öTñdEñÌ®[+³ëÖr,bè/ô6è"  OX  `€€ ° @À   `€€  @À€o#ÃXè0îµe¼‹%€Šì0µh뀀7ÚÌ캵V•­ê.“Q·ÌŽ»w½nžáç›Ü~<ȶ£ì 0W¯×9’Úˆ¯Æˆl ÕMÒT!©ººIå©ê
+0™§júðtªmN£Ñ ‚S_oÉ£îÚ9ŒÛ8›l/€êáS @ÀšU´| @ŒML
+ïSº‹FQÁi2­nYÁþÔàE.WË€nvŒkÁ&«.~©æ¡ª^M–·,Óå@i» €€Í°2¦Ò@À@‰ŒML° àë5 ž° @À@±ås°¶#Ou$ ìP´Z-£éæwα— °¶šÍ¦vš2U®>ÆI`ìwí(âæsÓáy¹œ7ØÌOŠ aßz&ïa™‡@Ž
+ÕàçÃ؇&ËWW¡›/ˆl¡p°–OÞ÷išÐäx%`KóvOUaw}ë“*[WE½½Œ;9uó2­ã~7¿é(iª¶×-;j?%]?“v¯T˜ªÖ'êß6·&"Œ	Ø\…ižn=£ªtlçeR)™l«ÉúÚTkIo­ã¢;CõB Û×6m’&Ü’ŽüFw[Ê·“øõŒª²M:]Úçê‚ÉõºEUt®÷y*m›‚€­¼¸Ê6Ét>_|toóóþÂ[´+øT¬åÂ7¹VVE¬ŒÂÛªÛv×Õ¬ï6v=ÿ¨þx_Ç
+Õ,lî‚#/·žQŒ¦/ïß«œÎv½L×צͲ¸µŽÉ2TÓ¤Yg]¹Øö¨yp»¢ò©µÛív܇ùGÇ'­>ì¿°¸¤ýjëÂâ’Ì®[k<OÛupýÞg• }¦d¹.­V+ö¦Ái†RÁÖëuŽ tø÷¯¿rë .p‘ <XX\"`E’_­õ}•·(W‘Ç&¦2[W®¬£(Z­V9>k{åµÈ¬Š<PJçñôt!!¬Ùl–ãcZ|½°8'zö
+Ÿ(©‘²è&·¨*Á¸jXW%Ç}o>ü<ÓÁhâBªˆ¥$y‘L²IÛÚÅ€+ªu°=.㞶•^’MtÍ€(i¿køÃ(%î q£{%mSÛ¶6Ù·q_nˆN“1fÓ<léè|_eŠ:PŠÉð…iö…«}j³ª
+T5½®š-k×
+§Aç²"Fu_¤R\¶µË¡
+³~>ò¥ÐÓÊrà
+ÛõV7G‘æµßòö"äk¸H“Š¤QÁæ.d£ÞŠÅ='nz›AB¢NÛÀp0y(%êÂ’j4/›ÁO\µµÉ2UÇÒÖÂ`/å3”Á^€¼w1 ?Š:ØK)>¸xO¸‚.À!B¾1 ° @À X  `€€ tnEÀ€£ã“, øª`½|Ñ Ñhк *ÏyÀÖëuZ |,ƒ¼ @}° @À   `€€  @À  lø¸×üØÄ÷°€
+#×å{~Ýwo÷ܽ^’åªæ
+€€Í%ßwUÍßÅr¹Û)PÎÇ"XX\RþmvÝZëŠ.ª2>¶¼oïgxºªR·œpØuÿ^¦îqÝv¤™GT Çí ˆêõz!Ç9ñÕQLH–QáWñE=W7O“Çu§j½lædãÚ(¢":âkÆi^mT!ëúíô0ú:³X&#š%ؤ¢Þv§
+Rݲ²רj@9åö"—îm+K T°™„§êBMÔEðô6•gÔ²’Ì38½Éò£æo².Áy§Ùn î"°ý˜“î‚QÜßÒÌS5U×…n¹&ëb;‚ ‹  X   , °   X ¨ ¡|Öv´§¢Ž¤€€ŠV«e4ÝüÎ9ö ÖV³ÙÔN“´rÕ
+cX56_óEuŽ1οrÛ[«Õ¬’ªÖ·ýáÛÚ ¨pÀÚ„+ ÐE¦ív;q¸êîn ú»ÉmYâ^UIÆÝÞÆä–2á·ö¦·´Ñu¤¹iûÙÎ_·]6í¤ÛO¦óŽ›§É;	“õ1ݾ4DZÉ-”P€
+†l0\ƒ¡ë[ÜíWâÝv~q/Q·ƒQMo{KÝ6Ú܂Ǥ=’Î?é-|¢æ·I—i:`zšy&Ù6mΠïØpåê#\mª§pÕ`z²Úy^%YGß·øI&ÏË2`ân¾i²qÇq‘;Ö“4•kð†IÃÏö]uK›ªò}‹Ÿ4—n²¬æTËŠj?Ž±òÈÅE®n¨&©\»¤ê*yøÕÞæÕ?nZzóöÈÃÛм¿ÖciŽcÐEiŸkTˆ&9Qm.œè–k[u‡ŸgsK›$ËVµ“ë[ü¤Ý?6Ûh;oÓéMÚ$nÚ$mgÚæIÛÉÔÚív;îÃü£ã“Vö_X\Ò~µuaqIf×­5ž§í:øz[çë9yš?Ø?yc’)Y®K«ÕŠý†ipš¡T°õz£ ]>eà–<~R€ê¨|ÇÊ‹á
+€€  *olbŠ€ *X (/Ÿ"h4´, ÖõùŒ+ x
+XnN ÏDÓ ž° @À   `€€-5à<`‹,e¨û– ‚…ŒO
+T `Ç&¦zÿ©ß6[ ›,+êñp¥÷{Ôº©*E“uµi§¨y†WmîùT»€;™ÜÑ ê–ÅQwÅžüQÓ‡+2“;¾Æ-+É-¦ãæ“äþöIÚÉv©fl^ØÞ=Ö6ÜLÃU²Yt·-¼1@Àz	×ËÓU“á[mn at yTö"—ªR‡b’·èQóKú¾ûBUÛF,ã
+6x‚.ïß;2áðÒ…’‹ªÎdlÞZ'};®j#ÓuTµ©ÍzS%Ù¨µÛív܃£ã“™
+A˜¦Rí
+ø¶°¸$­VKæwÎM3’‡“Üe¥
+ ¥î"°}ëÚ(#¾É ,,.° àC«Õ"`À‡f³é¾vaq‰–àL½^/ìÍT½\äjµZ R‹û8Te¶[¨¶4•ç¦-Û
+¿ý# |Ÿ´~N£Ñ(Ŷ° r]ÉŸ" €ªl­V«Ä2‹ÊW[±@À&8QŠtâÔj5åúwÿüOµ}ªùÄM«ú{ÑÂ×t²
+ê$Ë)ò1ŒáÉú„k·Û¥h¸îvøئàüÊÔfyÚoÞGU%™
+6A¸FUjQ• ª¢óõüàz¶Ûm'Kp>ICÓv;T•uÜïiÚ3j‡Û/®Ômƒéöƽ[0Ù^—ó Ú5Ѳ<tÄ0õ{F„áOgú|ÕtáÇ‹R}™lG’mKÚž>¶/é~×=·½.æa².Ó2ê6Ô‹\ªWy›PHû|ÛêÓE«[¿àv…»âú…M¶­;O›íÉېÏêÊ3ې-û™™ôÁª‚%퉛æùÁŠ,o!µ.Qa«ÚŽao›ê­´«õðµ=ª6F¶ÝT°)B6m5éúù¦'«Ë*6«PŽêKî>fZM»èÎðð„ *_ÁFäQ}V&'Q8 tÏWM§zÌE˜n—‹(Óm³¿i{ºÚŽàãqëlsÜÄÍWÕgj³n¶ëÖ{e>@m¦·­ÚlK².I¦Iº^i·M·®®ÚΤšÖ=Ïåqcò{ÒuK{£¼ØÇWeÀ‡ÑñI{¡Ò ü*ËÈXI*X€7eÓ5
+/;¿s®²Ã“èÏÖ¡z½ÎQ >–Ê :ø ° @À X  `€€ ° @À   `€€  @À  , €€  X   , °   X  ` , ° @À X  `€€ ° @À  Ðú›|­±ÞyJ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_002.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_002.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_error_002.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,41 @@
+‰PNG
+
+   
+IHDR  î   r   •Ä2Ú   sRGB ®Îé   bKGD ÿ ÿ ÿ ½§“   	pHYs     šœ   tIMEØ8¨­p  IDATxÚíÝy”TåÆñï­êªê½Ù	ˆ„Å€@ÜÅŒŠ'£‰G'“dÆd有q!FcŒ{ÔÄcrr23&Nrmµƒ!ÑxH¢pCÁA@(4ÐûRUóGUuWU×r×êºÝÏçœ>]˽·î}ß÷¾¿û¾wyÍ×Å_0âñ¸·ˆˆˆÜtÓMT¼öÊz¥„ˆˆˆOT Ì?ÿimp00Ò^÷¿ø0Œ¯ûf7ò¼NL›ûurêþ…¦½#íMæëþî{]l=snoÖ¶[Ïœ¯³¶·Øzö/:ÿ¶[OÓyä0_ræ‘Å|ªé[l=ͤu±õ´º½vË}ú6ÚÍ—Œ<²™/éÛë°n²—¾9ÒÚJ]˜/­ó–ÿ¦¯êþÂu“æ†ß  cŸµ¸EDDÄ×`{ÞÅ‹óïw4)p‹ˆˆ”’ëÉ›ÖÍ÷ûÏ¿ïõ!ó¯q¼¼ÏÜÜ÷zÚÉ׳ý/7õ½Ÿ~êe›÷- ŽZv§íelxô
+ 柷B{™ˆH™ÊÜm[@íŒKLØòæý Ô~)ßø! 
+G\ZA{âqßÆ0`÷†ÄûIÇçàï>wë€Ï¦,¼€ÏÜÀÔ“®vü5ħrðv2ˆæR ý×øìÓKn/:ß««¯àÈ¥w¨‹ˆøÌìy ؼq©Ï³å¼8­õ­eí-÷g¼¯?âÒAÚv¤‚öä¿Ë'“ ;Ÿ½ÅÔüÓO½ÑµV÷O&‚ö¬3ocÖ™·ñé%·ðÚ®Q©ÂR9¨­í-îìà];óZ¶ühÀwÙ-îý¯ß—ñýÈÙ—Ó¼9ÑÝ:jÎìÛt/£ç,`ï«÷dL;öÈoö½Þ³ñ®ŒïƝèþýû‹™-Ë	Ç^= å}Èüo÷½o}¢Õ:iÁwl%êŽgnfêÉ×÷½ßþ—›˜~Ê
+¼ýç3ZÜÛÖސ1ߌʼnú[O_Ÿñùá§ÏzÆ®Ið9ŸMô"lz"±}sÏþAß4¯¬¾
+€yçly¿¼êÊŒ÷Çœ{wßëš–g|wÜ?Ý›sÖ7^À‚óïÓž&"ârðž=oAFð6´sîš_§í­D—yk2h×ÍüÆ€VwʁdÐ1ë²÷òìÛÔRA{ÌÜå`|üÊÝ|ôÊÝŒw%%ƒö¸£®$ýþ½_J¥OsU_ÿà…dïTWyJ¢«ÜÈX+R]å)©®òtÛÖ&‚÷§Ý”q/_*hÏ<í0`ËŸ®ãͧ¾k+xsäÒ;rnæˏ'‚öÑÿHÓ—V]É‹ÿ÷MŽ9÷n^lJ(û¹D^¼ðØržôŠÁ{ý#—püù÷ahñ,x[	Úy[ܵ3.éë.¯›y	8¨ºGÍI\ðd˜\Æž—ïÊhmûÕ–§¯óíºoHÚ""âì®rÛ-îôàí ÑjYz«;ÑÒ¾Ó×Á;Õâ÷Ÿž#""C#h§Ÿï6¼ËêÉiãæ]™ì*—Á”º,uŽ[DD¼ÚÙÜv‹Û¬†Y—qàõû2.P9ûòœÓŽž»œ½¯ÞÃÇi¨=ò›`­mèï*ôU|øÒ¨e_œ–rÈükؽáö¼§M>áZÞ}îVÞý[æùæÔí`V¶èF¶­½‘­i¨ÍX|33N»™·ž¾~@Wyö9î#θ•7ž¼–×ÿ˜¹ŽŸ^r;†³ÏºÍk®aÓï¿=à·ç.ý¯®¾:ïÅiG-»‹—¿’—Ò.PK]œvÌ?&Îs¿ðXÿj¹.N;þ¼¬ärÖ7^¦‹ÓDD\”¯Um¶«Üؼq]\ƒŒhÓù’34Ȉ)²½d$Ïþ‡uÿ…Ç5Ø~rÚÚµkûy:7ü&MkôÈS¯å{|©
+Ü"""Z¼x±«ËSàñPöè^Ni<n© ØÐø%¥„ˆˆ%ñ"ïE¼¡·ˆˆˆ·ˆˆˆ(p‹ˆˆ(p‹ˆˆˆ·ˆˆˆ(p‹ˆˆ(p‹ˆˆˆ·ˆˆˆ(p‹ˆˆ(p‹ˆˆˆ·ˆˆˆ(p‹ˆˆ(p‹ˆˆˆ·ˆˆˆ(p‹ˆˆ(p‹fÏ[`ésq–®ÙÓØMçrÊŸBe¨Øz–sùjû€“ò6ÜÓNì«Ô£†@;µu9xàIJØ7o\Wô³Á\)Mš•k¾û©Lä
+2N×=µÌôå¤VêôÉþ½byçvz”KÞÇzj°÷ÅAÜ¡È.›q1@­-óx덻ˆDBŠ>2¬
+•J0µ¥¬àÊ=í†BÞªA1Œ[܆ÑËÄIŸ§§"•P[·ž^¾Ì“OÜÆ9gOñÕfúwf>7û}®†•yòÍgf=ÍQjmä[f®é³ÿ›i©˜Iw;ëR¬ug'ïÒ[ƒfÓ¾PÅhµLXI¿\yaf[ìOVö™ì–uúÿbeÐʶÛ'Ì”7³ieg?rc?Î÷“ü6S¦ìÖfê+éVh?2[WX©kÜ>à”À=jÌtt@õˆ p°™ùó·óý;VÒÒz>~áSe}´œž	V?·ÒÅfužBÓ
+šV×ßnEdõ(>ײ¬l§“í0Û]]h™¹v~§iì¤\™I¿|¯½Þ—ì”'å©Ø¤ýªX°ËU±:¨°R'8ÝïÍ–íô g%ÀY­ÌÌo7¯ÜÚÍî{^ìG%܁@+ÁÀ*Œ8Á1ÀIŒ¾µüo,]6‹“ŽgÒ!õ¾é:*å|å²þfZË^v!š]o/Ò9×2í´T³äûíÁ¼ÎÃlzØ-sv>½8`qc{¼(Kf–c¦Åœoúb­o·ê‡rÞ§|¸G4<@O7ÔÕ‚0€õ`Œ¡§½…Nüˆlå×Mäª+ŽóEF™)xå\ýz¾ÊÌz;É«¿m§[Ñ‹us3ýìvÿú¹,–z›»r3œ¦•ßϝ—rýK~;X0°’Š D"@ð&¡"˜øþ[—?Cãc»øøãv†¿¶¾ãJ^¿´\‡RùËwþ¿œÖÉÏ•pö¹ú¡P/š×L½á÷ýÊëõ/i‹{TÃ
+b½P]ášj è Z1"ã m‹Nÿ;§ž¸_®|›+¾1§¤GKVos(´³ê:Íwž(ß4›7®³<Oö4…ί¹YYå[¦Š)ß<f×ÛìüÅÒÞÎoÛÝ67ÒÚ­ôóâÂ4»Ûâö²
+«µ»Ÿ*7¹*óì –þÞJzX-KNÊE¾:ÒiþÙ™?×<NÖÃJ½e§~v“±yãºxiBc”q£N&‹1nlªGïÜϳŽsÒ’J`tm‡HœÕM‡òåÿø
+¿:•±ckwŽèý²\ñý 4ðFcÓšÒu•¨{€ÞÎ5a º†ß¬Œ¨ŠqòY1#Æ{»€È(¢`é9»˜3k+?¶]{•ˆˆ*õ§ƒoÿ)Y‹{lÝ`ìè 4ŒÀ0Z€ Õ̤ƒ/.‹òËUû¡õ]ˆÀãNáË_ÿ«›N£¾®R9%""Ã^ÉZÜ#k~J´ÂA ¡†Ä¹í †zÆ £hmŽP;²¥;™7{+=²S9%""’T’ÀŠþ–€Õ•A t0¢:T¥ˆqè„`PP_ýâ‹<üÈ»léTN™à·Á'¼ü]
+ÈPžéæçx4@ŠÒnØî†Ê•ôt·S„P}
+āúìÓÃÀ(ª*k™³à„@è†Ú±ô.x‹1£wòø;}[°ÊáÖ™RWééë§@­í®iœ+HæÚGJ¹m©«¡‹ý~¾ýÚÏ+~ßÏo÷þ˜x "Õ
+ÁÁýÐ }¾_¯Š1aÂdÂá8å”æD:û r —õ9¾sÛ4Î;w••aÏÖÓÏh”Óº»ñp‘áF¤”î`e(ð4pׇWÒÓÙKU"UUÐÓ
+Q¨ƒIâ@>9‹Öï3inZ€ÞV¨ì‚úÑ°w/-{ƒû¶ßý~çîð’dj¡ûñœ8bå!ùNð0³.VÖÇ‹´µ;h‚™ÜZ¶“A]¬.Ëi¹2ó¼q«iZ¬\ÙÝf;eÐî -vòÊ­2•+øi€ëë\hz3Ë·Ú»RªRÊ6p‡z~AW	BkÄ€V8r6Ì`Â!‡Ó3âÁĵj½$þ·í‡šô|¸—ðH¸ø‚—¸ûÁ©œ}ÖaTWyÛI`÷áòV"(¶,«¿me:7?±º:r·š–f·Ù鲝ãÖ²ì–+«•¬•g”;Ýf»e°Ðï˜y×`”)·ê
+2´H)ÛÀ]ZM´­™Pªj#BwOâ³`<5§›Ÿüê/<tß{‰kÖ¢@hi‡šTTWÒõq'ÿyÑ«Üû³ãùÓÓo³léÌ!Õ¥Rè©<VÄof¹^ÎçE+Ý«å[`£”Ër#Oìå»5°ˆ×yïÕ~ëe™*´o{±Ž Åüvøy€Ïwut½T…!XU	‰Ö¶‘Îq8öø8¿yj‡º?ñY,ù×ݝ#Gc4ï†0,ÿ·uÜóà$–~v€áY -å Vƒ²Ùé5ø‰;˶s¤íÅö”:OûôN‚ï`
+¢RJSz•~ Å“«Êë+VÓÓÙB( ÕµÐÑ•hQ÷&[Ö-pâ¼f"¼ÃäI½Ðžü<–œ¦ù „«ׄ¡þåœMD‚ïð‡'w‹±ðH߉†ê@ƒ1<¨­ïBϽvRþÊ¡b÷[ Õ )ø®Ü˜·\Hñ¤Å]Õó_Dã	A°¶Ú;¡7ù€6ƒ¾óÜGÏî`܈NF%
+Ku•´wAgŒOÏÖ]ÔŽ¯ÿ2üv*gž>…`0ày†[ÙÌ®av§•©—ƒŸX-ô¹ºšŠ-Ûé€n,ÛÎ@nn“råvšš½ðÑìïyQÀSª2å$¿ÍL£Rü3@ŠS®?ò´>°ŠpÛm„‚0rl-FCš›!–¸“X!kŸÅ¢3÷õ_˜Oöô Õa8t:ì~—èÁ6‚8✯òµ‹?Ã’Ó§""¥oÉèö>Qy<MkÜoqW¶ÝI4ÕUŒºJhkËlm“Ì5‰÷‹¾°/ÑMLÜ©sámÝв&LÄØ¿BpÕWžåÖŸOæŒÓ¦xz®[DDÊ3X—²u[Ž\ío®cݝ=„ˆÔTBoÚ;ú/:‹%s-lx*Œ1z$FM„ÃçN!º—Ä•åqúÏuÇ€={ šj8 œñՁwhzb‹J°H‰©µ-åPÓŸú¦ÀíPUçÿ0 £2œlmÓî:–œ0ÿ|E
+ÐŒbË£¸îûS¡Ì Ð…½ÍÐ0’î.¨
+,ÙÄC»è鉪‹ˆˆ·•l¢§m7Aj*#‰hÝ՝¬ûþ:aÛ-ÀhŽšx“kN¦"tRf€O¿=ìÀV‡‰î…KÏÛÀ‡~Ä_ŸÝ©t¨”ƒèùÚ""e¸«{þH´q“]ä‰[Ái†Xvâ ‚÷?
+ðàÊ,\x0ñ¬rƒþiSóööÂþf‚qƒ®n¨Ÿ9n'+}[Á³ÄØîº
+V×–ÝÓDDÊ•k§Å:_¦7
+ÝÝpp”P0N£ÿÐ –8LPÙ	«~þw¾·b*­-´í>…sþ•î÷!KÞ–œž8Ä1¶Òݱ(T÷±‡ïæÑŸNçííÍLŸ6rØg¤Î=*]DDÛ’xÅ::·ÑÛ]ÝqŒ8ôß”ÕÌ@E®þ׌´µÃ®÷ ƒxŽùâÉFx°j+^xæ•ÉÔTÆØôÚn×·Ù{#‹
+xPl †ì–hú<naõ~ÆbÛ_ìÑf¥ÛW(ÍÍ,3ßzš]·bó»5½6D¤$û@Õ%ԍÜB×ÁçÙ{ @ Oô›Ç²£v¢5m°çcÀ€xrš¸‘Ö:O›ÓW† »;À>–§žŸÆÈúvêk+]ÚvП/°¹9xˆ•‡ÖÛl¡ØoZiÕZ`ÀÊö9Ms§ƒ^x1H‚Ó´nGZFÝφíÛøŸÿþío³ÎÕ7
+N]ˆÒÝ[ÁŽ÷GR_ÓÁ1óƱpáÐ|‹“‡Ö{Qñ{9DÕí³šf^/g¨_£ "C8pÌ?ö0&OžÈ¦Í{’צ™19žŸãYß‘ç}<m†x”êšÇu¡PpHfŒ“gL§‚áÒr¬Á
+Üú]µ°EdÐ7À'ÆUó‰Ó¦(u=
+Jf­8·¯iïæoªÛ\DJ¸ýÚÂ;@ÈÉÃãÍ<ð?×o{ñ»fz)”ïÅoÙ=PqšöNIpšß"2ü¸>Ȉ¨•$""ÞhlZãÍxÜ"""â
+n¨µ-""
+Ü"""¢À-""¢À-"""
+Ü"""
+Ü"""¢À-"""
+Ü"""
+Ü"""¢À-""".Ó #"Îãlë	‚"jq‹øR<V‹-R¦‹¨Å-âo¯½²~XlgcÓe¶ˆZÜ"""¢À-""¢À-"""
+Ü"""¢À-2TÌž· ï/ûóBïEÄtU¹ÈÚé÷Lg¿/ö¹ˆ¨Å-"ƒ´!ñà“\-mmnñipnQà§ru‹ˆ·ˆ”IP6{Þ[DüIW•‹±àï|vj:ïQà‘2Þf>WÐñ?u•‹ˆˆ(p‹ˆˆˆ·ˆˆˆ·ˆˆˆø….N)Æ¦5JQàñƒÅ‹+DD[Ä/Ö®]«Dn?Ð}Ó"â6]œ&""¢À-"""
+Ü"""
+Ü"""⺿TDDÄG[·ªˆˆˆøÇÿBLú'
+íŽ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_hook_life.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_hook_life.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_hook_life.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,122 @@
+‰PNG
+
+   
+IHDR     ¾   ¡û¬¯   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœíÝwxUÅÖÇñïJ½#EŠ"‚("6^,Ø+*Þ+b¯\¯½]¯]ÀÞûµ쀈]»"Š‚‚(Eé%zM÷Ùñœ„@zö9Éïó<y²ËÌìu!gefölsÎ!R›˜Y -ì8$®mvÎ-;‘ª’v "áhô
+;‰KãUa!R¥”H-Õ88ì $.Í@ɁÔt	a """±EɁˆˆˆ¢ä@DDD
+Qr """…(9¨ 3ÛÞÌŽˆÚonfÇEí'šÙñEêô3³ãͬu°ßÀÌzT_Ô[2³Fa^_DDb‡’ƒŠ;xÝÌ:ûW ÏF?xÒÌ 0³ànü"˜Ù@à¢jŠwf–¼ÖõED$¶èVÆÊ18ÓÌî:ó¢Î
+œ
+œŒ
+Ž­tνmf3!ø§1³cS€Dàvà8 =Üð P?¨ò2°èîœ{ÆÌŽš8熙Ùe@Àƒ€Àà ­qÀF »™=Üéœ[^Ñ7DDDâ—z*ÇTü‡ïáÀͬ)îœ´2³zÁ©íÍì6ü‡û+[i³.°Á9wŠÿ@¿	˜œ ŒÎoê éA¹‚úõ̬#°SPw>á8ø
+¸Ø9÷ð0Å9w¥QrPyÆwá{
+œ´7³á@;àäàx&ðpŒsîým´9!ø¾Ð¸ØXìÿœ/øžïi H	¾ïÔ¹2Ø^¼do›Ù¹ez•""Rã)9¨<¯7;çÖF ìçœ;ø?ü_í ›œs3sy%´™|?ôð0ø?”Ñè”›`fm¢®5?ñ2ð¾—£=0¸8
+ØÔ1³vfV\ˆˆH-¥ä â~&8çÖ8çFÇž†žqÎm pέÃ')øùhø®ýhSIAÝåÀ€Àå@‚sî{`$p	ÁP†sn%ðpððspý‹ð½ÿ
+®_0Dqð矾5((£»ÊåÑ£azÝê½æÈaè~{fxô˜ê½¾ˆÔT¦§2Æ¿àŽ‡åιwÂŽ¥ª=sÓ+¡­Ð1­ro¹nì{,ücN%6Z‚»/„͝áÖ«áýv0îS¸·Kõ]¿¶z
+˜£§2J¦žƒšaðYØAT¥`¦›™-4³‘fÖß̇—HM`f—™YߨýÌ줨ýÃÌį̀ýÿ3³GÌìV3ëû‡™µ«ÞÈ#Ìl'3kÖõkÝÊX8çÖ„Cupν¬1·FŽ™-FáçeüìœËßV¥wÓ0hùd„üfÐ`8\ù¤í?0 V\l†æO®{Û͐6ÖíÙûÀÞ'ÁI!wBÝßaÍQ»¤üýn„žká½ö0á¸ãÌHùÁ@«wáÂï*çuŠ ÐX|‰^|¼œÿ/df#œsÙÀnø‰Ð£—Íì,à `0¿ Q3k	¬:8çþz [:çG•iä )ι3k†¿Ý;ßÌZôÐÿ÷[;çFÕí€ÿ›¿e|™vÎ-­Ü·§öQρÄçÜ›ø»>rñs'º ן +Íl´™üRª€¼Îñoèr+ôü¬9Ft÷çžß–ß­o‡C΂ÕG€KÔÍi+¯„¦ÀéÂ>‹¶~Üö°â*h=ö?òëûwús›Ò w§"å;BVý-Û©°If¶>QUpÐ̺à?ôßÁ¯·R`£sî/`:Ðv+m¾Œ‡9ÀÌúà'EÿËÌîÚ܉¿ÓëˠΣDæ>
+5³3Û¿¸Ü¹fö¿ î£A¬€ín@/à€r¿ò7õT#33ü_	Eö·õUÚ²a¶Y×~ø7†¿}³Ið6äšÙ&üºwß;çrJüG*¤Éëpæï~{Ú×°è `2,<R¿†Ë‚¡œŒ'`ʱ…릌ƒ+?*ÝuÒ¾†‹¿öÛKŸ€™Ã!ãê²Å*Ra¯âï`j‹_ƒåœàø¹ÀPàüDç‚ÄáB3;X|‡ÿ .Ê€ÛœssÍl~âõFàŠ`Xð$àè ìÌmÄvð°ØÏ̶Zá'n¿íœË4³ï€ÙιËúÂeKq™˜ÙnøäŠ~ø”鲕º+á+¿e*òU“ÚoÈÖÿM’ð=uÖ@süQeL¶›ÙN\9Íýv^¨3!rî¨?`J‘ጺ“Kô¨ëì7f&Âäfe‹U¤Âm€¹@€™%Y`ׂg O;ç†TöûlÁ9çæÛ
+ðk´ln²ñw^¹ þæ \>é‡HÒߟ¬îÁ¯{~xñ
+3»ÿ{¡2~Oqšàé/ÄßzWæ'§[4âZ~ƒ_9²À:ü‡ÿrü-žï¿TÍ¿uÒRØ´kdÿ£]Ørˆ®¤5,¢lŒjkìn¾îžËafLj‹R M6d$Cnç
+.R’‹ðÚw½¼ãœ»	ü¤Cà,ü‡|Y=œˆï=è‚_Nþk3ŒÿÝ\p+ð7À
+f6¿€øõ]ÎÞ:¿ào㞉¿<ë÷¥f¶É9W0D!å¯É@nm™ˆ'Abð~¹èLüÂøUÇ8ç2«>Šv£`ÆËðH_Øa
+̺”È‚Uåu <v$´ùæ_éïC³\h¶>ü^9º}“ϤpB$RY.ÇÿN]
+<÷å|’ûCT¹ñÿ÷Š&ޏá?¨£][°áœ{×̾Á?¬îóऻ‚ù9@ï ÜËf6#¸ö¡Á$ã/Ílp0Î9·Ö̾:㟛Ä=ßS(ÏɁÔ2fÖ
+ø
+ÿh~‚ԏ•w‡B´äŸ¡ÞÆÈ~úBÈYç·Ï
+†e—À²,hù,,OºA·hêLH/úKr>ËO„%;CÊÏpòàȹÎ7Â_ÿ‚ñ'@Ãaà†Cà¯¶´Åà‚-ëm†äŸÊÿz¥6sÎM.²¿žÈ²ìÑdzñÏe)®YÅ›Rdþ¯ÿècÌleÔ±‹ikþÿ|tÛEÛ_„Ÿ!—‹ ™Y/àzç\¿°c‘êÜÆt,0Ñ9·¤‚mUÁ"HåuókÐømøÏÛ%—•Ø E¤æSρą w èÓqâù½!¿˜gVtÿ£úc)™’‘R™Ÿ
+¯7>YrÙ¢–
+ùÅÌh¸v¹Úè1Ù"S”ˆ”Jf*¬¹(GrpË=•ŽˆHÒ
+‰"""Rˆ’)DÃ
+""!	žepwØqH•™èœ»9ì ÊCɁˆHxZëÂD*]ü
+“qIɁˆHxeι¯ÃD*W𬉸M4ç@D$<‰”é9"ÕCɁˆHx’Pr 1HɁˆHxñ‰)JDD£a‰IJDj¬ñá†¯"ûƒ…'û„C=“”ˆÔXY‰·Cd?¯
+äÔ
+/)†z$&éVF‘˜6¦,l
+À/Aê*ø¤çûóÏö‚]gBï•~ÿ£6°¬œ;)´¥,4!Qb’zDªÅ¢xäXø²EÙêMÝf=Ÿ½vEwÀ]OGÎϽ~ëÙŸv üuiåÄ,Õ@Ã
+“Ôs R-ÚdCÚjó|þ$Ï„6£àÔ	P¿„¿ó:BŸÞpì"˜~?¼4É÷\0¾zb—*¤a‰IJDJÍ¥Á»*ÖFòDÈé¹=`Ö?àŽ°
+‡#GAu[ÖIœë€® y¬è(9ˆJ$&)9)•6› ÙŠ·³¾q°áÀÖCÂJß‹Ðáûâ —Xd?	Ì;¹—9—[¯â1J5Ò°‚Ä$%"¥Ò2®}­bmÜw&d÷€Ô¯¡Ñ'Ð÷3è¼±äzùÛû ß\˜\rö„fús©“aUà¿¿þpHØJ’!1H%&)9©ÉÐñ{¸öÕ²×Mü~|&O€ÍGBÚhø“?×j4Ì~
+í¹!ayåÆ-ULÃ
+“”ˆT‹–9Ðvùê&.c.…	ûBê‡0ðûȹÆÔà«¡í#Ðx=,†.º­†?DÊv2Êÿ¤
+hXAb’’‘¸Ð{%ô]ü¹îë¡ûÇQ–ùoÍrßÑpÆ´*OÊK=“´ÎHL«“	)E>Ô¿k
+7Œ	'©dI¨ç@bzDbÚ…ßß>–“ ®Y(áHeK²ÂB¤(õˆˆ„GÃ
+“”ˆˆ„G%&)9	z$&)9	A’˜¤ä@D$<V¨!ÌìX3kXB™þf7(9	†jŽLà³­%f68Õ9É ’‘ð¨ç æ˜ t~0³FÑ'‚Äà9`+™Å%""áQÏA
+áœË¾ v~ êÃ߉Á#øg%"R<½?|¶ßÙ	^ên<Ñ^î#:‡E	4!±f	l v žÚヺÀBçÜÂc+%"Ró¯é»ûí?„9§Wíõn½>i]º²sNYÇTm<¦a…šeþß4ØèŒOòwBŒ«ÌâbÖ¤ˆÄƒŸ¨úkl:V½,®úkU
++Ô Î¹f6èJáÏ×µÀ»áDU>JD¤žÞæÝ®.4QøÜ'Ãæ6póЙO‚Íûƒk ‰³áò3ü£«oÍ^‡Ìs ¯
+Ôù .¿å˜V0önÈíæÛLýN=ÖÁ­C ¿Ly
+~Ë‚–ÀŸÀÐ=`ö!§$¬ÀUïùúùi0øÈÚÒ¿€ÞÿƒÃ—VãV%5ÏHà 9êX20.œpÊGÃ
+"µÎüT¸m~^Ø6•ò÷Àç-aÎóÐä%èw<ä6†ÜÝ"ç³›CNÐåÿò	Óœ ƒ÷ÎwAªóçr;Ãò ë-°Ë@ØÔžèÏ¥äÁU½¡WÈkï_éÏ]r$,‡®—Ã…'ÀyŸÁ‡maÆ0¨û-œpq24Ÿ‰iýÐäèÛòÂø³*ôÖU>
++Ô<àçDû!^na, ž‘¸5?µüuzÞ}	f¾·-‚ÄyPwôz^^|Ÿ†Ä9ðßá~¿Éƒðü9[¹€A~ø¹3ì<	Îþµðé†oÂSýö½oÀêS€§ýµÈ„·:ân26ïãË5Ë$ç@»àI†¿þÿ‚žŽj<*þ”ïáŠ`†ø”·`áuÀ}¥xƒª‹&$Ö<?Søï
+À°b)·xMþ;‘p$8Èo ÿû½‚
+y;ø¯ìƒaôµðíp8á>ß•-»$O‹ìwÞè“Šâœñm ³€[ë@ý×à¦Ç#ç›ÎˆÚþV¶ôÛ_5‡1ïBÊ$H™ã‡\ý­¿„œÖúËÖϧEÅÛ`¹–ˆ)V¨aœsÎÌ>þYpˆ8º…±@\&ιlñŒ{‘Ú¢O&ôÙ©bmÌJ‡ß‚¼°’æA£OáÐ1[&R–ÂÆC#ûSëB^ûâ˶́ë_^„7ºÂ¯¯ÃÐïàÜIþüŠnÀO~;swHæŒ;ËÏ
+<Èïß}!dõŽj8ò#»Éa}ß²½ö˜¢a…ši$p4PÈtÎ-	9ž2‹Ëä@D*b~*»
+R'B§kàô饫×ëcøøz¸÷lØów)þ¯¢b<q04YGÏ‚Ä<°hÕÝ¿¦?ù‰°æ4ht»¦,‡5ûÀ7Í`j7XûÏÂí¦N„9ÇÛÙÐy)ì9
+¾ºî¼ö›“aEÓ-‡1b–zj¦Oñÿ¶r,å¢ä@¤Öi—·ÜUöz}2aæ¹0÷zøâTh8
+uVúóiñ÷sY
+á÷Ëá×æ<ZÞ	}£€iö,̾òZAݏáŠüñcGÁ¨vðÉpß›ÑænXvB¤ÞnÃô“aÊ­°ìy¸ôKXÞþ¸>ïïïVhù8ð+¤ÍäU‘ºõ6BòÏeÝU*	õÔ8ιUf¶hGœÝÂXÀœÛJâ/RC™Y蘅J-uÝ$Øã8台#)Ÿ§€9›sË*Ú’™}Üàœû¾âqI,1³³€Tç\Üõ©ç@D$<V¨¹^ÚÅcb dfÉ%“J”¯?,"•£ó@è¹ øsãC—u~A¤ZAk®oðãRÔk	Ý5¶°M®ÈWÁ1+î¸+\‡¨ïYÀ¢,`EUG,»ÎßƸÿûÃ`ÖÕpÆ´­—©QÔsPC9?fÿqØq”W4uÐ/±ä¢µÝßI€+’,Ý·bŽåV'|‰EZIb’–O®8Ûr7Áüw‹:m[‘ÚNÃ
+“4!±Ô,zcÃ0®˜Ó†ïQPr "…hXAb’z*G1½ÇÔc "[¥ä@bRŒ&/ïÏD-™úl/ÿXÖ°ýýA_dØ èl™”Ðá "µ‘†$&Åè°Â¼ãýã^	Yp$-&UÞ5†uYÇÃ-åxB[±ôE%à
+'""Ó„ÄR0KIRÂŽ£6‰Ñä ¨=î…”œÊmsy{ÿ¬÷r?¾ÕÀJ˜{`QÛPx¸ADD=¥Ó°ô©õ¤–ø(?ääàéýaeÈO…úÓáø/¡ãæ-Ëe¶„ä, jmö1­à×ÃýcdëÌ‚³>ž÷Œm
+?翯
+kwƒ:³á¢÷ =ß?vUo ìïë´˜g–â¸ÑŸíeí=P^ "…hÎA©u‡D-ñµiÎA®Á Çá¯×aПËÎ…O{_~Á90ÿÄÈþ³½àËOaՐۖÝ½íŸ6ðǐñ <ô,½²w„¥À}·úó+ëCÎàaÝþkuër¼rÌ=ù›’‰I!õ<z"l>ºö‹<ß|ÒP’Ì$˜sÔy'òÌ÷ŒÁðððú9pÃ3‘²Éóà¶Kýö}§Cæmqüó/Xô,Ú†ÜXöøËÝ{ ,AD¢iXAbRHÉÁšC iZáÄ  ©Óù?ßòÚCÝ©¾áïºS`ãž…Ëvy'²ÝyœO,~hýæ–;ô-•aîÄì
+""MH”˜Rr×R~)_Ý•­ü÷ÕÇÃê"ÿ©’çÞ?jNd»ÅZÿ=«’f¼–§÷@"5™­®@õ(9Rr´²z—\®8MÃ\`»àÒ/˃åSyÆ—±÷@DªÆ”zÐ}}5_t»ŠTvÎ3	[$\!õq7ûòv€ÇŽŒÌ3Ø” sÒJ®{Ìl?$±ô\˜\?r<3	>oYú:ÿ®>|Ù¢l±G+:ùp‹“[ß‘*ðÕþpÃr§_8mS•ÿŽsÎm®ÈWUÇ'R!õ\ö)Üö,|n™IÓ!§;t¼þýý¶ëÖσ—ägàIðÖ8<w7hô?8ìÅÒÅpäû5Œù>›†Ãu/UàE•¢÷@DJ–ц¦–¯nƒXû¬?fô‡[—Cb¤M€ƒž…ô¸tنǏ€Aö.°Ž†ÿ/|~y??4žü'ìû½ØŸ¹#ü~t/|{)dï­‡eÇÂ	·Aϵ‘v†îóÀ•7C£\§Ý«Á¦=¨;.zÞŸxàdpIPo!,9	\Ü~AU¾!®s0è9æw÷/ºù“púoþÜî¯À¦¨^„]‚ÔìÈþÉÂ~GÁ{úö¸	ZÝ
+§Îðç÷šù|"Q óZè4 ö\9vÇÙðKø¥´\R¾×QÖ¹"²uÉÓaÅYP¡Ïð \*¸¶ßr»Á˜.°äÿûC¤¨a]`áãÐäNhõ!¬ß6·œ¿ç<XuÔy•}áëÑPçPè“	«šÃ¦þðYWH™Í_„3aÁƒðùdèùZ¤­9çúøF¹°.ž®4|,VŸ
+í·]â˯ß²zÁÊ\hø¤/®êw#äEúÏfmyü„y…÷ÌܲL›l¸p0nËs=ÖAñ…5Ë…ÆoY¶çZèùSi#.AT2P\" ä@dÛn½ªbõç§ÂÓï!i¤Ì€vo©“ýh"[3ûhHš×½²å¹ÉõaÕ5ÐøA¸þ…àà{pÃ×ðí@èsO¤l£pmT?¿«O‚ä`J=È:Ú^æ÷Ÿíç{¾è
+‡eøc/M†iïÁðÇà”?ü±¼¶pROا"`K-N–OŽuÅ}è»è“S©o
+‡Á~ÁþB2èð)L¹n
+>†>€Þ+ý¹Ÿ;ƒ«٭ᎨÖÖBvçÂítýªðþN#aÒ@ÙÉÿA<¦/Ø85˜P¿¾$dÀøÓ Ðٰ߯´3$É“«+1 Ýt_¬ðfq«&ŠHÕ¸úÿ—Ÿ)«3¦Âѽ!}<¬>ÞwÝonà¿'l„„¬ÈW½O ñ{…Û9nAáýSg@Òï~ø^„:ïD–ûÏk–U¸Ý„,hô04êYO*r«~ÕRÏA¥QH|;x9ü0𰟸ü˜ø
+´™ó€ôùðŸ‘eo·á›°ê5rö†]oŽœK™YG@ßWB¸
+w«ÔsP5¶Ñ{ "â™iIõØñÄÁðQ¿½)òÒÁ–A‡
+~UÝÔ1ùox²¬þ°~mxy÷’Ûîó>ä7_ð½“çz½äÂÛƒü Éðè10³Ne¾Â²PÏA¥*±÷`+eD¤¶0³ÆÀáÀ±ÀDàñp#oe/˜÷,|»H€Ä¹ÐîæH÷ÿ‰×À{C`îKp÷F ÉÏhs]Ém÷Z›¦ƒ
+Ÿ;,œ	3ï…	_ÂÄ•àBҐóM¥¾Ä20hÕ$†@ÍS0!ÚÎEmk€Ñ›œ[‘Jh€™µ€ŽipQØ¡H\z
+˜³Ù9·¬4¥ƒÞ=€¾@ þ³‡sWWY˜5ˆYófð¯:UÿÈæE)0±´Y
+{­Ùz™ñm¡Þ&80£rï‚ù©Ìk
+íWTçäÃ-=‘—ë7«áÅP#mëg%K+¢‰ÔpQ½ýƒï é@
+°xÔ9wMHáÉVµÉ†6óJ.óÏ¿ªæúû¬7)ˆHrníª°ƒ‰gÅôìäà¬mð?çÜõÕ¡HÙh΁ˆÔpÏô†Ì½á¦G+»e3Û¸8(ž-˜X”^¤x	ô0³O¢ŽOwÎUpñ'‘Ê¥ä@Dj¸Í k§ªhÙ97ÎÌrµÀAÀöøƒº[©RxŽÈúÐ;ÿ®ŠØD*BɁˆH8ç~~0³ÀaÀ?€£ñ½	©@Z°ÝxØÇ9·ØÌ–‡·È¶Äer`fizÔ©ˆÄçÜZàíà3놿eñd +´&šÙÞø¡Ý-&1'.“üß½a!"²-ι©ÀTà>3«‚ŸŸp,ð-pñû{¸åãÔÑJ³ÕbµÅÝ¥™Õî4³Çœs›ÂŽGD¤4œsë÷ƒ/̬p ê9(…•«á«˜YZ¸6ˆ»ä Ïp"~òÏèpC)çÜ3Ûh½ƒ8çrÜ°ã¨MâñÙ
+gßO	5
+‘ŠËE=ƒâ19Ø/ø~h¨QˆˆTœ&$JLŠ«äÀ̺ù”dfÃŒGD¤‚òˆÏá]©áâ*9Àß;\ðä&Àñ!Æ"#Æ6õ›¯wõ²•RPρĤxKú‰985ÄXDbÄô`á-aGñ׉ð×?ÂŽ"N(9˜7Ɂ™5Z9ÜÎÌꄏˆH%ЄD‰Iñ4Öu8~Rð+b$àã?ø0¬ D*ßðá÷¡ñûy	$,‡6OÁÅ_ûóóSáÅÁ°ù0Hœ
+?(\ÿÆ`»ÿÁÒ‹€¸ë˜â¯“‘~ -ƒŒ‹!¿)4xn|ÒŸ` d7ƒŸðûSêÁð·àÚ¾Ð(>2O‡¼N`k Ý¸è[_Ö¥À;aó!6özú.¬ä7ª&PρĤ¸é9 NêáŸj¶ÿà’FhhAjœÍ鐽?¬ß?Z¼ó€Üài/ÿrv†=OƒîƒU箟»dœ;‚~§mý:Y	Û–Ÿû\
+ÿkÏ‚‡Oðç³›CÎvQq%ùò¹ÀÔº1º
+{ö„#@ëy‘²O†?ÁñÇ~.çÃ…Fv‚;®§÷+¹l\Ò„D‰Iq‘ÏJ?X¬Æ/?º8*ÄÐDªŠÁáÁ!ËàŠ<ÞÕŸÚp"4
+ýgÁù?C½÷·¬ÞüU8{
+쳺äKµ|	úÍ…u>€'–\'Ùùށ%»Àäúpðr8!*9Hþ®~z¯„öÃaÓA%·	>éx¨Üò,Ü0&¾9-áÂq¥«wÔsPC™ÙqföJØq”W¼d¬»ãŸ‘~¸sîg3Ã9÷£™	|af]œs3BŽQ¤%døÖ¿÷WÀš°iä7ƒ¶Ó"çêO‡õEîÜé4¹ô×Ú!º­ßay)þJï¼:
+„yð;àíÏ`ïûá¸þ|JT›MW€k¾íöžÛæÜÎú½d!{/¸á«Ò¾š-¹ºòSùëWç\¾™ÅÅiRf‰@JØA”W¼$½€>ι_¢	¡ø…‘”H-ž	Ë`ÁnÀ_þØÚ]·,—”_ú6gï
+,òÛëºCâR¿²6u”û¥[ázÿ
+UüS#øð6øùb8î†Ò_·h[ãOƒ/΂½!¿ä7² ñÐñ‡òµ[ ±Öå)ƒxI^Z²… A˜ZÝc& w  pIDAT‰„§î(X~¼ö'lhúxZ]ƹ0bd¶ÇÁv·ú㻍…/Á³½ u#,¼ Rçö0·|h[$/. ½VA¯GGaSßæõ‡Õ§Ãê?ƒd¤&rffÎ9=qPbF\$[KJ{^$¾Ô])?>–òÔ
+æ\ð0<“SŸ€Äù°Ýý°ò°¨²ã¡nVé¯×r(L¹òC£gàʏüñ#—ÀïC`Þµ@6´}¦E~mdœ¯Ü¶Ò¿ƒ~/úã©ó(4Ž^o3$—±[?=ΝLòûóS·Y<¾Ì;Ѓ…$fX<&«f6Ã9×%ì8$>™Y蘅JÈæ§ÂÿfÂi»BuaG?žælvÎ-«ŒÖÌl-ÐÜ9W†„Nb™õNqÎÅåCã¢ç@DÊë—0q+K5©zc‘­ÐBHs”ˆÔhó›À’#·<nšÿÀŽ«?.‰¢Û%æ(9©ÑúÍ…~·nýüã«-Ù-„$1G÷׊H1î?Æ´
+;ŠZB=s”ˆH1V‹·+¹œT%s”ˆˆ„K%æ(9	—z$æ(9	—&$JÌQr ".õHÌQr ".%s”ˆˆ„K%æ(9	—z$æ(9	—&$JÌQr ªWw…›_;
+	•z$æ(9	Uväµ;
+	•’‰9êÊ)µö„6K`iX¶+l?NáÏM­ßì)ÿü>Ða–á÷ßÜ	æî–;þÿ˜);¥|q(Ô_ª¾×$1@%æ¨ç@¤Ôæ\	cƒ™C`Ãî0ù=xôî÷60ÿ¾"寅©{úí»ÿ“ƒìæ°¹üvV¤œ«#†Âš}á¯Ap˳Õñj$fh΁Äý@Š”MÜu’ß|`,¹ø¸äj뎃6÷Â%_oy.¿t=Îþ¦×…—~ñ=	Ý×—/Ä_ÀØÞpÀ÷Ðsmùڐj¤a‰9ê9)“:ßE¶{|ù­á»¦%×kô&,x?Oö\‹œKÈô‰@×
+°ÆïZú˜r
+^Ù
+n7
+‡ß@NC%qCɁÄõˆ”‰‹ú?“üBOp˜$.›_?²}íkðùg0áxXxÜz:Ü~?gŠ\$òKø¿™‘¯÷…gBîàêùë[$ý
+ëw‡!»—ãÄ®I’ÕGs$æ(9)“MûCî#äà·ƒ!aô^	›VÄDø°-ô]è¿çu‰ª—à'&ö¼ý9üø!¬«ÀBËèú#üÔòB~>¸†à¨3­b¯³Î4è4¿bmH)©ç@bŽ’‘²ÉAAÒ,È:Ú^æ§çC÷á»á0aät‚Ä¿"ÕnûR'@â*Øt Ô
+õó*ÊÑ‹áè[üvF2¼µ,;²{¦`ðàŠµ/ÕD%æÄëdc3û
+p1òEÄ ×[ü×ïιrNì+N“‘Ðz*,Ù:<\øvÄÁ·ÀÈN°dG8ð{ø}{èÜÆxЙ0£ä§@¯Wàð¥þøÞ3 áŠÂ×èr
+t›W¶¸Zæ“¿öû£[û‰‰šwÔs 1'^“ƒÝˆüg²ðK¯#¡½n*19€`mƒÅŸë?˜å·{Duí¹ÄÕ}=tŸTøØÙS*ãÑ‹+Þ†T%sâ29pÎ-;©Rf@åaG!5Ž&$J̉Ëä@$ƒî;©‘Ôs 1G눈„K%æ(9	—z$æ(9	—’‰9JDDÂ¥	‰s”T3ÛÃÌîŽÚßÅ̉ÚO7³‡Ì,=ê؃Á±Óͬ¾™µ0³Óª;v	•z$æ(9¨<“Ìì€`ÿBà„¨óÿ öþuì@ü}ø-€[€ÆÀэIE}3ÛÁÌêÇÚ˜YBT™f¶{P6ÑÌššY«‚òQåþ®gfIfÖ$(×0ªLŠ™u7³ÆQÇšYƒò¾1"²Mš(1G?•k0ÀÌ&à?è—F;8xx-8–çœ[¬öxýVÚ<¸øôFÌö0³ÿ €³€‰ÀÀOÀøÇoofÏ9ç>5³Å@73»X¼Œv1³[€ÀР®O˜Ù5@ ‰™u΍¨Ø[$"Eä ÷˜Ùma"•*ø ì ÊKÉAåZ	´Æ'ïÿ0³ÀjçÜ3[efss€Žf6ÈîÝF»ß9çn6³ƒðݏÓðÞ§à?𳀱ι_ͬ
+°Â9wµ™53³Y at NÐÆ^ÀéÀÓÀlçÜͬЁÿ™øøÒÌ’ñ½â{™.ʈHå(1¨™*øü”ð(9¨|ï ]	’à`» hìæ8çN)¨hf;o¥Í‚ø4Ö«qÀbçÜL3›œcfÙÀãÀÆ |
+¤GÛÔ	¶ß×
+œs˜Ù@|Òqpþù«ƒr·–ú]‘RqÎåâ'%ŠÄ%•o4ÐÛ9—mf˜™ÇÿçœË
+Æü¿ºöËê#à| þƒ¿ ¡HÂ÷&tÊu1³+€]ι©fÖÉÌÎŽÄ'[0³=]ðÏèåœ[kf?û SÀåˆ[DDâˆ9çJ.%%
+ºðSs£ŽíAð¡íœû-êx7ü¼]œs¿DOÚ;çfDk´»8Ø7üDÆt`,Pø?`ð#Ð
+ÿþËÀRçÜŸQõú Sœs+Í,
+ØÞ9÷§™Õ	ê-öÃY|ëœÛÔÝ	èŒwÎô6Ä-3kÓࢰC‘¸ô0g³žñ"5™’ƒÆ̶®uÎ]v,±JɁTŒ’©ù4¬PÃ8ç–JDD¤Ü´ÎˆH-¬ÒÏÌE;ÖÌZFíÿ_Ð3Y°¿OPg`Ø3;°z#—ª¢ä@DDÒ€€sáïùR¯ {û©À³^å"·}»¯šâ•*¦a˜„¿3	üÂjÑkšœ<gf)ιìàøhçÜÒ`	ø”¢
+wg}„_æS 8?¡úiàà	üªkœs×™ÙøÛ«#so™Y༠١ι¯ƒ[ÃẂ—œsšÙõÀö@}àßÀvÀ%ÁþxçÜÐ
+¾Gµ†’)0ÙÌöÆ/é>-êøiøõYã€QÁñk̬	þî¦ì`t!š{ mœsyfö¾w"¿ðÛ  ps®`=•.À ü-ÕŸo× 'á×]yøÛõ!À`$¾÷âpàçÜ 3»xX<cfÃœs›+ðþÔJDD¤À«ø%Õïv0³v@/üÒïð«þ$ïâo^»6	ƒ¦øµX®ŽOrÎÍ5³×§Íl™sîrü.sœsÎÌ6ψ©ãœ+XÛ¥^P±s.38–»¸ÅÌšá{?zâ{!0h(9(%""€snqðœ•Oˆ¬ðz6p‘sn€™½mf­ƒs³JHÀ/sn…™MÃ/÷;°S0áñ7ü³cÞ2³Dü3	Î3³ñ@’sn™-† æw3K
+®u%ð(П¼äà×}ÙÈ,ý»Q»)9‘lüDœsï˜Ù·ø9-‰L8¸?ì0X_¤ç‹ìçoDퟜœO2ðÃéÀÍAC&~¨àÄàÀ¥øž Gd’׈x-8wxPççÜ3›»¿ý¤Þ	h$©u´’TŒAªJfö‰sã¨ít+£ˆˆÄ%±AɁˆˆˆ¢ä@DDD
+Qr """…(9‘B”ˆÔZow;
+‰=JDj­¥7Àì}ÃŽBDbA©µv½Úé^}Ù‚’‘P=Øöú
+¦w{BÝYÐÿ3h“
+Ïö‚åûBêRø÷[P?Ï×YÃ÷…•{@^HŸý>€N›"í>q04Yy	0ÿ HȁÝ>†cEÊd¶‡ôÍÀŠÂ±Lí+{BÊ28î]èºÁŸŸY>8Žú¾ÙÛ—é8NŸŸ·„_Ž„ìPgœõ!4Ë…u‰ðì	Ðöw03*¾ƒ !Ný^èݾ‡£GÎg$Ãk'Àîcá°ŒJÛEd›4¬ š\ƒŒàó»`î}µ#,yžw^s`ÙðàÝ‘zÃ÷…yƒ g;Èk™WÁcü‡wÅ—ÃÔ[à·aÝVŸß~#;EÊD+ÄòÙý0ÿ~Èm	+n†WGÁ¬t_fv#_fÄ0ÿnÈkÂK=à³OaåŐÓ2ÞññÔσÍÛäWáû&¾'ûÀ¼ y4Ê…•'ÏE–«v$,»
+Ú]žWDªzDBçêÀMøÒ‡‡%Cê¸ý`Hrpÿi°üvȸ	ZæÀ)?B£##õg¥Ãsãáݵ¯FŽçì	Çì}2aQ
+<ñ&L¹ú_°õXò›ÀÅ@»,{?|øŒ<nx¶p¹ëðì 7¾IÓàò³||_Þ
+cÆÂÈóá¦ÇáêÇáÎ}áã‡aÝõ0ïahô œàë7–Ü
+³îŠô~džéQ½"RÔs ºFïG†:ÿì¿7þÈ' ~’`BË |.¼×î·Ý¯_	+aSçÂí&ÿäðÃu¿€ìý¶KÝ/|b pÀ
+ßƆ"uš|Iæ§Bnhð‰O YÉ?ÂÆ ^z>~9ävƒ¯>‚ä_áÚ§#í1,Þ=Îï¿×²{C§èëˆH5Rr º†ó"Û-ƒnô&QÇš®óß³Rü÷ÿ
+㾄
+{AÂfHŸ
+¶òn7uFáý€«sÒ¶Kƒ"uRg@~óÂÇ:þÙžÖ0h6µH½©ß2²ß'R~‚ü¦ÐrX$ñ?7¡Þ0Xy†ßŸr*$M†3¦m=N©JJDâÎÒ³!í#¸ýB¸ùA¸öµ-?À6ï^xMw°ÕÐqóÖÛ^Ó½H= qIác	ù‘í½–ù°¬g‘z=!qadÿ¡!ëH	‹nÌ?(°ç»«Ÿ¿°¡?4y	’‘¸“°
+°Èþ£GA~Û-ËåôŒL@ß6iŸo»í
+‡G>¸GîèÛh°:Ír!e,¬;¾kꏽº+äìõƒz£v€Œ;¡ù ¸þZHœ?ä'A8z1¤~	<
+.Åß}!"aÑ„D‘¸ÓþU˜ù*Üøžßw
+ åë-Ë¥}GÁ¯SüäÄ„èýÀ¶ÛNýÞû>þ²÷‡”oà_#·]g!0ñ%ø`Œþ
+röÔÏàü×ýœ„ŸŸ„´Oàš7}ùƒ/‡ÏFÃýá†ç"í´zæ¾u_*|[¦ˆT7%"¡IrÐi ì5¶ÞiCpìÏȱn«`Ö è¬pþD˜¹'||0¤l€>`FKÈ/Ò˜6¼~Û’^…ÃÆžý¿óÐnqá:mFA£gaþPïI8ëG?¡ {&, »Y8éŸÁ.G×ûÀÆ–Ðä^#ÀøúÐaòk¤üa°áDÈlV¸FA»]^/ñ­‘*eι’K‰Ô fÖ:¦ÁE%Ž[7½u?‡Ÿ(]ù\ƒçÂN'ÿ~¬ÒЊµ.î{,n‹ñ˜§€9›sZ]Rj,õˆHÈ ˇøÉ’œv4"¢ä@¤†Úÿh\†qû${{-*¹le;èXò=· ú¯-"ÅQr R#½¸ä2EõŸ]ùq”Æ^k€5á\[DŠ£[EDD¤%"""Rˆ’)Ds¤–Z
+|v—V‡€H•Ó:RëøuØÆÇDJ¤u¤Fû£‹«AáÇ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_overview.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_overview.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_overview.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,190 @@
+‰PNG
+
+   
+IHDR  ƒ   H   ÞÿÐ   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìy¸%Uuèkï]Uçœ{îÜ#ƒÌ“
+*2¨‰…8¡ó|qŠÓSã£/&ãDœ¢/Ά 8%È " €ŒJÝôxÇ3WÕÞ{½?νÐ4Í^Îïû껧ªvíZ§Nuïµ×^ƒ¨*0`À€™˜¥`À€0`ÀÒ1P0`À€Á”Á0`À€G0n©°ã!"ÏÞ¸Õ¡w«ê϶Ónتú«;éëãÀÁ»]U}æ-ßêÐZUýý}ìk`·­ýJU[÷G¾ Dä(nO›ªzÉ}ìg8t«C7¨êÍ÷W¾28ྰ3p,ðY`0µõIù2p$°ç¡0z'}]Ì /äöõC·°U€Œ¾…=FE/B	ôP¼ƒ­ûǾÀO·Ú?x+€ˆT€gÏV kŸ ÿ¨ª³Ûôõ*à[í
+üúÁ{À#ŒïqÛÿq¿f+…NDžœDÒ»h¿>œ¡·â<˜Û¿ïï>ôà‰=`@D¸·ˆÈ€SÕK·s~p5ðKàEÀˆªÞ™2¸xÍÏTÕúƒ òý"*.˜]V©2a„1ÀEp
+b@
+(ýý˜
+ýÿôçCä#ÌZ˜1B¾´ßfÇBD.Þ¨ªŸØæÜñôá-À¯þ>X	ܦª›·Óç_UÕ‡«2XYØú—¨U	"”…*Å`²òÀ "sÀOUõyÛ9w&ð8àb`3ðhà	ô›ªê»·sÍ>ÀuÀ»Tu xÐX<¬TÕ "OF–Xž{Eˆ$­œe³],…=ku†Æ#©`@p²0ÀZ(U‹ˆTúJᤃDg(Š n¤"s~Ÿ	kœ¥³”ßug#ð
+à+ªZ Hÿ7ø(ð×À߯^:ñ\T‘"0VÂrvÊûZa$‚ñ $€8ÀôßÅ̦)…ö'&ÝBi•ÊʦnÎìí-ýî7¯ÜvR""+€w‰È?©jciD0 1obaŒðp ¨jüØRJ°¨îh¨"ÓMöØÒâàŽ×U&•,ͨZÑZOÄ,˜X,ËÂ
+¥@EÀ!°°ô—-}ÅÐ
+XÖ*Æseù\Écm`ýå·©eËR}ï•¿¬K¶9Dä£Àëé[cv,NVæ»ì•®ÕsilÖ·:E¥BDÕŠÈbÀ 
+$U`$–¥Âª {‘Cž)QÖU,7$†¹%û¢¶gVÕM"rðçôÝc®øƒ6`ÀV8ÐGe÷]öK-Ì€ûKÓåüàO—ZŠn®£f9hº#äj·‡IRqIÀ‹­yé =
+u…`Û_FúÊŸ,l‹þ„‹@¯ßœdá¯fB–¥x`¢TöhzyɆzÂoR˶¾nîmú¿ÅüRò@#¶“ëD£'«§Ú<ºÙeKub9ÕRp-%Iqý‰ŠQð@pÙÂd¥ ÿþY §?qÉè+‡Æs†!õ ;uJõ‘#l±Êº,avÁê=à~²`Á>š¾;ÕK,΀ýA«ÊÿYëxJo©…pÿðœ[ÉùÁR‹±Ã Šiõt卛õðs²—‚ORdl£‚S°	HÈql
+hGð(a>1TÀ˜¾–Ò_’[Ä 5úÊIüØuaß i"g©Eí’å­¿­rƒ5þMÞ7^AÿÙþh©y tý¬´±!‡ya¨Õ‚$Å%ÛîA%¡(•¼—`êôýW±}ŸVkn›¬,NR"ý‰IBÿ\dÁßuq³†
+à {äg{l¨%\W±¬ÿC?ƒ‡"r$ý “ƒé>¯ÓÐq_DV,µX>ƒq¨ª¥­›‡M7e—n0cbb(!"&¶IÁYrŸ#2„8‡)RŒö•/0¿`uQ=1‡9×_®(tIÀ
+ô­ˆžþ5þ ,ôa# 5a¸L!8™+Ù=nÈ,kK{éžÖŽ…ˆ<ø ýe·S–Xœû…Ô¶ÌéžëgâÞs³ºðš¤Nü²å¤Ác‹€Id`cÀ¤	 ú–kÍ•ùD¨%}¥C¶ÿ~V鿃‹,ZÛ
+3ã,¼—@Ł±–Ô\dzSŒ\LW·˜~äü€{Æ©Ü–F+/RÕÓ–PžûÃ;Á5XŠø‘28à…*f®wÚ0Ã!S-»ˆzåhU{1š$©ëôăԇHF†ÕŒVÅŠU"âUi‹Ò˜„®DÁ
+êÁ;èõúr»ÚOw‚ô}çµouQnS7±Z¥¡S*Þ“•žÝϵC)7‹°Cúbþ¡‘½€ïÒ_>IUwHEeq²²fc|â––ìÑ$«F;d$Ø”ª1b!ò1ó
+d¸Ž´ûÖik”¨ÊZgXi!UhEÐ êû~„³ôßúô•ÀÅÉŠQèJ?àkñý\œ¬¸TM|ÈÚ­ûŒW¸p0Y¹ÇœDßr{}Ëà·D䫪ú²¥ë¾1ÆÙ_¬(îøxέÌñÔ×”ÁTInÞä›í°{;·Ã¢1€—Üklϝœ¬˜‘ºè¸•Ò{ªPd™J!A¬*bèYp"ªèú9H24Ë ÙFÇj@@U‘ÜéDb¤©0m at K …q…Bn?Øn­¦lE0…¡,Î{nLV×%–æÒ=Á‡."²pý%ù§©ê5K,Ò}bëÉÊLÛ¬VC,Jg|žç6º2)º3ÆF#2:JR¯÷'+X¬¯Ê|TÚVX¡Š¡§ ¢ ‚Æ~$±–}?ÖNV,ú*Ìémï¢ç¶‰J ¯hÀ¤P‹	©hyŽLVîªzíÂÇK€SEäûÀÉ"òaU½j	E0àŽËÄ>¸¼àôÃRžõ›ܸx¼Áñ‡D6¬ãÒ³¶n?ÏÑGYöÞPç‹¿¿­÷¬,øÞ! †G­æëW
+Uí÷ó¬C-mâï±ßÉ4cÿ2Êyow\N3ùá:ÿú¡Œ“ïÓ ¨t%p½s¼CZ
+Ü7B ]³¾}ð‹ý—¯µ£#\³áóè£fijQ
+[¦£
+V¨t+’&V»)¬Q†‡¤1R—DÒ+ñæµÕicÄyEª±„Ѽ'=ɸ%Q¨YL&ô‘¥2lûƒíÂ@¬–C:£bbРD›’…’]š%Yè¼Kü8RˆÈ*úŠàpÜör_޴É?~ãœîÔ‰/ò‹ˆ¶:!T«ÎUq·UÊBɬôŒ•4Dr	”A(¬!u†Š@/*zÓ,¸jj”¡ï»0œê*D¦eB’ƒÏ`¹é+Š*·MV\dûlYM0Þ1ÚSRÒ(Ù¿j¸(uŸ ? §Ò·>(ƒ–”;Ô&.øö¡ž_ÿ[—So-7¸ÑœõYÏeŸßºm‡÷¬,¹à‹9ßüðíûøÎã<W| ²öI%?~Ë4#5xÎA %?{CÁwŽ¼7B*ã•M@p­¾KÖ}£Í›v›ãðÞ×ëìx”^«·Lå‡N7Êý²Š‹ËÆÄ?j9Åž«mw—UÕ°jE…ñQñ¡Œej‘8>.j‰M_ÄN¯bÑÓØlF3× tÚ4Š‚9õ´*Õ@ðÞ%åæÍÖ¯ÕbýzÂÌ<.QfM¤ÝÍ	›º„[š¤™2W…›»Ú÷3·1ö•B4|¿‚g,6qT¢p@î[êgúPAD–ÓWwŽWÕŸ/±H÷‰H¿®}ðšuÝ«U+£#¢•z*yÐ2øPdIÊPÍ…¢ˆ~ãzõ³Ó¦æqs³±=½E;3314£'ø@/@(ߘ‰åÍ7QÜpåô,e·K™y¡dºÒš	lîR£Ø!Ð^¤7 ‚_x'}„ ïç»iã„š€Ç‘¨¡ÒòÑ.xÔR?ˈɅ¿ƒ´R–œí.•_)§”\˜%™7yáS„êåJkõÖíz|ñ†e_ŽÌ<»Åv­ó‰µ·õ‘Þ0Á–÷Ì°ê%?;xÇÝ	4ÏSŸY··0²yˆž—lã“`ØóËîÅâ~““ð\ñ˜”çž?ć7 œ9ÔåŸMyÖ5=¾rL¿Y´\–üÏáësöÈzc\ô?guøðÊÔ.†U7Žrþêì¸çˆÈK}vW™ˆ¼oaJU?ù‡’ÅÍ~}]ói%©”‰¶Ú¬Ù¸rÔ±ßj	Î8<Ð.5éæ"Y†Az¾nÕ—Š !͐$EË	ÍĵÊÍg	…B2ߖ̈ÆJÆŠ‘*ëÊH£(I³
+eÕ (2Ÿ#óMìP…ÆŠ:…1ÔJ%S!äDÑŠe6ƒenTQUjª$Æ¡ÁC	Oèttz´"—Cq·áaÊBíës€=€¶W{G`¾Vݼ¹8<ª¬
+UüĈ+GÆí57ßA
+Ï‹¨ÉˆScÅ8'¡ÛÍ2ÁPAÕÈÌ,¥µ”õ:=UŠÕ+%Y·Ñ×z9¡QÚØž#ª‘jm˜r|ˆµêy ñÓ)qÖЭZÑU_H¡¿Äl¦ ïa“…ÄB‹ˆð˜é{ŽW9ߏøte"R^
+|MUÛ[?œ~™¹ýwxÀ€%å–Á>’#ç¶xÍq k_`Ùç?·mÙô„?ú¦aâÌ‚ÿ:éÎo“΁¿Ërd ÓŒŸRrÁ?*ÉȺÃ;¼÷°mÛx.þ—’ŸŒ Ì°Û«rÎø”2·[t†Õo(øÎÊ’?ÙჟPföêñÕÏͲÏK”æΠYdËÞÊæÝ”®48éŒÈG€ϕϏl° SdgÍqä1w'÷€;ðRà½Û*ú¹Ì÷ßð‡"Fuë6vìå~x§eI¾ï.•8ZñåÊQ¼÷1Þ2]Æu3‘õsʦ¹¨½nÌ+ŽNbhf	±R!«TŦ1I!­%$­¤	SSÝØéaUÑñ!ZãÆkÌZ!YÆÆ*ØPšóï	µŒ0TÁ‡@hF\³$˜3€5ÄvAœí;`‹ˆOD²D˜Í…“9¬
+’f2ÙÈoL|¤ò\ú5‰«À9"¢Ûl­%–ïnñA³[¶ôŒ˜e•?>buÓtoØäu®
+µ„|×qz»-£Üy…0\;1BÊèÛ0^—°|Ì…ËlÁÔ	Õ
+¾(	ÝŽÚà5›yÌÞ®³Ë*‰«W¡{îJ}ÏU´Çêôˆˆ±—àGªx+øó°n[–L;hG… ¾	-Oðд0#.Í’µØ"b³”ê|W‰‘t©ŸïC€Œ~
+÷¹ND.‘5ôKuŽÿKU×,©„p©eŽ8­ä¼·ôøÜyJoÿ
+õó¯ºõü<Ç=¤7Ìׯmò‚ÿÊ9óJ÷”Eß@¥\5ËÞ/Sš»D¦^ä8üÍw%HƒãQæåüƒŽ¼Ûú­=>9Yûæï=¶Æ{7G6Øv;×ó«…êq²Âëß:Ä?®ŸçÉ?÷üæUÀWSN8£Ç—N˜`í§ Ú¼eˆCÃœþ±…ûþ¿Å{XöûdÂÑ¿»;YÜU}ÖRËàƒV¯úÝÌÖoiíœf¿vc'L7­ìµzHŒh¬ÎuÕ“¨Ñ^¡ˆ‘("¡ðÄÂßZ²«¨lT’(b FñB’@šéÈøx•ZU(B¡†€ÐIÀ[ÑችŽ”µ!¨8$h5‘á*„Ai$Š_^¥>_ S$=‚¯âë	†HÏB	ukH¼'d)+=WϸüšâãRàýwqþ!m5íæaøÆu­ÇN5üªGí4Rì´Ì©÷1Ì5i–LÍgÚÎҍÖhHŒ ‘ÂlR!-¼@­Å/ÔýQ©¤ÐBsÞSäÁŽŽ$:\£gd6:Aœ!²¤í‚ИӲRR‡ŒÔ¢€F¨!7BÛ
+IÅPm–2\Ãá)멤	Ìù~…ÌZŠV2YÞ,ô±UÇõ©“Gr“9à©ÀqÀÞôÓü\|øœªnZBÙ–„ÇñNQòœ*¼æAygf9ðù‘5/®ò–7l1à.”Á~xééNÞýjòï
+ÕÛEŠy~u’0ôëÏ\°Þ©kðô£n[bÕLé,Æn¨ñÚãj¼÷%y¶&p݁BíÂ{¢䜾/`º|øó]]ÃH›ÿs˜eÏÍàÖ.©8ž°¦ä—ûl¯Ÿ!NY—ó•ÎsÌÂÐ/G|i”³/çòïÞYÁ|OD
+àÕªzÖݶÞ"òŸÀáÀrÀœUë7·÷˽®\µjRº½"¶;=Ê27Y£Cµ¨¨÷…–e‘áJðâ¢÷*y©cDň
+€ÁûžzÀ+)QBŒ”"PÎD ƒæ&I”àEm‚›ž÷½ ô¾S«eÎ8²²¤—¦ÄP"uAìBÁº ”àLAk,¥ZQÍgÛRé”1"C)&*¶f˜ïFêÆ£`A«­Ô+ò[#·Ë÷pã	"Ò~«ª¨êeÀe÷´9Œ~ž·#ïrýs[¿¥µ³MRfæó²ç½<jE…•“MmW‹Uœj/W4KÄ«CÄ A•@iÖª!	2†þrnÌûÙ¦«CV›ó=©dŽJEðž®8J0BLúK©*IÑ£4UHâ2È=%’e˜ x£ÌN$Ôg÷(-J†1õ©ZbP%ԍ`Ë@LYÑÍ5:ûˆ™¬<JD^L«êwJŸ»°Ý-ÉœŸ¬|pD\z
+~ømÐ;Õ="ëÿªÂk¾÷`Ü[™ßYé>1²©ú`ô¿#s—©e+O¬{[…×Þn©´äìª2¼PûyÉù¯ÜFÏ'?ëï§7M°þ'}ê3J±×=moX>Òå—'nÜâ{‚luÌl¥d¤a!Aÿ­L°ùïÎ<¥Í»ŸVò“ϵydzîM´ó#¹ÕþÕ÷£¯¾¿ðù0z¹Þ0ÕÝ·(Êdx8»¬¡—Í} O§­ê«I’ÆJµ¶ב¼Wh¥VÁGѾ÷žö¦²é[Æ@h""¡? ナˆÄ^Oµ>$ªŠ;Ò
+	Ý.¾Z£KZgéG´bD¢€*i´¬ÊÆ‘!¢W’Nï=>M‘Ìà*B¯ ç#ÆZ±
+ãÍž>z´*Çú¦9ppÔÂöyàâûØׯ]ø|Kd9TÅLÏõvíæa§=w_ŽC£åi¶b¼Y•Ñz¢J†^3B0!Ç¥‰“—ÑXÓ_WU1Fú“•êDDDPH¬ar²¦ŠR–8$x°	Ò+ˆçK‰1†¬šŠs ã>¤^L?‡fă-=ÍŠÁÖ­væRÉz…†Ò‹ÔÁÖ,­R±A0*¤b¥Þ)801ñÆ,1gáÍôBÞü–~¾ËûÂn}@ÿ}˜Fg»›}`{gRNøõZšw£Öùäs¾õ£:Ÿº9ç+ËÇ[¼ñx¡rù$ÍW,ëòáemÞuþÖíî
+UÞõ³&ö¡vÿßu>ý5ÏÅu¥gƒBî(Û¿]WpæºǽµÊ[>ŸrÒ\“—9Ì/¼«ûñ[zœ:Üä¤OØÙP	ünb˜¯_Yeóy-^7«4€V½#áØ3‡ù晳ìÁBU¯æþ)€[÷õ€FvGÅݲ©½ÿæéVZ©¤az¾Ôv7hµæÄ!Il at 5j¢Öh飩Ö*EÔ&	ÝV‡á‘*¡ðIÙ¢bŒH„¾–§¢VP#hˆ˜4Š .! Âƍ]¾¬&IŠŒ'8‹¶Ú0׌R2…Xò2Múuì¤ôˆF¢Q$qØ t5RÖ¶4a¨Û3½ÜK”*Œ¤H&´ƒRE©¯=çd¤“ëÊZ&«e'Uý-°ûÔ×G€<}Ýz¹¾ycóÀn^šJ¯ô;-«êÎËkÚìšÝ@»0&„4M‚ŠÑ¬V•¼›#Ñ3V¯j³«DEŒ”c$Þ:Ž¢bHbìç\ðÛ‘(h»âpÝÄØo#‰ÌÎFŠ¼­µ˜h¨;¡%Mú©hD1*bÁä͹q²†¶£Œ6šÚ)r	•*R±˜T(ƒP	ïÃe )K©£W$V–	ªUõñß]°zïþ@ôõPF°óÛ¦©{ éòÑI¥kª¼nZ¿Óü—‘
+¶Çg'ïnå²àµ’OTxãFËî÷(0ªÇ'Ç-ûõžÞ½;YžÞ¸§éîr¾2¬tM…W> …;¬Û³Býj€”ç´‡ùêuǃPý9€2»—e¿/m}]•¿™2L|«Ç¿"LLCÛU„¡k„ñ;<øŒ´2N|±2õäÏýï.ÿ÷³k'û×T)Œ‡…Ï¿ÆKa<Vù»—+Åd›¿ûÖ,ûý pÍ	ý6+ºBíÖÙ…aE.T/ퟏŽCÿ¶à¬×vxÿ•Ù¬äìwN3úÓ6o:Õ²ç§ëœzSÿ{öV)­Ê}x®– U•ùFoÕ–ùÞNõzF­–¢(}”ШŠ Æ%NU£‰!ˆ"¨‚sŽj}Hçæ;_
+¡4Î(!"A±V¢õ‚ªªªs„$Œ1Fdd¤fڝ€÷àõ
+C5X6Ž¶Z^fçKé¶c³d½H%FÔbô¨¢BPOÌ=v¶¥šŠ™­¥ê£Gæš{¸Š¡g-.sØècRªìž—·¦«ð$*nýæö¾·´&Ë@hu7mê荛;2ß.Ä‚5ê
+€ª‰Q*Tj™FqlÞܐJ©f(h?9eT$D5!ªñ‘D#^ FÅúR	E‰Î™¸ysW[íR¾ÕoÙ„¡^…N;Rzž¹hò‘Ôbꈅ‡²$vsbbQ›`fsb&4R³Â«tzÄVÑOP]±´Dðªäõi"ÖGY¶ÄÀD“—î;Eò‹iFNÝöÜ4cŸÂ]Üàď•œ[™aù{§°¿ió¶_wx÷¥Ó,»b†ÕoÛöz¥ë¦ÿçv¹²Ãû.™Â^1Ëþw‚aÕÛ§H.hpüµ]þå¢Yö¸~š¡¯7yùÞÛ¶Â]2òÌsÌ“§HÚâ
+—ÏsÜ5ÓÔÿ£Ë‡ïðîÏsÔÑS$µyÛ¯ç8äêiê_nó7«§p—Í°ê™WfÙûeS$6yÙU-^uåÉsö'÷ôyÞœ2ÆO?=(+³ã³XVFUß²Ô²,1ª»î¦¹Ãg[ù>㣵—ª½Ü«1ÎתNHjUk­Š ÆˆŠ*bç\!ŠjÄ«E¯«™S«1ÛõTuVƒ1Öô—xc¿ÊƒŸk°råÆ*‚ ¨4*Ü´¾CYŠÖ‡†jNĐ$–B¬"ÆA§	*”>šJbÂPF™G©æ¹R­ŠÏRH
+’4÷š¥NòVŽ¢žé剕ÎRÿîÈæéΞ×ÜÔ<ÂZ›D±ÑYÑ‘z¨ibÕYƒ1&kоÙOuQLÿý"*ív›,µ&I+Ú)g-ÆHƒ.¶ÑßWãÀ{%ÁYUBP­ÕFPkéÿØ°¹¤ÝS®;\f“e}¿B-Š~ac“€FÄGèåÊHE
+g³m[	Qýp]ÌDµï
+[F¡[hÄHO¢®«WdíÝ?©eDä>ë
+S˜5Bzõ$½»
+4œa·WGnþ;ÃnïŸàÆÏ̲×_nø a§žà–\ëæ8ø»Jñaì›–=~ÖGn9Xiï1Éüúýíò†È-o²+ ÙhxÔw•ÙÝ#›O†°"åyÏáô+ï?Mõtaìç†UW€óžªÌ âGø¯£Sžs«¥{
+¹’ßA6ìôaxSä¦ç+íc…áÿž¤qknƒg<®àG§A²Ö²×'„‘éÀu'(ƒ¡ØO˜ü“LýÝmrL~H™9Y=òç”ÆòÀÚ—C±¯åÀ׏så™÷öwXdPŽnÀÃŽ¢ŒÕ^ÇŒq&uçH£vi|0š¦ID"‚`…¾QDˆò¢0‚Qg­&‰¨u5ŠÜË-›Z¬˜¨Ñ)
+ÝD„QQÄCª"ˆ±¢¡ÄDQ­T3-Š Ib`	:9š²fmCò¢Ô¢WÑ¡š-k“J•Âe²&h44[‘"ïi–Ôht`r”®Fª!¢eèg¶)X¡%J%
+¡Ù{NÔí•wÿÄü¡™iä+“DÓ‘!Q¯½Ü‹±#D#*‰ŠëÔ 1ãlCˆFU©
+kð¹Æ²w¯1ß-<D¯UIœA,ê}ƒAU”…ÌÑÑn·K­Z£b¿Žœ
+ºl"¡µ¾#›¦¼ŽÔ“r¸žø®!K-=1àK$sÐíEõAð1šNn\–Ÿeç¸¼¤l%Hj0¢šU$ïyÒÜËÎeÐéÁd呍Rì=Må;Û;7Âw_´¸´:Î5Ÿaù‘‘›ÿ¶Ás~VkÞ#T/çÊO,^3Ï¿J)³µÒ¸À·/ArË$ÍWÞvýS~^ò?ß*9ïEÀ­ÿwN0sâb†”Ξå€ËלÒæÍ/LyΗnßo¹gÆŸ9Ì·WF¿=Mõt¥ù'=>7º¸´[rþ[AÊ!>øü*oŸZhû“iÆOQŠý¶î±Á³VfN6¬øÌ›þa«S_ž"¹ pÍß®ý¾e¿û•×óNûØÑ!fÝ^1ÜézmDÐ(•4u‚ª”ei|D¼"ª*ÖÆô]¯ÒÒ$Á:+eˆÒíéõ¼$©•J}˜©F_䬃zEEQ¢"€Uœƒ4²j&ÆZ¡d"Ív!k×w¸æw›L«X1‘bc—bL(Ù    IDATF³Ë–鮶۾˜™‰I^Ó
+h½Š&‰èØP%Ž
+IèAÖm*%/|¯šâ´_®$%&V\´k,.u$ÖÚ‘Òkm©·'Fµ^\ÕÚ¨¢£©ª³b}1 TMâD+¦’Š©V­("ívÏøàÅ:§Î‰&Y“
+ɦÙBÚͦYVG¬EŒ1’—*e‰k¤ŸPÅؾ¯CPÌP½&ø\í[ü¤ÓS&F3­%%›·4dýú6é¢7×P×ÍÕ£Ñt¼n•P¨10ׄ´7^'·BVxb§$†Ht†VŒªN簍®9áH ÛØþ¶U+ªZãÞfºà‡Ÿ.øÞ§Á4ª¼ã[û*[žvj”s¿tOîn9èË[ïñÏ—€äÐÛuÛû+]éðž•
+Ž?dž§<IÛRFwX**—n¥.»‚î
+ýŠnJçHaøG[)‚ $ùÛöéùù³©ðÊ/l{ΰì«:üý÷ä{ßËà€‡
+!ªcC§Û³!ÄÐhYªµD¬£XcU’ÄŨ–2Šø" B–„¨Æˆ$NP5 hˆ‘Ä!RKÕ—A6LõIu¸bµ[ªørÁ­ž¾u…¨8QET+¨ef¶Ã\£)`uj¦a†‡ëºÓª16nšÓžOЮH5KŠV+º‰a+&­WaËtd¸nÔ¤D(KQGìª5µ²$ïåà* "©¼
+&‡Ø)t§Q'ƒ™%D$/Š¬(%6T¨U
+¢Æ~ø/ïXUSzI«e@¼/qÖ¨«e BQ‘¬âÄ¥™—03ßcÙxF§DÝ~ÉïUMߊAŒCcD¼ï§Ÿ	^iöJZ¯­V׌ŒÔ£K“#Vç[ž9S–¥IRu¨ê¢sfQ°i®Jh´¼4šªE‰®K:­U‹:#.÷ZÁ&­±½"®ª˜uKý“X„dÍ$í“ïIÛ*=Spú_—œ÷M ÇOÞ6àC)w²«îip‡eßÛeq<¾ ·ÂíŠcÌqȳ<W½Êí([ùvÒÿdwx§…±5°ez Ë?îX¡vã¶mŽ]WðƒÛSº{ Úá#ßèÜ!þ-®Ú¸þŽòÜsÊà€‡
+ij»©•ÜŠØ—ֆËÒ—8µÖª(K5.‰ÒíùèœÁYC@šê1"VPM¡Vs’eVC€àÁbšZõ¶J³ÄÄ‚ñÇ,ÆÐOô«DUèåg
+FDC¤?ZzÁZ'½<B‘a§’wtz¾C©dYÊ\‡¬,4ŸpÌΫˆx2—™i‰¥±SÉLµÕ%®¨#¡ôj«©ØvÎd'×æÃ-ºx‡FUÄØØË{6/JÍ‹2f•T¬A@¢#ÎE©V+¡ð*A#ÚÏt‰5àl¿:°K
+"0Ĩj-b­Ñ<¦²yÎSMÑѪ£S¨ø(*"ýȤ ˆ"FDË€ØŠnÞÒ Ñꈱ	yÙ4ÕjUk™c´žk£ãivº’%IYÑw6qbÈ膩 ¯š˜ Qœ¥êtÃëè°3m÷4¸š¨’…<˜Ö1(#Qu!HÀ€»&pý“?+[¶SÿZmßÚxÏ’íµ½]žÛÏ9Èsù§„ô*Á¯wì}ÆËn–ûyŽ¾Œí¯¬Þ­B5Ü&ó¶t·ÓgÌ@‚a§¯ÜYŸŽCï—"Øïã^2î¯5¬»u½¾Å«w/8ýå–ýÎåüŸÍ²ï‹•æ.lø§û+à}¥Å«wÏùú;”|”g¼J7Â/½³ö‘
+vž£_™z<HiÙõÆîaÒé'<6åÄ5þ²0Ë~¦45Á†ûœÆbŠä¢1.:¶?cpO0"ÅÈp6Ý셝U1!*išÆ™¹6Y–&Ä|¤(‚˪¿±IT‰¹÷hTrkè$j%ÕÄ9ŒQ±NpN	b5#[f
+–O¦:×EˆA±ÆhQDqÎ"ê*˜‰‰ÑØnÚé1ƪÆÈülK†GjT’
+ã#Fgæ}ò«Ë¯:úÜ.{ÑŸ=ûIÿõ´'ø£á!‰yOi5¼Ô‡­&&Qc‘V¡L¦ÚqN2ðRt¤à!1½"¬¬en >D0F|j¥'*ã ±,ƒzß[œ¬%ª³†zÖZg±¶¥îƒïû3ˆjÚëOVªU§e©ûC‹f™‰>z!Šä¥Ž8Z…‘2‚ô˜DDÈ‹€5kú“gE\âbˆŒÅžÒw!®Õ˜HºlœîiŒk­ô¼$óMÍ+U‰##FZ-•^YR«8¢ˆ5Zä1¯f¦ÚîIhvÑá
+1DU@³Dl£££½B–×2ï瀻dž§<)²áÂÈP®
+ÜðÞ&/ºxë”oBºFÉ÷Rº²ß}ÆsÉSAãÈŒò“_,ïòÑIˆ÷)…@w¯ïò±Riß¡Fɹ{n{L¨]¯tŽÍxñ÷ï,ÕÞÁ½öŒlzAdë[üå­	¢¾ý²ÈÌ7pô/Oz@óÇÝ[
+Îx‰aòâeäI(9÷½wÖV™5³ìýåȦ§:þ–eß®û«i&?tOîUò“¿-øÆV?lY…²~ÿ¾AXqÿ®ä‘8Ó[9Q½~(‘µ1✳Öµ£õªÉ\b²ÄÚ²,M»[ÚNÇ›v»g»y4}ç}5Ö1ÖH^xÓj—Òî¨ÌÍ2×èJ¯Péõ¢t{UEEÀ¥LÍdR’Dû©e@±FCTÊ "Z«bV¬#NAQ%hÔ¹¹&ÝB%ËjéÄh…D$…—¼Ð¸i:—éÙ\+Uk…v'`ŒŠˆ’f†¹2”¼D¯j
+¢¨w¡ÚÉà ÕÌCˆ‰ÑlýPÍ••,5Æ9S­fB4Na4F1"¦ÝÎM«]ºV§´yLHQº=/í¶—ùfi¶ÌôdãæŽtº¼T|„P1Öm"ÓóQ(‹~ùÈ„°¸4lÔ‡HéUŠ¢¿œ<99b†‡ªÄ "bÐ¥ÓîJ³UŠØ*£U	^Ón·°o~Ïþõœ‹®úãéÙhR«1MUñT3«6Át<âíVRlPh¢Á
+ÁL–éæauˆš,õo2à¡K—(9ÿàÖÖùÂßTyË@Ú9ß>µäì[«ˆç@X=ÇáÏyàîî«ý¾ë·ËØå”{´¼}gãQ¨ÿHiýQ“?¿ÕïP™5ž‹_·m{Ëþç ôøÜk·=÷@rŸ–‰…±ïüà$àÑ
+62wœ0|kÔN`Írenœ…¨œÏ>¸ä“ Æ.Ÿà¦Ï6xÎAßíÑD6SåÍèñ©W+ÅrÃò_ŽqùW…ª–œ]mñÚ#[)ûæ(?¾`–ý_Ùød!™ËxÙç‡8e]¿þàÌ	BçêV/SòåJ¹ëËß•©	Ö~rëï3Ç‘'*~r’¹?YœUä|åâ&qaƒgž6Â/áQ¯©òúÓ>gØýg<ÿ¿K.ÚK)ö(¹è3,ÿÓ„gÞÁ”;ÏÑGy~û $<á[‹J¥+strdêp!ÝRåͧVù›©m¯oðüÇx~ù´QÎùôýz8#‚ÖkÉÌ®«‡¯¾äê-;ÛÄYk+’fN'5ÆV'猫Úî&ø@âj2<dCˆ"Ýn”<–Z–²âœQ#ªÞ+C5‡1¼U笈U“ȆÍMÝuu•ŽZQŒµ¦ŸÎ£(Î:ÒDt|¬bZ­"Î5
+
+Q‰1HŒÈôLË­\9ZfΆc8à¼Ç´÷ÿŒI»Ç¨‰¯Õ«ÚË¡ðPK… `H»£¥KÄåAµŒ"©ƒbL1ÞQe'󡃮\6tý|³˜˜kû]«ëÒÄç¬eˆIâl¯ÛÓ FñAû‘ÃH%%ºÄ©š UC´ôBˆB§Û%M-õ¡*Fk…$E4K«ˆ2æJ­¥‰´zhš@D$"ªE‰$Nt¨fdÕÊasÓÚVô¡¿¶BÔF³CŒjC•ÊÊei¾ysË…—NWc£å¥,KV¬¨ÑËiç¢ÕŠŠETR¡]¨ÔDˆ%1u&BP-—Y·ˆ“õŠÔˆ}„¡ø•3ì´Ýh–ý/å'¿èn¼ëˆ“)ÏznÆZð‚VÁÞâ¹ø‹
+NúûIfß0Ì×>5ÏÓŸ¸ê”vÞÝqȹùÀU(3L°y»ÕNî
+Ë^F6½¾äìÌñøOYöZ[rÞ	‘-/†û
+Ÿò§§ä|ýØœ¯ž^rö@6§l~:Èâø~«us”Ÿ?ÍØéÊô˧vtša¯‘5+k«l>~’Þ	÷G¸Ê ã ï–\ðO‘
+iðÜc…Ú¯ÀÞª=GÖ¨´vþ»Á3+8ûó†?ã8ô›«
+øÝ>k>`?Ýqèׄjló®ïÆβìóÀožeïeÜò±&¯<Y™ß?帋L@°°˜ƒhãþSdý!]>~z±OM8êÒÈ
+›„‰Ÿ;ùyà÷{Ú‡:ÿaèy‘"Ž2,ÿÞÖæ匓›-^ŽçŠ£€K#›ž¸úl`
+@ÙøìÀ5—¤üѵË¦«Î·ìuMÂS7{οµïyŽ=²ä¢[öú”•‚³¿Ðä¥/æ«×ͲÇ;”¹£,},²æ˜6ï=-åù¼µÂ7Ï“.ùÕ{*¼ä5Eðî!®\V»ñ1{M^xóæÎcQ†!†¨&ÆhŒŠÄèUkµ4Z)4btj¶g{…3“£Yœ±qr¬.Ív`j¦ÿýëg½yv¾µj—Õ“k¦fçw`ï=vºÎYSÞ¸nóž!F³÷î«~÷Œ£>óàý–ÏÌ4½üð§Wwé•kk·{õN·¨=öÑ»_vâ	O:m¸–5ÏûÅå/<û¼«ž:>V_×n÷Æa]Wþö¸§>î[;­o]úÛßsÚ÷/zÉŸ>ýqß|ÒaûŸsýµ×=öŸþÚk—¯Z¾Ñ‡èZÍöðÁ‡ìÿë§<ý¨ÿž\¹òæßþúêþñ¥o¼aÙòåjCY{—&·ü¯WžøÙ믾á€ÿøâ£×Ý|Ëê²(d×]W^ô1ûöžxðYy^T?ùñ¯tíÚ
+û¾ñM'¿éÊ+®?òŒoÿä5Ï}ޝ
+pÆ·Ïù«¿|ÅóÞôчyݵ7ö‘ÿûïŸ}ÕkNúÛ#žð˜-ñÏ»ÃSIm{Õ²Úïç[s“íN¡fpÖÅZÕHÔC´b¬DU¥[xQUu¶*C5B–8íåH¯SR–cDœ3êK¯ÞGF‡STÑD’$ADTœcýæ&»®®’Y+=oDDÔQï‘ ¼°ˆˆÖ멬ZQ‘õ›:â‚\Uæ[=WÊ
+
+W¯Žïýë—¼ª?Y)c%K)r%ÍRõªª)ý¬èNˆŠO,.JéE5YÈ„m$Xc$/â²z…2øˆ#¬ˆlxóöÏI ~1Ëÿ[iÿ‘a×á{¿Y<;Æ/Ï™aùç#S¯œå1çså	Oé
+ñÏÏîðîEÖ¿©`ý[úòÂÄWï‹„£\ð³v:%²ñ
+žKþÝs	Ü˜ñg–óoÞ—>éógœñžÈæ¿ ;e=7ã¥_èò¯	ÙíŒBã\ý–9žøÛȺ7•œ"·ê¦!Œ~;·¸×ÜGËàdC¨ý¦ÁóŽ	\ýÇ¡_ñ\¹]Í´äÂW&ÿk‚›>³ph«ú©f~‚©÷ ÌqÈñ ~‚-ï˜çØNÉùŸ>í]ÀvŽÙXáõ·†mGÖ¿Üqð{ǸäGÀYÓTŽmóÎgŽsõi9_7¬¼a„3¯hpbŒü¾}ç>ƒÅ*¡~þ¶G…l“Ò]uWÏ¢Æ7v9¥iÙãÚÅþ»üý­ç=—ý…aù×ǹö ÓLì_rÖÉÀ{"›_žð´—-X9<ErQ“??fŒ_ü ÉKNŒÜü’ï~I¿ÛrWr¸ºëê¡«F‡Óé5ëÛ‡L7ÊÝ«µ$Xctl$%z´ŒANÕGbŒq¾YÐhäfh(+Ç3¿çêÄÔ«b¦f;­Û°eU+F¦Ÿ÷¬'ùŸß¹àß;ûâgï¼j|ý‹ž{Ôiß9ëâã¿ýƒ_œ˜&®\½ò¨¯ÌÍNíõ™/ŸõÚ·¼ú¹>`ÿÝ.›žj.Ûû?ÿ™e#›ÿø˜C°aScÙÍ·lÙ+q¦óä#<sótcןwÙ‹K*/8áÈSgíÑ›nÙ¼÷æ©éñÄ™Ú2W¿qÍÚ}|ðÙŸ>ÿ„¯6Zäk_øÚ[¯¸ôªÃÞöþ7¿±ÕêÖýMûüþú›öYµzÅ-»í¶ê‡ˆèûßóÉ÷mÙ<³ây/:þ‹ûì¹úÂo|õûo½ð‚_ÿ¹/¼ÿˆÉecöÛ÷KÎøö9õ¾wê­Öÿgï¼ãí(ÊÇý¼3»{êí7½B  Ašô
+¨t¤H+ŠŠò³±!öŠ
++Ø¥HTz==!¹ýž¾;óþþØsC¡‰Ðó|>7wËìÌÜ9s²ï¼ó–jǤI½<h·ŸÝvÛý{?üÐâW]rñÕïÚ}÷m/½þo·öÀ·›»ÅÆÿ|öaoñl4+u´eVݾ`൥jc|±hŒ¥VqÞ«zãä9²Þ1ZjÐ?X×áRb{;":.ˆe|§ô7x¼¯ª_<ç×_Z¹j`ƸގÇ_=4	 XÈ–Æ÷v¬ztÑãL™Ô½ìŒÓŽü¿ÙÓ;ú2ÖËw~vÝ›¯ºþŽ×Ö&•j=?yb÷²ÏìĶ²#—]uë1ç_týÉ…|f¸Rm´©ªi+æþï´£ß:urÏhRÃ·ôœ+ßtØîßÙw×yßyÛÃ;áÓgŸ•ÏçJÕj­ ªEQý«ß9óíÝ“&,¼ùï·íñ­/œóùi3¦>V)W
+sænôÀY_8íc=¸hög>y/[9Õ{5™lTyýë÷üÑûO?á}Þ«ù̧Îýåßo¼ýàoóÑ}úú†&âÿιð=ï;îôí¶›sÍ›O<ãÎÓ?x⩇¾ß¹·Þrï¾ïß—þzÒɇ|ömo?â“öÓmñ\èÅ?§0(Ý,ü!ðÃõß[}&ð$m_ŽÓrœvJÌM™*_ÛD°>âKRâØsKÏÎY·¾´_=žÚÎòoÔùõëüj£]WŒí¶qÁ¶O}^×ãØ]Ü!páº×Û¸à!à„µ¯
+±Ë B瓳&¹ný øA™LvÜ=Á0«/Çÿ[ñ\=¨Ÿ§Øö“»¸p~áü„[ž6”eîïw¿M©ÍmçO󟾉ÆTÔ[×wgí”qž¡IBî®±óÇß¾'á®0LJÎL½Äû¯î§ø³QÞ8'-•LŒ8ð®'jÌݧ”žQx[?ÑretòºW•Úd!¿|}OfoyÄ
+“ÖôÑÐ}¯Ò˜˜æpÖ|ž3ÖÇBö>e`Òعã±÷fÿ %>DD;Ú¢•³§ç·çƒÕª³µ†³6lâÔ$±1adMYÉg“±"¨šR©<¶¬Ü·¨¢]¡‰"#"è!ìxÅî;lö¯7¼f»+EÐw|Ð÷÷ÛsÞ_=p‡? ,YÑ7Ó‹•Ž®q‹÷SNñÎg/»rþÑß¿àŠ÷,]Ù7-°Æ%„íçm<›-f^¿ßî[ÿr«93o¸ùŽ÷+—«ùj5U\rYu4ê©wÀÞûí|õžûîôçwÛé&O\øЃÎY¹héf>Í<K†¯ûÙŽ:îàŸ5®\Ñ7i§]¶¹éØãùÑ^ûì|É?|ò)}}C“/¿üú“^óÚ]~1oëÍnxì±e[”J•Î÷Ÿ~Â{Ã0hl½õìƍëZzï=浪rë­÷îcŒqÅbþ?šólÆ–çnÜqÓ¸ÎìÂj5–8N$›	LgGÎär¡‰“†Ôê	AC†$iÈãý%¹ë‘R80T×é㙳QÑcðª&
+mòÑ÷ù¥Y3'=R*׊õz#{ú)o8û­Çíó³e+¦\7ÿÞÊ
+ËÊ•}³®¸æ–C÷ßcë+Ïùâ)'}ùoy÷Èh¥ýïÿºo÷¦}+ ªØ#^·ówØgûŸUkõ⟮½õ„¡á’¸æÿzq\—l¨T*u¨Õë¹SN{Ûßô¶7}5_ȏ|û«?üh¥TŽÆæç’EK7òÞÙMfÏ|@A¯ºò†V,|ÊëÝÿקøm˜<iÜc]ø—÷ö÷
+M2Füi8þ´z½‘ûÒ~tÞ·¾qÁ·¶ÚjÓ¿vø¾çn´ñ´{DDo¼áöƒn¿mÁ^ ÝÝ-G” „ìRoç¢{Ûøíýk‚ÿ.Ž)µséÝëÆ|!(U)qê“„ÇßëtÜö!0£9Þ{ÍÓ=[àKËÛ¹âö"ç,ùO	‚°a°‡êá½Ä;÷ïüLž¬í\|ƒO5Œûý3{ïdz–ì¸þ{köÇ1t-Sª[×ùÙ<°}óâîëfÕg»Y²ƒaÜß\ñá´T°¢ÁŸÖ<£T¶ÚŸ"¼ÚkàŸV°5L½Î³úPÏŠ5®Þi¢ëÒ~Ûþ
+@W8šiD¥1{­jJýiê—{V¬é£g`žYžáøQ0å
+Ÿßò‰þW·z—g9ñXÇ‚Ó‡ØæÀ§ë{‹g&Ÿ‡·›Óõ‡·èüMwÁ>ªêm±-ººC[Ì…¶XÈš0H”hkk3ù|ÞD™0,Ö£Å+ª
+X›L›Ú»Ì¶­˜+Ö&Ó§Ž[êœFù\¶išº|A¸å®G·=ò]ßûþ_w¢KâÂÞùR AÅX%—K§ÉFÓÇõ‡81êµ»#¿ºR­GF+Ýê½ ´3’+ähøæWTÄuv„ÒÙÑ;®w¹ªÊ£­œF32ÇÜ­çÞÒÑž‹ë1ºtYßD€Íçn|Š©'¾c“M§ßY(äF/Z±9@…µ™3'ßÐÖ–?¡g	@6›©¼ãGý_¹\í¸ëÎw»÷žGvÚu·W='¯úϏŽ¶håÖ³»®š;£x-‰/•ÊÐy±jL bƒl.²ù¶¼éìÈÛžŽ¼i/fl>kìªÕÕÌÃË­4(2bqgœ~ô—wÛa³›=t×>ñÿŽýü>»Ï»ú¨ƒw¾`ÉòÕ3ÃŒ•öΉ|íŒc>³hÉã³Oýð¹|ð3ç}d´Ò¹héªiaæ÷xû›öþÉ~»nõ‡ýwŸ÷‹×îõªŸßøÏ{Þ008Ò;88, Ýmš‹¬Ôkéü;èà}.Û÷5;]µÓn;ýñÍï~Û§|à‘¹ÜyßΪéýžÞîÇtþ—;ò¸C~:4\î¸âò^÷ÆcüÍ[Þyôw8h·ß~óœî›ÍfÊ?ÿùe‡T¸;åÝGä±Ç–m±zõÀ”oœý‘ýÃ0h#~Ûíæ^sËÍ÷î÷àƒ‹¶¹òŠN*rÃûì»ãÚ¶kÑâ¥D25ν¡ŸüEýt¹Ÿöï—8õoJcKË&gf9eè¥îÓ¿gÐ0ÉõÒØóÙÊ…ìu^ƒ?œ?ÀäQËœlÝTÿ>‰"?¼zˆ]>ÖOÏç,ÓnJ¸ÿ}†Iç0ã†Þ…B× gx3¡í> ËÔóîúØ ó²ÊŠmÀ·ùæS¼˜œûhº™u’лdlvŒNn¾l€q‡²Éù–Í
+q&á÷z~ÙÎ¥w§ïøën;uˆmŽG‰Çžºÿ‘pÛɃl9>ÃQOÒ’ì𓘿;ȬUJ’SFö‹8þ¨´Î	ç%\æ¯ú¶cñ`GÛøÕšíê,ïZj˜tl…/ÿr-3]Üsɳ÷Ó!"U CjΣëü¬{íÙÎÿSe^Œgþ¤ªßXûo7F|>n>£ø·—’þÑx³l>²ah}6´&²ªªÇ^]’¸áDJµ„l5¶ˆhSlD›a›:\¦áÞ ±½é–ûvwÞÛ¾ùÖ÷yÍ–ëqdB«6J¬ê™0wÖ$®™ÇWÍh+d‡Æwû[”PÞ«xŸ¾œ‡«y7.+Ë—.ßXD|Gï¸ÇL\é‚À9—P­yé׳àŽÛîÛæð£øEâÉßqÇ‚-J¥JÇìÙ3n¸õ–{÷½âòëO.óCÃ#¥žýð¢3OÿàI§ì²ë«þØÑÑÖ÷«_^ñ!U5{ïóêß=Íœú1йÎø¿ãúüË­íeªú¯õÝcˆŸÐ›{¤½ö?²¬²}©áge3"Æ«ãxçñÄ!„’xp’˜ÁÁÑ(‰Ãšó;ÖU0bÒÉšÏGUU
+µùÿ”ÆÀ­w?´ãξècùáývßòš­¶˜y×Ï~s݉A "F‰2éz¸½+ç3F*UÕ0bçÕÖëqÖç£a€Ld¤­½ q3b­î|±ÒQ0&m³°Rèì(Œ L9í‘DÃ2±28Tj¯ÕêÙ|!_2ƈze³™þ °q¹T]ôwù²Uc+¤Z­¢(¬xàn?»õ–{÷ýÇü;\½zpÊn»osYggÛS´6"²5#ýÎŽýðž¿’ÚZ¤ªÿöû¥ÅóÃ0ÉY6ûgÕPŸ
+z.
+Øý¢v.ºwCôéyƒ–i?
+ØfÕS¯ÏºZhIçÜî| KîåØ£c®92ᶣ
+Ýw¦
+oq¿#³Æ#'`ûF‘¯Ráóov,ÞòéwÇ„Ãä=ï­,ŒSþ^äëèâ±±Í
+Çâ=„h ϧËih˜yIÀ֏BšR&Ç©G6øãÞJß4ÖAÈi7«ß2Ä;í.˜8`Û3;™ÿ·±2í\sÁ(‡®v,Ú=`Þo<+çl» _ÿ¸Ìé»x–Ìó,¿3ýûûtpõ¿F8ð	·¸‡¾©Ÿ>ÐÍà)÷›    IDATò¯
+²Å£ŽÅ{
+¹¾tø˜Ú×0ù[†).ÏY+!<¦ÆY;·áóEUsMÑeìËÿlǪì­kÑӍAšÆ³Ú¯uÎß°teu‹ÅýµÃ(2ímÆ¡‘\`¬iïÌx#Å‚MÅA+`Ц6]1Å»¤ùRHbÌ®;Ìþçßæß¿Û‘§|ïûãzŠƒ—ôMh$I˜4m
+w?»ðú“~ó‡ùG×êq¶XÈŽžñ¾#Îèíé¨
+yX±ªJìŒf›/ç?þþÊc¯ºâ¯‡{¯F½òƏýÚ̍¦/xèž{wPï©Ö¡˜5ê¼q'½åÐÿâç8ñÐßùWcmR¯Õs¯{ýž?zã1|Ã9\pþ?šÉD•þø3;\ý—sÞ/úl±˜zÇ)Gý_[{að„“ÞðùoŸý˯O™:áᧁßÙçù™=Óñ}Þü›óèÅè‡ ógDÐ|.œ3³xݪÁúâýy±7]&l¡º ÈX4’eq.0ožX¬ˆ1ñÍùiÒ´#XÒΈø×ívvÞÛãÙñ’ÃÜéâ;XºY©\-F¡¡­Í4÷F®¸æŽ×¾õè=è.ÞußÂݧMê~xò¸ŽUQ˜F‚ixE14¿Ü{ç‚íúú‡»ÕÅáü¿Ýxh¾P™8}úÝ£«g Ö:©×czz{Wl9o³;¯¿ö_{m´ÉÌ{g̘”ùË×½µTªtì±çv¿x|eÿô+.¿þä¹[ÌúG©TéüÂç~øãO|ê”
+…ÜÈ®»osÙ´i¼òŠÞ,"zÈaû~ïi†öCÀ,ž,ðó"ž¿˜u¿Øm?ű²Å‹K~üvC÷cŒç-vñÈÏÖw½“]=vÜη¯}¯_= |îÉ×~{?ð¤~YÞ3˜å=OÒê¤uÏ¿¸nýíÞ~%ðmàºZ´ß\Zà›ç¯[n!§]Üs)péúî[f&Üq90æ¹ó÷±{!»Ô;ùǵÀµë{¶éX²^ç•.îý=ðûu¯w³ôì±ã<ŸZ•çSg¯[æù¢c{6ÿãXk’S
+w†Q-^²º±]©D1—|X+Jú2WüVsf.˜<±kU.k½
+‘q=Å¡Wo»ém¹\éé.ï¼Ãìn6kòCa{í:çÆ|>Sùý•·ÐÝž)¿ýØ=~qñŸïܯËTœQ€Ã_·Ã%+š˜8õ†/Þfîô‡ªU¥³=óøVsfÜÔÓÕ¾<ñ*ÙÈ*Àö»¼ú*Aµ422îõG¼îç§m|§ª—l±}p»¶¾qúÆ3î÷ªÆ†«–N<ùðm¿ÃV7_yù
+ŽŒ”Ûo?ç’×°Ëù <²t«\.SzÏûŽûS§Nxx¿ýwúÕƒ.Üvåʾ™££å®¶¶Âàž{mñ·Ïþå×wÙeë˃ ˆ×7ŽªºAc‰þ·&ž<.÷À„îÌ#KWV·XÒ_ßÞ{Âb!Ò(²šÏYÖz#¨¦q*¢`ð©MáÔÅO,VÔ!;n»É­Wßxï^?ùÝßßø§¿Ý³÷Â%}Scç‚8qOmŠ	wÜ·hÞμà{‰ówÞ|éãÇ¿·³£‹±@ß@Ñº—L”®V­\5õ­Çþ¿_x¯&nÄÑÑ'÷•	Æ-X½j&€ª"& $êTÜ~¯ÙõOßúÚO>|Ƈ¿úÍ(Fœ™<eü#{ì¹ýïsÁW¿òÓïf2QåŸ:儁‘	§žòÙqþ?òŽSŽú¿b1?|Èaû|ol±²ÝvsÖk_¥ª/(\‹ÿK´ÒѵøŸeò¸ì}Ýíáҍ­Ên.ˆD¡EðµN>n¿ßF΀*D›Ïžüè§>xÄ·¼’ˆ s7òà'N?ê«a at C±Vt§ígÝ:o‹oU¯:©Ý°ÕV³ç%ÕΛ;ýžSNÜï<1¨IOm+Š¼zë™7O›4ÆÞ† Œ›8aÉ>ì÷Q'½=yíl`Ä2}ã™Þ}ú;?nƒ@£Ð✗ĩÆNeó-6½k³9›Üå½óÙÈÞlMš®iöì·þ‹ï?ll¦LðÈç¾pÚácç¿þÕŸNðÇ¶ëíí\~Èaû<Ö¥Å‹ÄØb¥³#Yµ²¿>g¤Ré|&“É.°`DP^»Ï¶+—+…¶BÔ0!ÁÌi=ˏ?r…¨XD
+ú¦#vÿ팩½‹EöÞm΍¹Ñ;ï]¶™ô]ošðØc+Gzó™¨ê
+©	¼ç­¯=·^odkõFvÆÔq‹wØfúCq«Wû÷ÞöüSÆß_k8ò™@vÜ}ç?wtv¬D]0}Æ„ÁÙ[ïp¹*Ò;nü’CŽ<è'¦LY'J.o(—^sàî—Ϙ9yñ­·Ü·µsI8eRï?öÚkû‹ úû†&ÍÝbÖ?9tïïO:áá©S'<ü–·öéL6ª4qÖ9oçÌÙèfñ½n÷Ÿ<Ýb¥E‹ϝ–0ØâšlÆŽl4)wcÇH²âÅ¥]Éæ;»²¾ž€¦é̉	ñ!Ð4Ÿ‰BâÑÔ•Ã(à•(­Ô„†‡Ð‚ó`fL¿p×WÏžßÕQDÐæ»7Uã(äód#Q!C
+íí;ì¼íß{z»—y@­Uêˆ:T,VÄÇNÈå™œÑj%‘\Æ‚ˆzçð vÙãscõª©Õj½pÖçßwÄŒ“<û-^:ŠÁŠŽb°r´’L~xE}¯ZŒ
+!ª"ÍÅŠ°÷¶‹2ébéÓzúN:z÷KêÞaŒàßtÄF!u#ºÝ¼î˜7w£;*U¯ÓºÛ4ÐÄ¡cI¶z»‹»ì0{~šV;ͽ]‘z{Ƹ׼óÅD¾\®4+6°µ}_À®Ë´)ºbuË„In|øë’É„ª>‘ļG‰ÊæsgÝ3}ã™÷dBÕ|üÓ4+ã'ô,9ù-‡>)lÈÉo=ì3cǧ¾ë¬ëx`ávªjkÆÆlѢţ%¶hÚÝ<üªMÛ]^Ýi ¿:­·++jMÓÌ ¯¨I­Â¼€ªÇZ›jhPcH¼‚$
+ÑzŒ”ëh6B*ô¥zà~¯úó!¯yÕŸTï‘0DñéÛ¼³#‡j@µ^
+“¦M[ð‘O½÷“‹—
+ÓHj#O걂±KÄ9Á;K<aÆR¯{xA$ñË<÷$îï=í¸õfh±Aж|°l“Irí=Žîߨ‡ù)“¾ž@*Üa¼¦>GHºhqJd-‰z´ië*¤A•4ϱ¡áS£Â†‚x˜6©{ÙØbE1ESç“ÄC!‘¬z¬d3Í·µ
+ì°ó¶Ÿ8yÒc^UÂ0ÔÒh‚h‚ŠÅ+&ñÆç­ mÄJ.cñ^U½¢¨>k6ß|ã[ÚÛ‹³6™vW[{aðÅö-þ·àë\{nÀ^-ÒW8	×e‡ØûݪÚz™ÿ›$N³w?<ºÿp•i[Ínó5'ŠACCbmªÉ“Ô[Ô«â½Ç^1F¨*8+©–¥£.F{Û`¸ŠZƒ:¨ˆT‰¢ô®NÅQMœÊÃG½
+,º³Ú?Ta¨T×Ðf´§Ó Vû+¡7Viˆ:y|Ö–œä"Ô©h&T,B­ž¸žŽL+hô+UìʁÆKV7vÙlfžrèZ¼*„Þ¼|*¾áÔã%µopÍk
+BT­BhÑb¤”¢Eé5çÀÔy$ŠP^	´\òZ®ªÔñqÜ`\W K—R&£F½d³ê+u#a`¼ˆ§³-Юμ–ÊuÉfŸ8/…¬ñªõ˜î¶ÌMxx[<DdƒÈ
+eÞ?µÆùï†ò«”d˜’¬:ÿqÄo‹œ³äÙki±6crÃSâ¾dÖ‰L9mC÷ã™è#º.
+,
+ýd¯¨ðÉ	ÿn]17e†Ù÷Õÿ±ÎµxZ+µ-fÿÚžcéÒÇci«ˆ*µ€àED1&5º7BâSí ^	¼GCMM!"Š'Ý–T“HØÔË«G¼"I"Z­*¥RBµ’Ä1Î)I¢„UAÕ‘‰ŒA½s‚‚ HcĉàT‘ÀˆX+$NŸ6^h‹W"¸I=ÑÝ¡øe·/(™Bˆà1"¤€ÓbF"‚ƒQEE0*„b0bÀ{ðŠXqLÓF!5‡@Á»¦&Ð¥¦4/‚âr9Cg‡addDâÄᜆ©çUº§œËgQ’TåmÀ9!² ƪ%Õ¦¶εÛZ<;#¾e•³¯SŽW4:ÿ(çƒÏzVœóçÝ6t_ɼ"·‰•8IqC÷ã™q㔸Ûa«o„ì>òïÖÔàÒž˜¾
+<%]N‹ÿ<Q`ªÛnÖ~ٝì{ÿ"·ÉåhxD ˆ¼*N,â=Æ;Tžæ–ZÓ<OÃ[k IâC	õzªR´cG`M($†U+û˜2­—þÕUꕘl&’Z¢šxƒ1‹âe¤\¥4«ˆÅƒµ†Pb<!Þ'XcT¼Çƒ1"/y Ó/ºÍfíXÙ_ßü¶£{l»yQ*âk, øÀ€SŒº5rž3B¢JØ\+,®Ü ç °hâYÇ{ÄZT=x—ÎÖzÕ+‚TË5-—j¸F¢Š¡‘(Å| #•F:«ETHÄTÕšË$.í4}`2¡Uò™ ¼Æ²Å+ˆ˜+ÏÍló¶NnûóÚ÷J¼kÔ^‘òÌË…ç­¬saq€Iì§ãœ¦½Ûñ@ PæƒS˜ùö!vØ¿Ÿî¯±ã>k?Wæc“˜ðñ~z>7ÂÁóÆ®±ËCì¸Ï 3ßÖO÷—†ÙýIÒý0{îÒOÏúé8gÙÇ>qGeßÜO÷—‡Øyϱ«%Þ;m€	KËorB•¯õŒÝdÓãG8h›&~d€qŸåMk²ˆ(Ub‡ýÒ¾¿ê AfXæýSŸxvîýt}}MßÔàŠüØõ—˜rZ?ß`ÜgJ¼÷)q=˶t,
+ÓãvMNHëÚâ°±”5¾×9À”Ó†ÙgÇ~º¿<È&'Ô¹°˜ŽùOß®g€qŸ`Ò‡žÇÇÕâ0u\ö¡Õ«FX56¿)&5¦¼1`,"1é;NÔ+FšÚBÀ{Œ¦öX¢Ö®‘Q¿Fó‚
+`ü„¬‰ãÛè×µ&˜kSH÷üÔH¤ê=hÏY*7¨7P¥ÞHLSOCœ¨†¡T_Êqkñâ3±'³`Z¯¹û%5ò!„1` ƒ`ך›ˆ¤"ž˜¦Í«¦óÐ+&I<Þyl€ Íù¨OÌѱ é.þAò9“ËŠP(äÅ«à}ªŠ´’ªªŒŒÔƒ1p1±¼W@õ¨*ÞyÍD¦%¶xF”A£ÔçA°¸ƒ¿_µîý"ß]Tä'¬{½Á¥…Aæ9À¸O0îÓƒÌ=bLfyr™MNáàyu.hKßõ½g
+²ÙÑC¼zßAf§TŸbתšA6}Óº²NÂ-Ñ [2À„ÿkÖsLÌ_rk—“†Ù÷Õ1×e™÷†ôý>óíÿþ(½0ž·0Xâ„ó•ÊF–¹)»±Ó—÷ó,9ÝñÐAó.vÜwü >På[ÝU¾rdûæ^sõGÙâp Ï¢mný2øÀ2ë/1ÿøÊ('n0ÄöûÇÜôuCçý!{ý ÂúX?<G(qÁ²éŸnù܇n•^¤×0ùŽ=¨ÔÛ*œñã'žYñÚWAè~X软Îo~£€Af~ܱàØ€­/r,Þ˱ð£	÷M`âG<‹Ž°l~)$™û=¤“a”£«”glw¾a“k•m뎙gõ1ŽÅ´9_õ¬Ú5`«‹”¡éÃìùÓtü=+NM¸íM[\æYµs™Sß›~HÿL)`ûË^ý§çû™µø÷èéŒo³yÇõ<2DµæµÑXD 2Lh‘À ÆŽ…þMÿÏÛ2³Q#H=F­1G!}Ñúæ™ ™(%•6Ë•úšh°NSë慠‹©6b1ÆPˆêÕšØ0Câhî]Q&ï¡Tµ³µò¶þ²ñÔÂÍå‘ruኺƒThҐ~V@¬Á™T0c4Jt:‡Ç+ª""‚ºt±bš«Ž¦\÷¤ÅÊ„	ˆ'´ÑÕÓAÚ$>5žUÒÆÓ_AºXñž¶H©8*Õt±'N‚f¬&¤Þpÿ±üª-þ;º<H
+ܤçô<û0Âë·áÈ«¾êÙÍ3xãþo±õ¥>3~¬\Ìߺ|>á¦#K¼í7ŽŸWFvõ¬zµgÅfŽ‡¾4;=µþƒwq<üEÏÊMÆ®òæM†Øõrǽçx÷S†÷v<ø•a^wE‰wÎ+çYfÓ6o=n„ƒ~ê¸çžá=•¾]^àPýÛ</ap„C·Rê[vpõ:™]–w~D:rLƒ>ÛÆÏÎèàºùYÞ}†gàõ U¾zŒP¸9ϧá-wìpŽgÑ!cõ
+¹»ºYü½Nnþ«¡óʘë÷pÜ÷NÔóºxäçí\zw÷^üÄ3™ûºYòNþy¡ç²„[÷€4àu¿ÿ8c÷ˆ’LXÛ^Ï0þ².‹û'„‹G9~€gàuYÞùÉ®ýGW¦}x ð¬zkÄÁŸÉòŽÛs|òBÁòÆ9#²³OëâþtpÍ?;™]Þ÷tãWá3ã•‘²œú™'ߝ笟(ñÄ*_îMKhTà¬Oupͯù¶2´@ȁÔÛ¹ò¶±ôx-^Æuf¶åí@¥ê4gŸôBÕP”dL@Q/ÒLY—þNµ„¤ïW˜ðgÖJàÓôvÚôÚlÔ•R9±jÁ»Ô˜Ë4·Ø<J֐ÏFûç=ÆZAMSÏØO4Õâ¿#$›Í,Þ¼dÙˆŒT½JSг‚4Rh
+Î6…AY;¿
+éoc…0‰“æb¥¹RQŸó¾iç
+Dc‹ V‹1bH#)=±XIS’‰cÙÐÓh$Hà55´UT!q^ª
+ךŸ-ž¡ãrаÌÇÿ<ÀøO³ÿ17eÖW6æ¦Lƒ?$ÉpÒ~½Ô_ÓÅûl}ŠÒ˜SåëŸ\÷Oÿ›…öùÝ,›ÛKcïNnÿH–“/|G®[>á$Ç)Cªªó«oƒëŽ8øu½4öîad·€WŸn\ó¿¸nÊðáYÞÉ¿šmÞóòÑö“»¸p~áü±-Ì1<Ë&
+Ñ‚€í ¾¾ÌhÌåMa+\qH9½÷¥åàÛ«|¹W)OWªs˼çÜ2ï97áæSÁ¬Ñò	ŵ¨Üj¨ŽPâ©sÖ›¹cíg„üj¨N f]Ùìʘ¼Ñ³zS at c®Y³l˜ºV[ÁjÏŠ	5~Ø®«ÀW—AšÂGj|w"6¸ìcýi8›ây|ª»Ã0é9…툹qFZçÙ_«K—Ç\;½ÙŸYÞ3`yÕjÅýÛN'-þ3„T'tg®!>õþ5‚ZҐ‘ÁYÁ·&Ü©fʼnG]º%<¦8\³gAsX ®{V÷•¨5b@°Öé{Œ
+QPc„@¼fC/•†ÅêœÇ{ň’ͤ’¥÷ÞˆðoÛª¶xù3¾+óhW[°bÙªX³©0g°ÍÅŠÓœsbD½¤¡0×,V ñ
+®éÄ4¶lh.Vd,Φ5¨Oç«V+Ž‘R§FcIœ#´²f±’¸D‚ÀbEÉD‘&>$qc#¨5"ÙŒEU¥\u¦=õoÁkñŠ¢È>+tŸ®Ç³ú1½x˜Ýîé§íÇÃì¿ÃÚeK,$S¶ÿÄXú×±,bBáZe䐵MÈRÂG»xàscïsËÌ$Ï™ù”áƒÖÞê­saQ9P(\—ãc} Ãìu4¶°Ìþü˜ÒFÈi'ÿ¼FèüƒRÝu”c7{r›¶¿ß|L¦KG»!xŠ0ØCõð^â{‰wëà…§/W›%Ü”8u:øbÄ¡+ÓñŒ1ÚÔvÎäøpŸPX,DõP>þ‰Ÿ‘w<Q³¬we(„î}^^´	·¿%`˯ôÐÿñ6Î?\÷³=“æû
+}P5~ҍÍÒ{ïZ	øˆ×ŸµvÿS-æ”…Ju;ÇÂçd¸²ób “çŒ÷¯]W3]ÝÓb˜\ž©L‹ñ]™%±Ãi3 /<I¹b-icš6ZÍ—hœ¤žÄ±B¥YFÆ<EĘ'¶âÄ@¹3\NH$L-ýMÚb`2U"+äs!¦éÖÜðš:’!¦	¨U•ÄyQ•–=Ö1•ú¤Þì£Ã
+5©¶Cê	Ö‚
+2¦¬n.V‹uéxÒ¤–5¹ìÒm\ÆÊC*®x|”zÑ8/b!‰ÖZŒÒÅŠ
+Œj[Á &LàiVˆ'MðUŽBS¡E‹g!Ñ¥ú?^仯²lþ¡ë ¥´Ì_/dËCÇÊz·T7ÈV¯ýa@ƒ?nºvýBñŸévô“1lô;Ðb‰¼vìZ…3ÍY6Y“·ÝóøÜô¨^\·MÁ–÷Î^»n!w{ø2	ë÷¼¼oÚ¹èÞ~òw³ÛÙ–M.q,x«ÐõëˆCÊ5~ ˜r‰w­Ê×/r,x‹¡ç y>ò«ïó ã?a™ûWe¤]šÔÅ£?}¦ö,[/áæ¯
+0Ë&·{Ïîâá§Í/ äq<|ð;7÷½¤þLåŸhkê/ë\|nÌ´‹”þ}À®D-›%†‰ßipé×™óä%Ž‡vÈpÄ%í\þ¯ºb«ï[¶<_)·Y¦/nçw®¯<g>^åÛVøìwêüú|¡sÀñà®ÎyÆ(ú9N(ó¡Ê 3ßnè^¼®'U‹—(’Š5Ò@ɺ±`ÑòÄ»´)VÕ¤>#hĐ$h{­'Í+kló½wihUtM`_@%PæPZ£„™P÷ëiÄU‰«™À(ªÔcð¯‘(EÔVÐ4¦œTkÉ褞|߆¹/Åp•o”œS‚1Ý^s®Ñ´sM3Ñ4G7í	}¥¹X	MºX3S0ÍÝ\cÒÅ˘P(6
+;S‹gBDPÛ4F™ÀhÕy¬ ù\¨Þ{i4bM¦ãT62"@âœ$Λ|6\¾áF®Å+‘,§e9åBà„[>9‘'z}Êqÿg”ê¥BN¡>ÀñÀg×_‹U†ºÖ¾"dW­¯d‘oÿy˜}G=\àY|˜Á"?ÿËX9¥:-msáGž¾ÍJ瓯…ëmsCð¼]±Û¹âÄQN:ɱp_Ãä?tpÃ/Çî	ᣖ-/p<øš€íÏîàú¿4·>_[á‹Ç'Üy”Y°ý• –Ùÿx"	X6»ªY€Næ_7oO¸åõ	wi˜4?-³ù-PÎ=ñÌœÛ=ý
+|ëì
+gæxpË¿V†®¶l½À0ãâ€yÇž3lt©eÞ# ]<òó2₩Áeû…ôÉ:—üÂ0³ ›å_b‡»íáYµ¡ûžˆCû„œ¶så±£¼ùÇ‚7™Õ–×Ü–Ö=ù;–Íêéñ”ó¶IëZö‘!v8ıtXª†	·…ìZUFaêyO|0[USÖä…Íóáãêün/OßFÏ÷3kñQÈD&‰– Qnÿ6_¸®)ŠiÚVyE
+0
+¬®¤×bð~L ÓüzÄ)Z®‚‘ä-*ª¸¤!Šj½îñ>Ñb†D
+Î'ê€À¥û×Q êD¬ljt·gÞpƒÖâ¥"›1%±ÁƵqMe_˜têU4u&QkÐz
+ènGo
+‚@3ç±oiÆTŸÚ"–êåQ§jpDÙœZï©Å
+êqƒ(0ˆ¨º$»DŒµ*ªX!
+
+ˆ¨z/Õj<0©·ÐZ¬´ø·	ؾÑÅý?ê§ý̨͐ðéI©‰Z´
+ª®ƒ¶	Ùå9)„xÛꐽjBÇ”Ác*|r‚g0Rª;z~0oM^l!³J<Û'ÏY+Ÿ[“ëßÝ<oa0d¯Z7‹¾ÿt÷;¹ézàúu¯gyÏ`–÷œ³îõ®ýÇ“ÏÿróÚçÍ-ÔÛž\æª[ž\æò;ÆŽ3SÊpÌzµ‡]Üûû'Ÿßõ‡±ã'Ï£G]UçücÁåùôšhæÜüà/¬C:¸îõn–œûÄñ÷…œvqÏ%4Wcd9y$ËÉ?;8¤ÜÍ!?;ÏsÖÊ<gýz}W‹—ÄiÖiºÒT‘(¨WÄ
+Ʀ2"±¤1ÛrÙ4'±1`õž4´ÇÞéÖqjœ…6êÉXl ŠWê5±Fãj•B[Hx-f­ŒÖUkµTÚ4x#6
+ÿ!M¼ïéË„¶´aG®ÅK÷jÂ04h30cÒøÑ©•ÂšÅJ(©í_’@¢Ù F©£Hs<>uDJ祤V'èÐh‚ØPòQj7ÇuQT‹Y«êrQ–l¦@=Qêõ$µŒu/"EãX%°J½á¤»#»hÃŽ\‹ÿ<‹-:¦tÚïW†+ó];ùç5/´€í.Œùëq5~z$9@vûÝÚe„žûa5u.Ü#ÏY¿}¡m¾ÔüÇ2íUÈ>úŸªï¥Æ³ºXç·gÔ8û»Jej–wžø\CZüwÓ?ܘÚQÌHŒ·mÞ
+±§ù¢”t‡×‚:ðµ:ä³øöÑ ݺ¤/Ù0ÀY›FãˆcÄ;$ñHA!żh'ª ‰¾úå  
+ïIDATêœs–BÖh[.b¸æµ\IÔƒQ¯Šˆ¤i$‰Ä±3I⥷3sÿ†·/
+•šë*‚À¥Z<µàÅiÔ{Ÿ™> µ{m8´3•Ä 
+IÅ$	jêÕ”,µC¡io‡h&¯ªÆZë5r9+½]‘f¬—j#a´\Ç©¤žS‚D’8@÷¦˜·+-žý:Ì®»¯}­Áùaö;’ÉBæžÇ” 
+|þ°«n;k”7o²ö3	·DClsàói;UR…=åY}$DÚ¹äI‘=ÚøÍ¥>ìxèã#²ÕÚ÷ƒ!¶=à¹úlþckãW /ëqÏDÓÎï-º-^^¨bF+n£Éy_®¨	Û$óò„3‰Ž%mÐD¡£ã‹0\o¾h‹€‘5yŒE=jS'Œmnсz‹ŒŒªz…0’ZCÛòµFBM#ª•8UCzƒAɆ¡#¸ÄI˜±$‰¾lìPZ¼øŒV’žžŽ€J‚¨)‚£Í½(ðµd,D­$©P•PÒ]eµ5¶™¡.,ˆ—T“(NE+åç!¡-jÒhàO]C­V$°õê1Íe#¢P4q΀ùê"Zü Tv‹¹iß>ì¨>
+’(õ­A0ýǼo¬l†ãGküèÔ˜Ωóó«üæˆVB<^©oN:ù®|>íÆÿγìCéñô3×½0/Žxý{üñ»
+.ûc?¹; ZqRß|Ò7f¾À‘xqxÙJ©-Z¼(W“î(—)ÖcÈDââ"“îþÒô"–ÔiDë)¡Ýt¨Ž&Š†XK,’†csÍôu¦ãCSïÏÔYÒû żŠ§¤YÕ(dh`˜ÑŠŠ±hà
+NTŒSrù@ÃÒ+"qì—NèÎ>%‹ÿN¼'­ùYÓ¦ä}¹‚Ø"Z0–nا뼐.N’mˠõԡ$Hm½1¸±X„êR/b1M§ÀŠE†U5D¨Zïh+„xQ-ÇASЈïq ¡µF+ı3 ÙP+ä‚Á
+8l-^ùѶ5¾±§gÅvJ}2øŒÐõkC÷½Eν(dÿ'eZêàÚÔùõÞe>zŒ2¼9Ä ZbwUÄAkœ0¶6Lú†eöügj?Ë[~Sã¼  Çû.^_™v.¾'æ¦ýJœp´gp.4¦@´ÒÐ}cÈ^‹Ðb˜â“¾a˜r×™ÿ-a°E‹g ‘PÌf­)×¼/äÄbšöXžf°£ª
+Ä–bâÞ"ªé6Ø`MîbL3°´j·
+À{4HsÀJÃ+õX40ÐpVFčX¢@ÕyQkUSC‹h&c±Æ"•Z]2Q82y|¾%þQ©%Q&Ê'	d"tÌ¡)õÿX£¹ö4ö0ZN+±G]ªR	Lš¦®¡ŠxŸn57M7Ù¡&]°ˆ—T@ÌFJÆzFÊ¡jÒÿø•ªcQ«‚1ˆ†d2ÔIœ¨„Ö,í(f–<Ûßբź4íêÿ üáY7iúœ÷ÌeŽÍpüן­®<g>žçÌg-²K½‹G~þLe“\7ËŸµ®—’–0Ø¢Å3 	ŒøJ"ˆ£éÖÓÅfAk^\¹†täð±B%FÖâ
+$~Ìò´©Y;X¡µ¨÷P©z­Ô=µzB­î4F†KtwD8ç´ÚHPDŒ(A›F¿•‘RMòÙ :¹7÷²Ye¶xiˆÅ\ÖJ߈êäqâPŒOB´9?´ì°ÎkKíëD	mHb QRç#iªRÍ7h­áÅ‹Ñ8Aã8¬Þ7㜓\ÆøZì0VTðV+Ú  "^ÊÕ„b>ni­[´xyÒ[´x¢@Fë>CÓÒôÔÔr‚¯ÔÑÎ\êa\©cŒ–JÓPKS/TÕTm£¥ªR*ÕI’D¼­7<Î9UM(òŒŒT@¼ò‘öŒ'ÎDÖj„jˆ±¢mÅŒ(iG{T›Ü›¿Ãi9<ýï!F ÑH3³Æ@Piš1ŒÆ¸JÛÛ†/'P‹‘Ðb£º6…?h¦Nl&LôªV°¤žñ±­ÔÒüÂÕj]c­ÐÛÑh4h4Þ	Ôˆªj`ÆB”J5Ú‹Qm\Wöž
+7L-Z´x&ZÂ`‹Ï@62C£U×74R뉢¬Žë¶‚¢¡¨U¨ÅЙ#øjÐ$Í`ÚüWM3èîð¨§ZS©Õm4¼S¼w$Þ©óŽb>¢\«K=nhG!0IÜð£Õ†ä2YÅ{+„‘•|Ö˜J¹¢“Æå–u·g‡y®±´Zü…2Z×4¶ ªª¦1¢ !h¬h­ÝE|¢ØZŒ!°BÕ»f\AšêCß\¬x´^JåzCÔA­¡êœSïÚÚò”+uœÆm¾`”†Çd
+B«Qh¶bÆTÊ5ÍçÃÚÄžÜÖÈKµÕ¢E‹g¦%¶hñX#I[Vîʆºçò•Ué(潆FJ±hµŽt¶Sm@¤¡gœÃ¢$N±‰C¬Ái _)yê
+§‰sÚh¨xŸà], ù¬Á%^jõªõ¡–«
+ÉFU1íŐU«G˜Ð[X=¡;÷І¡’BÖöUênùh©2q™†L›á<¦`©WSªÁ¸|êE\©c¬ ¥Ajeà!Oilú3ZV††©7MœÇ;Ñ$ŽÅùD=J[[¤#åšÄqC#«’Ä
+Sª6M¨¹Œ%vŠ÷*½=³jõ°Nì-.›ÔÛš£-Z¼Ü	 †yÝa<Môí¯(äÙ‹´x¾rvY{!X:R®Myà‘ŠÌžUÔÑ2¶Ró®·Ý0<êd¤d4›S“ÏáBkÎcêIjŸÍ#µ:'¶\©«sŽ8‰Õ¹Å+-d3†‘Œ–J^T0"š	Á'Ps‚µ*™0ž®HGuÖôÎ…pņ›ž|Ä‚L ‡2±7P	öU‘jÂj*qø<pÎa\âÓÅŠ1¸Œm.VF=ÕºWçÑFËs‰x× DòYƒ&bã¤æ/¹l¨åjƒ(0*ÖJ=VÂÀtwE<¾j”	½…Õ-A°E‹Wð¥•'¼E‹gbÆ„Ì¿âØíÓ?ìÚï‹124Xdr¾>8šh¹Øár­˜Àd2APÈ‹ŒQc TQ††cÊÕX“FS tAU
+Åœ4ÎÔFF’lƨ±Vp ^­8«ÅHÅkįœ·ioËQ¤Å
+9»ló…ënY0¼çý—d¸¢‚ØjU™5Uâþa•á’`Œ#ĉ5FÅ£XÍDÆg3ÈpI®Ûr%Q—xœwš$±ª* ÚÙž—Z#6•R)1¢dBÑ®¶ŒÕµ–±ªÒÛ•Ô1:Z·Ù|Ü
+c[Ð-Z´xù¨ê‚
+݉-^îX#µYSò×X[Ûe¤Ïç3Çu7RΊ$
+©–+L”	°Jï%[P‰2¢ÃCžF#Á%¯睈ˆFÆPÈEÖëë.1Fjç‘(@Ämíy$Ÿ	Ê]máýùl0´¡Ç¢Åˏl(ËÇu„Ãýî½TŽÉd-Õi¸¬)Uâ¤Ö¬ú¸Q7Æd2ä²ø(0 H#V‰©ÖœºØã5µ
+”¦ã|>—¡RmØ$®'¹ŒcMêåUlh¶C¼÷¦µ+gN*Üßÿû©ñûNáï
+ݏ/eU éÊïÿ·wo»mA€ÿ™].IQÛr›¦Ò6-r‘GÈô­ú¦Ú´IÜ ’B‘²xڝéEìÛ¢‡ B¬ùž`÷f÷ÿAbÇóOµÇøÅÛíøª9Lù¡9¤ïŸ]!)éþxÿÕWU–U‹¥× ›í„»ã€˜’¦˜$¥çYE‰ý h‚‚™4ÏD„ÀjUÊõ*ÿíj~É<Û¡kþVLZl›øâíŸý!/òº¾KÕr9øc;FŸåðޡȝä¨*Ö<-¤®{íLj'¤•êÊα*hJqòÌèûŽr\_” {ĤX/Ûù,»µ²rˆøçûGÌ£ jaИÿ@îýnxqó{ó’ôÉõ‚ƒJß	|´ÀjÄ;ÒF“vCaú¡CŠ	ìX© Ï%jÒ—ëâÝÕ"¼.‚Ío5ÿNLRÞ¼ëjSÞ6<¶Ò¤¤»6Á«¨JUzY_
+Zï#öMÿPV4¥¤Ä"Æ]?„ô¾¬„@’`>/ðäªøÕÊŠ1Ÿ?ƒÆüý˜»fú:&a"÷Õf?®D at eîÅ9@‰ÐQûnÔ8M v48GÊdY︽Xf·žV³Ð¯Wù›SïË|ÞDá6õø¼ëc~»9ü¸˜Ï\Ñ$N‰œ†Œ±\x%†Q›¶×iÁL‚CG UG	Á{rY®O×åMQxÌKÿ¾Ì]{ҍc>	ƒÆ|Bªpc”ån?¬cÂ,‰¸iÒ €@¤žå˜y¼ç±*\S•YÍLrêu›ÇKD³ºžnêþÛ»^¯w úñw…$ÇQÇqÂ0LˆqR8VïœzÇœe®ÿî›Ë×eà]UºÙ¥aÌ#caÐcÎÄCY©Ûñ2&-ðq؈ޏÊ!UQÇ$Ì”ÊܵË*ÛZY1æñ³0hŒ1ÆsÆøÔ0ÆcŒ1§caÐcŒ1æŒY4ÆcŒ9cUæB¯Â    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_struct.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_struct.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mapiproxy_struct.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,149 @@
+‰PNG
+
+   
+IHDR  =   a   =B¤   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœíg˜TUҀߚÈ09*E0
+FT &T]sÎw]]×5§5£~ºæ,Ä,( DA¤  Arž\ߏ:íô4=3Ý·{pÞçé§ûö=¡ºgîí:u*ˆªâñx<žm™ÔPÕÿV££NÀ»ªzUuÉáñ”GZuàñ„‘öØÿäJU]YÝòx<ÛÍ0¥§N5ËÑØÉR¯šåðxÊ$¥ºðxÂü\[Ý‚x<5I‘†"’GûZ´É)ç|š›3£‚qjÇ"“ÇSSðJÇãñÔ@Dd?™ «€\ùCD—Ñ%SDžÖ›Dä}É
+¯ˆ‘•Àz`½ˆ¼'"­ÃÚ%""æ\ "—Fȶ»ˆü l‘e"rA?ºÇSiøí­éˆ)¾+°›à¾@0AU7D´MvvV3Uu]Øù`'w83qïü¤ª¸6Ý9ÀUý=ë»c¦s– ?ªj‘“©½kºDUׇõk¤«UõÏX¿§ÑûŸXì	Ü/"KTõµˆö7¸ö 퀓€+€‡D$ˆ)E¯=“î"ÒEU7́MÀKî¹;v?-"Tõs§H}IÉõ¾x(Jú7àñ$UõôlÄn’Ï?»×
+ÌZ„µëq^1%é²°6§…»[)*p†;1ÆÛ@ý°1V¸÷ïrÇ)íCÙÀ€ ³Ü{Ï„Ó(tïŸRÝß³øGéžk» 9îÿúÍ°vë(QvZ ©À\÷Þ{®M¿°ë§{¯!çÞ»64—{®-pº Ë\›'ܹsÂÆäÞ;8ì½Wªû»óÿ(ëá··<  ùÀ+îxWà ©|ˆÝüV  ?aÖš!"rd”ñ~>ÆÌìÿ2€‡Ë€…˜¢ôx²}†­VOÂ|}§TU'\»A"’í^Ànü+bù<žH+ùØ,ÀüÝ:„ÎEiÿ¥ª.UÕ"ìúhàž»…µ{UD–3±ëìúè$"ßaVžùØb§YÄœÜs1ð‰{=³ y<5¯ôxÀ¶ öQÕs€Ý{»¹çã)1cŸ£ª7cæî\÷ÞeQÆ{è ªýUõ£°6ã1«Ò(à
+÷ÞYe9Cªj1pœ“)ËÍ’¯»sÄ|[éæ §»sÝókªš_Ág÷xj*ϽåØ"ä$`º;—¥ýü°×…ç
+Â^‚-d>ts<Ltç^ö½~£d±Ú†ý^†‡œ«S±íd§Fã}z< #Ã^¯qÏ!E¤cع	 ªš'"“0“vøùo:+LˆÐÊ°¶Z
+G0ÿƒéDžÙ	ø†’Õm8µlUÝ("ÿ®.‘Oœ\ /Déçñl+„üÕ>SÕÇÝõíz‹…Éa¯§¨êÐˆôþt~?mÝÛCUuˆˆìì1ÖOa¯/‘€A at 6O
+Ç[z< «Ã^Gœ[öºMØëvQ·øµŒ1¾Έòø£¹®Ãž-@Ì™ù(ížtrïÜ…ý_OVÕ­)g"d
+ý›Ûršƒm;ōªŽÞu‡O‰ÈùFD– _eõ-×æ7çÌ/œ)Y¤Üƒ-”ž*›ÇS•xK§"¾ÆÌÙiÀ­"ræÙҝÿ2†1F {c
+Ö(l»ê@àXU}«Œ~!þfluÙó*…ªÎ‘€1ÿ$€ÿÅ —ÇS“yÛÒ=s¾sà?óµ	ñ-–˜0<ò'lë)Ü*sf9=³è´Å¶Ä^ÀYq1ß»•Ø¶Vv½ãæý@-ròà1Ìz» ¸øæiÍõxjRz³#!"1“ô­ªz·{op0BUû¸÷nîckËà7ÀѪZ "§aÑX -UuiØ<õ1Gǐ³d%ûÿ¿©j;×nf͹[Uo‘ΔÜ@‹±­°É@÷^ŽZ˜-"r˜“Ì2ÔBÃBê=Çãñ–ž›{°ˆª1ab)(mQ©êƒ.ŠädJòô|OiߝXX:@©?ªºVDöά=ͱÄg3°è¬`JØ×o–ó)8‹BùØõëçÚÿ夬ª£Dd&–Óç}¯ðx<'oéñlóˆH +ž^衪S«W*ÇãñÔ4¼¥Ç³=0¥ÒÄ+<Ç㉆Wz<ÛC°mº”8dz<ÇS
+¿½åñx<g‡Àçéñx<Ç³Cà•Çãñx<;^éñx<Ç³Cà•Çãñx<;^éñx<Ç³CàCÖ=gGDš±Ìåe=ò±LëáßU5?Ú˜ÏöˆY÷$É ê—ó(~Ãn´¿…jfy<žø‘T 'p¬{ìŠU>_ƒõ
+½®´Ú‡=ï,æ#wTõW<ží¯ôx!"iX…åc¾ÀnÀzì»Ö=Â_aU;`7Ü-8È=F«jq•~gADZ`ϏŽÄª›æãUµ(À˜iÀ.ØuÙ«è¾+üŽª.LŠðO
+Á+=ž˜‘(¹é­C7ÝïãQXD¤)¶Òìà}€¡Ø
+wœúNÙ¸8Ë:þð¹ª.­„¹R€Ã€Ó±Ãs€·0hY²çóxª¯ôxÊEDҁ€Ë0Sø—ØM÷Uý3Ésµb7ÜFÀ»ÀÛªú}2çñx¶D¤-p¶ ¸¢ªyU8:pv=öžîõ[Óžm¯ôx¢âV|§ÿÁ¶ îÆVÕö“ˆtróÄ¢oVÕaU1·ÇS¸m¬[Ó€Ç±"ºÕªhˆHkà>Ì
+tðŠ·Äz¶E¼ÒãÙ
+éÜ
+lnQÕoªYž#€G€?ëTuzuÊãñTÎ9ùvàràà>U]]½R•FDzb‘kTõ»jÉ㉯ôxþÂÝÐr€[k’eÅý \üø¸MUWT«PO’‘F˜/[.p±ª.©f‘ÊDD8¸ܤª‹«W*'6|rB "r5ð>¶o¿gMRx TµHUŸÁr‘lfŠÈ.TÞãÙf‘®ÀDà{àøš¬ð ¨ñ*v-Î&º“ÇSãñ–žÉžöNRÕÕ+QlˆHGà¿@ì‡âjÉ㉠®RÕwª[ž ˆÈ1ÀËÀµªúfuËãñ”‡·ôìÀ¸ô1XÒ²·…@Uç¨êqÀkÀxÙ»ºeòxbEŒÿ Gm«
+€ª~Ü-"·W·<Oyx¥gEDzaæô¡ªz†ªn®n™‚ ª W Ÿ‰ÈñÕ-Ç#/bywöSÕŸª[˜DQÕÀÀÑ"òš³ {<5¯ôì€8“úûÀùªú`uË“(ª:Kšø„ˆÜPÝòx<å!"· { }UueuË“,\ޮñߕ‘"Ò¸šEòx¶Âûôì`ˆH`8p¤ªþ\Ýò$i‰}¶ÉÀªZXÍ"y<¥pŽG€jºÃr"ˆÈÀqضù6iEölŸx¥gBDZ㱐ØϪ[žÊ@D²×Ýáɾ–—§¦ "ûŸG«êÕ-Oe#"/ µTuPuËâñ„ðJÏ‚SÆ/ªêãÕ-OeâŠ(ŽÀ2HßZÝòx<.h`<p¥ª~T‰ótÆBÉ[b‘¡ç<`QÄã§ÊÌôìüzÆ`u»®¬y<žxðJÏ€+)ñ>°TU/«ä¹êb7Úð›nðV½y1°DU*YŽ&Ø6×õªú^eÎåñ”‡ˆdaŽ×Uõ¿•0~7à÷Ȧb×Û’°G&Ðhåžwº£€€*ÿÈY—¿ÎVÕ‘Éß㉯ôì ˆÈýÀ>À±Éösq
+ÕÁÀ ¬*s6v“]öHÅn´¡›n3ìÆüðªÎN¦La²í|ôÞÞü—<Û"r+°ªžœÄ13«4à=÷˜kM,i ôNŽÀ$Þ©ª£“%§›ç`à ç¶”ó}â•ží9x	ØKU×&qÜ®À•À‰Àrì†;Ô…®VÔ7×=8Ø€Y¢žRÕeÉ’ÑÍu6ð/ ‡ª®IæØOEˆHsàg,4ý·$yV.æGànUš„1kc—¿ OæBAD®À4ïØì©V¼Ò³ã¬0“ûUõí$Ù¸SVž ÞUÕ¹	Ž¹VQý\¬ÆCªº!AQÃÇè„…{ÇfO•!"Ï«UupÆj]M±bŸ£3ÊéÀ¥X%õÏ°|I‰2sŽÍ[TõŠdŒçñÁçéÙ¾9»É$¬ðˆHšˆÜÌĪ¯wVÕ{Ux Tõ÷£°æ4[D®p7àdp–uúßIÏã©çkÓ¸+	c|‹¥dا2 U-PÕ'€ŽÀ2`’›;\‘¶IÏã‰oéÙNqÑZ³€ª:1Á±r€¡˜’|…ªÎI‚ˆåÍ·;–ž¿	V,áºZ"ÒÛfØÓW„öT"2Ûò}&ÁqNžÎRÕ¯’"\ìs‹mÿSUŸOÂxvSÕsËã	‚·ôl¿ÜŒN‚³¶ÂœSÙ
+€ªÎTÕ~˜óãÄd¬4Uu)ðp[¢cy<!"ÇaûÏ%8Î¥˜ÿΑU­ð ¸|^׋È.D"<ôq¡õO•ã-=Û!NQùØ;«†³¸|<¡ª%K¾8eUp¾MUÿ/Á±³±l¸¿&C>'"2xRU?H`ŒÞX¢ÍTuaÒ„&K¶Y¤ª'8Ö5˜CóiIÎ㉯ôl‡ˆÈ#˜/Ï-	ŒÑs‚¾MU_¯¨}e""€WUõîǺ
+訪KŠpO"Òó}k¡ªùÇh…ŸUSòÛ¸¯P¾¡ÀÉ]¸ý\àø!3µ§f‘""uE$5ô†ËÝz""õÂŽk¹D[¡ãœrúJDßLwÑ„Žë„›J£ô­vœÑ7[D2¢õ2VºˆÔ	;®Ñ·¾ˆH}Ó¢ôÍ;®WNßT·:
+g‰H­°ã2¿÷Dpòœ
+¼À©À[À[Õ­ð ¸-µÞÀÅ"’èêð̼¾{â’UŒû
+ÿI{ñ?OÛˆyÂÛ¦VQÛðëH¢´MIRÛ´rÚ¦—Ó6-¼m2 ž€Â“‰¥px´¦(< .Ô¼?p­ˆŸÀ8y˜s÷É’Í㉁úÁ‘9ºÏÌÆ¢{
+°lå!gûÕXrÝ&îøwlÛºV”¾EÀ| ½;^‹eBo掍€ÚQú¿Üñ:`ÐÜ/ÁæDéy¼	XƒåÄHÈBúØ\ %îMá}7«°œz`éh2>6hƒåÞ‹ì›ëÚïâŽW¸v
+Ýñ,P)ò{/>^¬:îw –ìQUÝ7H7Æ}X$U
+ñ‹†ù
+蟈¯’ˆ\¤ª’&\™sué'¦B÷=~š	}óìõÂTX%°·K9&z@–nÝv^*ä	tqmGdÀe´ã~ø;º¶_eÂáùªP$ðEFÙm?Í„£]Û-c3 k;#
+Ò#Ú†ÆÙ"0.Žt?ôSÓ G¡}ÑÖmפÀô48ĵ’MŠaç$´•=]Û‰ïÎSÕ-eþ*
+Ü´¾ØöÏ1ªzlr%K"Ò«!ÖGU
+8F:–èU”Lù¶žk×Ð2Nt%7~J‡qõáò%­l	7……æ?×öÚ=ÜÿÒçµau:ZgÇ«^i
+×./éóh38ûOhè®ÉWëC“|8Æå%ú.fdÃE«Kú<Ôn\Zr<¤	ô^»¹kìÃ:vÍp)<æ§Â'
+áÊrd¡!´Û‡æÚñÈ,X’	syÚ¶ O7‡ëÃr¢=ÞNY	-Ý}êíº]Çm²ãIðC\²ªìyŸm¬‡=]¶ý³aS*\oÇKR`hc¸úÏÒŸÿŠ¥ö›ðRhG¸kvt-øµ6œ_Îwödè·Ú¸{Â{9vÿŠö÷Ö-v mŠ§†PŒY úi ˆ%yX¬ª÷ìßxóªqÉüÄ¢Ižzõsp·9À‰ªúC2åÛz®ÛQ¢­{ªÍS<¹*g‘–ÀO@Ë ¥Vœey¦PT˜è³º‘s+°¤‹|$Dä& •ª^“LÙ¶žçÖVPk[°‚Ýc· uÂZ­£d!¶XÎÄ’]ä»~¡gÅrªÖ
+ë³[ˆ‡Œµ[°…nha[ˆ-ü³Ë™w£›#´Îss…ÅØb¼<Ù7c‹“´ÀÍ]žìœ\¡Å®{ì›œœ!Ùó¼á²o¢ÄX£.%ßY4Ù(1ŽD›w£;.»PÆß{‰Þªq¤‡åééLù0‡Ã Üƒ…§Ö8…þŠ&yx%1rÇ€ó“%—Çã8–@m¹k/k²Âãxû5931†aYÙ+™_2J~ Áî±u"ÚÔ‹8ΦDáûñÏ
+;J+
+PúÇ×>#ì8ÒJC´yëP¢4€É]+ì8%ÙkS¢4à^W${¥ƒ¹k=;BöŒ(²çPšz”þ΢É^›ÒDûÎ"e/ëï=¤A
+|þmx¶mÁ¬<óƒtvûôu€7“*Uòy¨'"‰Ü0?À²JW2#kUÜÆS9ü.á>xUÄi@ d bÁW·'U¢JÀYw®î–0?Ï8ǘl«‘W‰Ìõ× ÇqöºèT©Õ®=ñ’<×(`灿á
+æ\x[Mò㉆“ïFàHÇÛ8Æø
+X[ù7ÜE•;¾§lê‚Y#ªgiíŽE8áTàU
+äÏ!Ëá"r·ˆŒ‘Eä¹MDΑ¤¸3¨êwÀ,ÓrP†aO+‘³“Vsг­S§8Ú$µê¶'Qҁ«+l#±¼:A褨ê‡ûÿ…‹rë-"ÿt7ÚsÝM¸}²¢i\TË\ಆ©óúî~QQm4PU­ÊûÛNÀª§ÃR3FD‘ñXÀ\à^Ì2:³ùüâ®ÍdXùoÆFî}ÄJ(=O	‰f×ô$¡Äû?Ž^JÜ{B,L60"R¸¸‹Ì‡yÀŽ…±µV‰È`Uý2‘¹7߈Ȫº1@ÿaXh¿ÏÒìIm@•ÔÅRrŠÕË„Ûž~»þ†–å`,V¸ô¬ÆÝ?IK¡ªDd"p¶e/€F"Ò^Uç•Ã㉍²Sà•HÏ"϶I+`…ˁ„þ˜µ2‹ÿ頻‡¨ê?Tõ6U=[UUÕÖÀÀ"ò…AŒªÎÄ"e‚†öNH¥@|Ã__ÕÆä”,A¬ô G ?
+ +{ñ4êþnyUª:ÏeC>
+¸UDÎ$q	Ð?ÎÉ9K‘QIÜï£'=ŽÆE)pö†êÃN>–«!nYe¶ê©ê”€ý›_¨ê¹å­Ø\Zþ.˜‚õ•ˆô
+2g·¨Ü
+÷à°e(‡Aþúª6º«ê¦*œ°-Á-­{ßé蜵ÿ+ÎsÞU ôîr©*‚2螸2Nf•X‹ëæe·ñìôÊõ!ë5ŽJ'ÍŠ™Dn¸£öxxNUŸŽ¥±ªªêì†û‚ˆtM`c%x!Ä_(ÙräåÞpËP¸÷ŸÕ-É6N"–žXÖÕ œ
+L
+’°ÓEzÞ‘@ׁ+æûv	B%+=O	i–ø§¼ß‹
+éð?W§(5®
+Ûÿ°L8Ú^×_çŽ(9WCþš
+é›àŠˆ¨¢gN‚Ü°Ò™ë¡Õlè?ÝŽóRàésíõŸA¥ÄÅˇÃìË!g
+üã^ÞÆß™‹àöD¢
+ÂX^¦µ†Œ8tArÆL"7Ü–@Ðdˆûb[ZÅÛWU§ˆÈÀG"r€ª.¯°ÓÖc,‘ù˜?D”ý¿ çè#ËRk~nÂÔ"Hɇ”íÌéz"’R…ш‰*=#*lË±ðñ@¨êX¹KJÚ+à0¡-®ÑúÎÂòy<•Ìœô4x§*§Ñ¦4X–Äíý™pòT{=êLXíj°¬ÿŽRí°½á‹JŽG_Z1øãDÈkWz®ùÀ´¯àŸw at njɼ‹¦Æ¯ôä׆ÂæPà+)¶»$ñÆþ]gÿ$¤-ƒCOIΘÅÀÏA°Û<ò£ÁoÖ×ce/Eɨê{"Ò³P†aØ
+7ˆÒ3‹JµôLδ œXÑ–·€‡üt˜·´	}æ¸VðË^ÐíØ/Ì*0¼+,o
+yumÑn&fõ{ý @àèI0rOXÛºLƒÙùÝfƒ<
+õœ?ɯõ`B7ÈÚÝgÃ×@a1Ú¸”ò_v‚Ma×ù›³÷†CFÃ+a~]³/ljõ–Á±¡a¦ÀÛ½L–C~€Ö›`Z˜ÞÒs¡ÅrX¸4[
+Gº-ÒÙõarW“åä8·_¥”
+”ì3 YXÊÙ $béiŽ)ï‰ð?`°ˆôXâk`HÀ¹gED‚fw.Ÿ'[òèêbMÌkµ
+ ëÊjÄÃĬ48s#hdÊòP˜qª)=ós`ÍQö^©”ŠŽ9ÎW#e#ׁ)ÇÀ¡ÏlÝ®ù«Ðó˜|(,ºÖõ?„Þ3c)/†u‡U­ ¥ÚÍ(¹a†Ói1¬}Únžá|Ñ~ïdŸ¡ãt8,,±ßëÛÇë÷=ŒØ66€¾c Y.Ìj ÷t_K-xí`{=pœÕýøv˜Ó
+3¡þ2Øÿgh»¾âÏSüÄù²1Và+-0g tîØ7ÄÀe"²WÀªËñ©A˜ì,"i•Þ|Üf¶NZSN‚U'À왐×É,¥¿ÃŒaéY ™0GaêÃp‰K/0ö	ÐHɃâ,˜§0ë)¸Â}'Óî¶qæþ›Ãèoy°âF8i*LÝæÜÙßÃq7À´6ðÓ½º~Øù;»>Kàœ‹¡ÓZ˜4Ös§À–=AÓ õ˜³3L¼ŠÃ>óŒ¥Ðï:8p1,Û–Ÿ¾„›ï‚¡wCîîÐñÈÞdóf,†#O·¾ŸK.„Fð°ë8èRì²oW«°‚‚AÈ$¸r–…åÙŒªªˆ<%GA¶”’ŠñνADÖcÁ‹‚ŒQ>'¬aëTÀŒj£nØúýô•ðÏ'6ÿÈn0ñQÈø
+ºŽÎ«Æî£/„ÍìO[Ù³áòÇ g´Ÿµ>NŸžì‰°á ø¡|ÒÏ~ìëDÙG^–ë:=lï­<ʶ¼"ÉØ =Éì=ÀÚyg5€»^„Éÿ…ù×ï7Áè2§µ‡i÷ÂÔ°­­ûn†‘/À¼›`ލðéËðTXïŸî±>?“_þ|dŸZÇKVQ}k7í^ؘ_
+Ÿ¼fc.¸
+¦> ŸÛgJÎ	’Lk-%•Pã¥>V•5XQ–À¸”ýOafú Ì£¤*l¹b•ckÍ¡û
+ó-K.€Ž@Ëç ¥‡—´Ýw0Üv8Ü×ö½ÉÎ/:wë1Ó×ÀÑç@½¦<ýpUù25„fŸÀaBæ¯PØ>Ž0oé-^‚î×CÛ%0ùŸ¦ð4yŽ?rÆAaá®»‹Ÿ…Z3MaºûaSx|~
+ýfÚ¹üVðÁÞÖ~•ûœ]?Ž÷¬Qzð+X´sÀ¾á¼‰ùÙáO ‘¤‡b·J u	*7dÛ‚`ó^Û>ì±kåÈ´-°*>}֚ˡ°>¬:ÑÜ^¶MÒ`nZI%ôŠèøLݾ>Öé‹¡ñظév÷6…(k:œ3n½
+›Á°}à”ˆ€kºÁ“
+« ¤:ΊMž÷¯´-²Ì9ÐýQh¿¦î[ß7‚Õý!íO8óBØ’C_……WÀ¸ñp`ØŠC
+ Ïy0î»(&ö‚ã¿€u÷ÁÜ¿Cê*8üFk[»Võ…Ôu0ø$¨W £ãüAݐ‘>_#ž£½^4ŽHþ÷W›
+ÌÆË	îx"l]%ÿ‡)/ÇÛÑ­UDêÌ×Rzæè[#²,gd¼Ô §N†!»À†ƒ!í¸à³ .¹¶ì^ÒvÍNðèI°¹»mqXXvû>º½cÛ^¹ïÂè#!¯=¬/ç敲.xjÁœ¯aI;Ø°[„œãáÚ—ìõ´&vûºmuýñ!L9Д#€œBè;¼÷
+lêaV‹,¯íP˜ù/˜Ù­¼¶¦põ
+°}3'ED2Hã/‰(=	®ô܍YKªÊ®ªËDi¬ªqmèjžˆl‘úªdÑVDéJÕÈ• UÄ6å+½ay7h2Ã|WgÃ[ç
+xÙ¬øóêÁÇ'æ]ÍòZoViX€‘í`òI¾z
+‡œ/å;ûƒ ¿¡×Z
+¿û»-Ï—Ž„] Í8Xߖ퍧Âñ# ¹³òÍ­
+‚ܦÐj¬¹t,ï;M†AÎ’?±|{lÙ	Ò×B§¯àÄ2¬ë“v…¦¶î8ҝoÜ×í AØ5õ}K{bɘ¿€¦•|ÞŽƒì%ÐjÌ8êρ;ÙoýUOCf1<r)g@ÿW ó›gJ?Èm™+aïá¶Í0¬Ìé
+
+æAÎJøõ(h=þV¡OY,ˆCéÙ}.ÌšR`×Ç싍d±»øš)
+FÂòA0çX,7J²˜¢ÐþIèµÖÅ Int¦ú¶o•|É]‹t3‚  {IDATÆÄöY–9åHÓàÝÿ¸7‹m`öžn¯Ú—ýóO¦ô¬Ù
+Z~ Û樂ü1 jÿ{ÁýÃ!ëh:úÄèoR<z"¦!j•U™ØŠ"$À™"òRÄû±¼N¦ˆHAœý¢½Î‘
+˜cS¼cÔ‰HQ9mÊ£>ÐCDòÊiÏxa¯O;ž@d¹0ÛwCËø3¢ûÑ~½RW@»g ­ fºÚM[""
+]HqAXh±”£kŠùáPDI%Áˆë½n˜2’¶¢Îsí‹B?daýµ„b§ÔÖ‡ù
+ ±óÙ;ù˜}%¬?¾wÛÁ-Zyš(p¿ˆìú@<'z®Ð[Dúèßè#"‡G9W‘ÜôrIÃ÷Cñ”l›Å"S!ð²ˆ,+§MyýŸ‘µeœ+¯_+à¦æ-ç\Ç÷àBbgX?H˷׍Á)S`Ÿiðú
+°òD9¾?ÖÍ^7…gjSxçE(ªg¿éÀ¦}€0¥§°|ù¬/αyö;Þ~#ë
+÷€Ì? ¿¬?><‚ë`iXÓVÅ®²çÚ£à•v0øQó½}é(h
+’3¶EKQCóee|Þ	¾yÚ~ó²¦ÃÆ}á»ãaÍ༯¶þº-‚oò °<x+4ÿ™ ‡‡ù~¶ŒzÊä©õ3lìãúۘ玀%­`Å©°z
+ü^Û,Fé`Ãfå6	N›èüÏ„Œ…Ðù1x«'üp¿)FY3`Õþ0âxXwƒý=–¶³q×ü	…º1D/?Ü(
+úä‚ÆásÐv(Ìèj_èñŸÂðcJŸŸÔ¢Äo`ÁUpóUüåó³îPXöP‰f
+Ðø=èò4X{.ƒì8ü*B
+WQS›ë›ºr\EãÐs“‡Âö‹Ý|N6­`Erþ0¢'üq lÚæw‡÷ÚÂÍÅ&Z¯ÏT¿øKK‘­5‰òúF 	ð÷ÚF_Šåι:Î~`þ?º1F…»
+¬.£_´9†Ï`ñ±|æðãÏ°ÌÊ‘~±|Ž—×(=ïüeœëžF…þ‰0Ï%x¬µ Žïþ­ì¶ÓAF>L?Ãõ™e–—²ÐZð¹°Ë$XéÌUu#ª§„)3»¯6ËM~+øò|X6æžjç²]þ˜ÙõaÒ¿LÙjü¬8†ÿ:_f²Ô-€fÃ`Éy°b€ý@0{w^¢dÛW*xNô܉Ø5ø|€þ½°ÌåoF9‹ÜS1+i((a'`UÏgêŽ9Ï(§MYýÀ¢@çÅÙÌ'i	ð{9mþ2)]2¼~»®L=VÁžwÁˆGL™Èš—»Åéç™Â“5ο	vÙhnágÃ>7B¿)pï[¦}¾ô	g<i}fׇy-á»ÛL×:„Ý—R6Ã9çÂÌ60áqX×x>èeíS6¹gØg~îåÒóO¼È”ŽVÏÂÕ¯ÂÇ]`̳0ç* ŠÒÓr3´~Ÿk
+ÖÚ£`v>Ô?òJÆlý´Yµ>ê
+cŸ†9WRê~ZÔÀŒ$?‚õðUo˜·;Ì;
+˜³œûGsŒ3ãR :Ý
+ç¯Óï‚Ÿ®€S«
+›ÂnwÀ)£`uÅ…oX ·É)£aÅ[Pÿ·­M€ ãŽÒ—@í°Uàƽíå“Cá‚ÏKÞ¯½Üöòƒ3ɢǜo®Ö‹ang8/†›dËi°Ó;†ÃæÀOÍáûc¡ÃâØæï¼Æ+52G憫ìø“#a¿ñpÆ×0ô@sÎÜÜ®âñÀÔG”rJŒ²5µÕê\DVƒ8ãŠÈoÀ±>7‰È؏Ë'˜Cô.ØÒê©xê¹U^F¬´"²Øõ´ˆÄÒw°^UƒFÏ”3öƒ1þ݃Òg$<w¡m=ù¹ùÝ•…¦Ãhw“NÙ=ž(ìÔÕ°ê`XâBú3ÀI8Œ÷¼ÆÞe«ÒÑý\¿ùÐ÷Q3a¿}«]/-Ÿƒk_†»šÏ3—ÂMOºÏô!¼ò7[‘ÖýÚ­«ðk(ësŒ„ˆ4ŽPÕ¸-S"ò5¶Pø:¬Ì{ûbŠÏøx“3ŠÈ%X	‹ñæ?xß"·ï@à=U
+PQÎصÃÅ ë?!Ã݇mó>~	ëÜà¨{ ËY7C÷÷æ_™ò°OD
+ŽÔÕ6Ø–Qa3XÞ
+˜	_óφ‚V¥ûlŠðsª?Þ¶~6Ô²
+;™¯ìê]í|Ö,;=­DV€Ü]ìyñ%0ø’’÷‹ÚÖ\û(×Ù•o¢áðé°ü@Ø´?¬éÃ'š%'ÏÍ»è2V±°1ü^§ôg¿t¨ÛùɃãFÀcW›Eë÷GaÍánÇÄé¡à‰Y·Áà0?Ýü]KË—9¯ÄJ›cu|U+>ŸƒìB¸ñɲϯp–Ÿ¶/ÂaÅ/=ßBÐ|µkÜ|^Ú¶t3gá©Øþ?1(=§O€ÅoÚVÝèÿƒÑ.
+M
+ 0ÆT»­†º£Ì?í^3Íõ¿]kNÕE¶C‡7}ÄØYMp‚ÑÀ+"’£ªqgVÕ/\‚ÁAØju)pr€Â‹ÙùÝBÉL¼Siþo䔟"’ß‚# µÛîé5]9îï²ÛrXyU‰•³Ý:¸åøx?¨µŽœ#ÝÖmËÿ¦þ÷ÂÂ(Ðmìógé9êFD¦n„k.†/÷±mßÃ'C÷7=øX5v‰ÈïÔoì|Ý64‚†ËM¦œBXYº¾¼ýÝvôù„á€ÚVZZ1tYe&íÍ{B‡áq|yXŠ*Ìʼ˜Ø}J¡ªëœâsV.ÈŘ¥3PfuGCJ[gãaWJ[jâ!|µšé=9ú‚þ»V°áÀ’ãoÏ€°×inKo}9ÊUj˜¯S¸[Ⱥtøõ³†t¿Žø	{¶"×·™nŒð­d€Ú«ì9/Ì/,7¹=uƒ4}ZG¤%hå^ý{ؐiV®K†Ãà®;a}oøsO`„í”6…¦oBëוúa~?˜Â¢åf¨?ÒG¯
+¶í¾z_[d(@ÊSÆZ=Íæl-Û_ßGÜùåÒ`×
+,
+òà åÑ6ŠƒZ¯1Ðì7h°Î<º÷uáˇFXoNx¦N-1‡÷º¶dA›2„Î),™wß2LÛl€;.‡Ow79¥:;ëR¯ïìF^ßÝȻϹ
+²Â¬7>“Þ‡Ù /rVÁ!ÓK¶ßz^eŽj»¸1úþÃn
+·Þ3Z¨n¦Û>ëTø¹#lj 
+—³ìÀË
+aðªØÚÿÅr‚G0­‘o0óü«ÇX‰UsN„º@Gd°è•…ûVâ
+wÐL™‹‘ƒQ*lw÷ÕöÑ8×ÂÌé[Pâ¨[ŸçÄ(e
+"ç§q.Š²r?d° ì>§EÉõMö[J¿÷öþðÛ‘°¹dOŽ>N¬t/V}§*ËPŒö‘Fªïõ–vá|*=‰â,UàÐï/až Ô"Á(в™™»UÜì/þwæÛ„mÃþëFûmûì?–¢Ã}°p€í2¼<Î	;	3{Áêcáþh0Vía‰q+"?Õ¢)IuMáõÓLቇCǼ-f=ºý<T§É7°¸#¬íeÀÙkay'Xß~¿õ˜³ZÂ×ÿgÖãìùPX6¸ä•
+\°QãQðGXÛüêÆì:D3œ=†Ã·ý,: SXž¹£`åÉ°ò¨·Ä|—îá½+·<^¨—
+£ì–„‘Y\’Œ0{®°Gˆ²Ú¶Ù mÂÎ[A„VŠ–?o8}gJV—Õö±ËFØ%Êx=––øð¤Óx÷eöˆ$r®®+ƒ'¡Jú‰~˜´‘&ª$_Ï[Xfâ@JO¢¸¨³=)íK»<ÇG
+¦mn§dý¤Bv~lís6Bí!3îÙ‰³rWØÔ
+‡#^©úùƒ£ª¹"2
+8†R¬13xFDvQÕ “D8ø6`띁?È~݆2•èD]7>¥gÓ¾aîÇñ™K!¯£¥{¸ècý3|ú?øe0L˜e[=CÀÂó,ÏÖª =F°I.ìò¼õûw¨ýdO‰£:¬ƒýn†©×@ÞÎPo,¤~gAB©N™¼äux*–Ÿ³oµ÷R6C£O¢Ùl­É²©»æ€í„4~Îu»8¿Cjß"ÆŒa‹·ÿÏðýÛ²J_R:ùè9Cà%ÕÇÁŒ;ܸë¡ÅÛÑFŠÞ›ì šH~OÒÑYªq[z‘°=õ¸©™ç;Æ®šDd/àMUçîꛉ…ìgÉèê¢^.®ÿ‘+;Â.A
+Èzfu>Ü÷ƒªÆ§%98Ÿ˜CU5ž=Íðþz¨ê€äJÓÜï#TõÙ }û WÕ¸³ª‹H°TUëTØ8 ñûô$ÊŒ†PœbÛ´)q܏¶¤Âu¢ûÖÄÂçàÐyæg4©¼÷’9Oïõw4¶¤]±ÀôƐZÖ˜a£<òR`^}ÈK‡N«¢Å;f¬¤Àύ¡V!´_[6˜%iðJ”ðáÙ–øK.·Ò£ª›EäEà.,«ªéKÔ‚˜­2ãVxí¨´UæôLóëöT=+ËöYeJæ̏ˆ¤T¶þL‘>ªôzˆWlô ‚סkOpž¶X
+¢í„.}¢²Š‚+<`‘T£ºAÊ:óݨ;NpOÑÒ»3‘Y\ñgŠwÌXI/†½ãN)48{hV2õ$B>ð\“ >=`JÏ}	Üpÿ
+Ì‘îª:¹¢ÆÉBD²€+Ã±+ýyD¤>0¡ZÄ[†Â“<:Vu
+Tu±ˆ,zc+j¥¾ˆ\
+‘ý‚FràvàqUÑ÷p+úïì›H¡VÏ_ìûÌëùõ!c-ìô³å´ñ”02+@Ⱥ§rÉ .¤1«ê.tû ÔÒr™oÄü
+ªÂŒK±ªZŽ—~¹ôâ“u´¥Ò¬<ž”O€~Pzà¯hȁa"rTe_‡"ræOO¿ðþ9X"ijŠÐŽJUzîoƒ+oøC¿(¾­žÒI%…ézª‘OH ½ª¾
+ü
+¼QÒ¢R‘vÀ?0+SP ïìÛŽJ5­ðVÔjcNŠˆÔª†‰?ŠH"õ‰cŽù¯Væu访ǁ3°òôàƒnÍt!ñ*ñåps”àÏŽÉQ›ŞÇSsP`A"áÓ'EÉâgc᧏%0F…ˆHððU
+´B‘. at jNÈ0%¯’h·G…Õtš(Õ•§ª“€9ÀE	Œ¡Ày@àCi$ñþBD:#¨ê´†@ð­-€>”ΆîñT)æÓã©9_öqÙPW§'0F–³ç0yÄ)'IÅ­‚_ǐËIvY!‰XyÀüˆ¾I ´‰;C¶'Y4ЪŒÜŠààV‰#GSiT58ø«o·_²„‘îÀ×ÀíªúbãdaÙm‡ìßÈUUïÓã©–¥úí­G:p~¢Î‹7w%b^wŽ½‡‘"´
+ûV¸å0,)Q`åÌXéqrì‡Õóx’†ªþ Œ®Mpœ"U½¸
+øHDž‘–AÇ‘,y z¸ZU_®¨O\|ž€ÃõÑÄ”A?žOº•Ì³­2<'æ{gæíW7g:	†ž»¬²}1ød93Qÿ9øË	tš[Í«'P[UË©7U.‡“ðeˆ7üöqµae(ªQ€Û€ëD$hy˜¿PÕO€nXÅôé"ò°³’Ä„ˆ´‘;€ÙXEó®ªc¹2ÇlÜü3aŽ!xªŠéQ•Y¹=5š‹Ö¦ÀtÁêmoJ^¯Ë…iù%Çóò`inÉñÄ|Èݽï†\˜Öw~üžWr<%6åFï»)×·ŽçYÿÐñÔ|?Zß‚-0!¬ïÒ\“;t<-ß>WèxtXߢ-0.¬ïò\˜Ö÷ç|XSƼ‘Ç+rá—°¾³ól¼Ðñ¸|›/Zß5¹ðNí$üuoþ!"	%üRã?À@¬ â9]Dâò;‘Dä%lKë&U½8	[ÿnM ÿÑÀ	ÊPƒÜöqx@^.¾«¼†¿²Þ'µíŠrÚnˆÒ6Da”¶¹å´]SÃÚ†¾£îÅUXwk+Tu.0sÔOÆxªê
+˜ão1ð‰ˆü."ÏŠÈßDäéáœýDdˆÜ."c°hκ@U¤ªÉȶ}+–P4ÐÖ”³´öĶÙ*‘=/¬<ÛžÏMDj‡V½nEŸîü;‘ 8TÅÛEEä…ÂEé›
+µm³¨jAXßüPÊò
+ú¦99cé+@­P¡K×7%dMp™{ÊèÖ7s
+ï[ú¡ïe¬È¾@QXß,`K軏Ò7#@±Î­‘€…ªúïDÇ
+³ð/`wl…övC]*Vêþ†;a‘Q=±„g
+¼QÕõQ†ŽWŽÓ€€‚&%‘_€	:qV0ÇiÐ0l7¹ÜK/ׂMip¹«3ößpÔzØÃ)ám_È‚ÜÔ²Û>Я,i[—¸ú‡ÂÉk¡M1¬ø_Ã’qŸsŠõE›Kæ¼`54T˜Ÿïׇ\B²g³-IØù[¶žóçTø².\¿&zÛðÏÙvHËîzNîÖm'¥ÁØ:pÝÚ’¶õ
+à̼èm¿Ë†k\ôГ9Ð$úä©Þ^­?x"Ò³lž©ªIÿq‘Ý0klW 1Ð+ºÿ
+˜ŒmA%Í¿LDÚãÝÖ]ÃW¨ê¡É’+ú<ÿ͆ï›Âϵá¼0íøþæ¥#»žn}ÖA{÷=
+sÆܵ7/
+>¯W®,{ŒÀ›¡‡û?“‹3`ûß\—byØnS:i
+ƒVB3—møíºÐ¸ Žp×ÐO0).,GögÂÁ`wç¸ÿq¶eRàV6‹Ráý†pÍŠ²Çx¥>tÈ…žîz_æÖ‚³×–Ýç±&pòjhíîGïåX2ÃãÜ=hf:|›—¬.{Œç˜5.¤œŽÌ‚•é0ÐýN,O7ÃuaI
+j­€zî;{£´Ê‡CÜw6)3úß{ð¯ð÷³
+ "­±Ò󇍎*gì–˜iº/°v³MÇœ¨`Ëí_Ÿ€×T5"q[͝‰…¸ž«ªcŽÑ¥ªý#<žX‘ÞÀ›@¯íÅaו¬˜¤ª$0Æ·À“.M†ÇS%x¥g;GDÎÁÌЕžÝUJ*-¯®Ì„j.âÁªzBc<lVÕ¿'O2':"rpÐ3dÝV‘K1æý‚^çbµö†m’iòx*Â+=; "ò0fþ>¶Cx“‚ˆtâ=	šÁYDêbY˜÷TÕ •Ù=ž¸‘瀦À‰	Ô‰«VDä0,·V/U]À8/ sUõÞ$‰æñÄ„Yß1Œ9>>XÝ‚$‚ˆ4ÁBݯH dXÒ·‘^áñT1W`–лª[ 8?ž7€ÓTxcyÀþ/I¢y<1ã•ž gÝ9è綻¶9œ3øûÀ+ª8¡s²¾
+K½ïñT.°a V¢â¾ª(ó’,\}­€õ£ã"འÐO"øí­éŒ®UÕ·ª[žx‘籨”‰l
+ˆHàUÝ'iÂy<qà,﫱¨®GFDš`9­®IÂXÓ±íéÙɐÏ㉇mf¥áIw“9¸GDîL°>W• ƝXæä³TxR€Û‡“%ŸÇ/ªº»Wã\”eDDºß_$ªð8^ð
+§ºðJφªþìe#ZÍkËÅå3z8
+8ZU7&8ä%X†»7•ÍãIUÍWÕó×€	"²uˉˆåâºÉ%(Mt¼Ã€C€;Ëã	ŠWzv at Tup–ævœˆì\Í"m…ˆì|‡ªêÒÇkÜ\¾­FÎx¶?Tõ!LÿX¬¸oµ×‰‘TùðÐWU‡&aÌt`pMå–}ñxÊÇ+=;(n¥y.fõøÞ¥±¯Û]bÕ¤'¸”ùÉÈùó –$±Ò²/{<APՏ±Òµ€Y"r$P,8œugf	Þ_­pj2¸øMUUc÷x’…wdö "½°:ViÀuªúm5ÉÑ+q1¸HU?HÒ¸o»më‰á<Û7"²;–Z¢¶­T%J‚XñÞ€`°ª&­ò¹ˆìåÖÚOUç'k\'^éñ Õ-Ü‹Õ
+¬ª¿VÑÜYÀuÀõXºþÿ¸-¸dŒƒ9bþ[UßIƘOe#"GbN¿¼M¶ó¯óçëœì…U…=T›0Is4ì¶7$c›ÌãI¯ôxJáJI\܈…©¾Œ©ŒLÎ.3ò@̺3¸EUç%q|>–¨êeÉ×ã©
+ÜÿoOà4à,Úk(ð®ªþpÌVÀq@à`L!y‹¨Jjéw/ù‹üº#™c{<AñJ'*n«élìfÛË„<ø&‘Z9"Ò»áöÇ¢ÈFw%³ iØ\w½€£Tµ Ùã{<U…S€Ä ˜ƒÿoÀ|¬¤Jèy)¶EÕ«ºz4z ­€Ï€/Uu}%ÊüPèƒ<5¯ôx*Ä­ §°Õۯ؍6tã]R,\öäF”¾éî):€O°›îˆÊJÌ&"»1gLŸùÕ³Ýà ÖÀ®@÷½n¬V+#?ß'sûª¯ÎòÑZžš„Wz<q!"-±ÈŽ¶”¾é¶ÄÌïÙXÊjJßpg`ŠÎ”Ê^õ‰È>À§Àª:£2çòx<[ã"0—úúvžš†Wz<IADRfÀÆÊ4™Ç(Ë©À
+ìñx< ÿ%y’ŠbÊ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_one.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_one.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_one.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,84 @@
+‰PNG
+
+   
+IHDR  ÷   ü   jÅíP   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœíÝwœ]Eýÿñ×;	¤H(Ð»éˆ•"R©*"‚  XùÙá‹( ¢b¥èW¿MPAPzIB=4 Hÿüþ˜9Ù³wïÖìîÝ=û~>çqïi³sËÞÏÌœ93Š¬’t$p20/oZØ5"&5.Wffý‡¤€Q¥MDÄ^ÊOwÒèØb¬RZ£Q1k‹¤QÀÚ5›ˆw‘³’yÀš¥õ‡•‘îäànf½a/àÿ€…y}>°0±a92«0w3ë
+†•ÖßnTFÌ÷þíNà`{à5àQàÕ†æÈ̬¹xظ¸£±Ùér‡ºþOÒYÀĈ8«Ñy1«GÒ§?—6Ͷ7Ë[ÃIKú
+Ûè¼t×Üͬ7Ü
+¼üx¦¡92«0w3ëqñ"ðIÛ ÏFÄ…Î“Y•
+jtÌÌ̬{9¸›™™UŒƒ»™™YÅ8¸›™™UŒ;ÔUÇI!Ýb4'?ή·ó–K33ëqîÕ1‚4Äç°¼-=o¶.i‰šsR¿ ÐV!¡ÍD{ÇFÄÜn~ýff–9¸WÇ«ñ£®œ(iÍ­=¯·o)`ùNžW0TÊÆBR! W
+¤Œ9]y¿ÌÌú:w#"ïä¥!$‰¦@g
+ÀáÀ²8o0TÒPš0˜K7 :²/<L¤™u3wër€+^Ãä€ßÙÂE±,݉cdrËI!HSPöZá‚ÔŠQÌÖffàànV’›êç o6*ù’EW
+CiºDÒ©Iƒk²Q¯€Ñ…‹1ÀlIëÔ‹÷ΙYÁÁݬ‰ˆy¤àúV£ò i¼¼Qçù²mì{/°%°Mí¾ü7ËæÓý…‹6×}'Iÿ–©»"bF£óÓHîfÖBr3óÒm$F[þ´;˜®.†ːZ	:u^'î$é±;K|'I×EÄIӁg$=	œ\Sœµ^7õ–œkí’´4°30Ø*"®ê±v¤÷ /æÉ*º+Ím€)ñR'ÎYØ	¸="^鮼˜
+¹™þí¼4D;w’´w飵;IÚ<¯ƒw’tûÝ#åçýùN’ˆ¸[ÒþÀ¿_§Hš
+œü5"Äl„C$Ý	¬< |°½$ î~<
+|èpp—tplD¼Ö¥§4N ®Žˆû[9dOà6 Û‚;p4ppuG–´
+ðà,ÜBbÖ/õñ;I:Ò¯¢Þ$éƒÑޝ$=Z¸(žwõN’ˆ¸YÒǁ?å׿,ðCà8Io EÄÃ]I¿?|Xø^{KNš‡ùN`2ð¼o°0Ø&"®‘4x0˜@heG`{I/GÄ=5éo¼ lBºoûIIKÛ’®¡Ì“´lNãõü¼X?çe3`*ð`F)Ýa¤k|ã#b¾¤QÀŠñdé˜mr‰oéü÷fFÄ„Ž¼‰9ï-åqàà~à®ÎÔöÍÌÊúð$é´¹LûZK§­;I:ZH¸ž4¸×P`ɼ,#i.p#ð÷nz›úŒ!1YÒº<~$°0–T;~¸&¯¯\	<Ltpp1©1˜Búw^îiž<§“ÞüIÀ_%mE*LÜ	œ$éûù¼•IÁzð0©a~>ïRà`R
+ûï’>Üœ,é;Àk$m%½8؝TX™,-ét`çˆhµÔ.iï|î
+À’¾<
+lMj’Û3çß̬ßêƒw’t¤pñnR¡ Ö Òe“¡ÀÀ¤K"ªÊ¸j.ŽˆW%ýødDœZŒYØ("æJÚx
+8="uÊ‘ôðË6j³WDÄùØÛ€}"âuI›߈ˆÃ$=\7•òpiDœ×.¥÷%àC1SÒöÀñEIÅeˆëÃH/ˆˆïå^» +~[—¾ |."”tðùˆø”¤«€õ#âä6Î53³ê̝$¹óæ.¤@©ïÂëÀ¤Öç ב*_Ë«Ø¡û¯ßSêéy+©3Ù½’îNˆˆ§:Æ ’–'•¦.* Þhï¼2I«—•Ò˜–/ —t;)€“Ï91ÿݧH-[Óvp߆ԂéÒÃmkff=(÷Q88”ÔÊðð<MÁ|Bm‡ÁšJj%twp_ÔÛ>—°¾|_ÒgI×ô#õ|Ú^1]ÒÀáunc˜U'·DÄI“ƒëtàûpppmDÌÎ×”>¬!é4ïTRÏýÀF¤Î…[“¼™™õ²|ûäÙÀ椞ò×ãÚº´ZUC$LTbIgçDĽ’® .‰ˆ‹»’°¤Oïöþ–w]œ&iBDü´d~
+\,é_¤‚È’q"©Äñ’¶~ÑN§—Kº†Ô<³0"NÉë®$}v‡tMIÒˤkóË’‚ösí¤6p^NàøvŽ73³ž18&"vûd_!R/ï¥mDÄ+’Þ
+¼Óšîݏçõ"bœ¤¥€u#âÁ¼}$ð~ÒµŒ;"âÙRk kDÄí5io<³JÛ†&ÕÌoˆ·òö1ÀÆÀøüøxQ:“ô.`zDLÏë#roç4f•ÒØ("n­ù{»“:î=ˆg%mß·ðå׺3pcñ¥’4Þ÷TæBÙĈ8«§ÿ–ÙâèÌ 6f½%ÿ^OŒˆ±ÎKwQ…úXîÖ_8¸[_TÅà>¨ýCÌÌ̬?qp733«w33³Šé“Á]Ògrg7333ë¤îy¬ööŽ–{´#
+-[{Ü’*Íù\gzF$
+ÍãÑ×û;Cò}‹Òk/offfýMÍV&iSÒ˜ï3r@ýIù–³|ŒHcÏ/
+,!éZÒ`0[ gKšEº…m"p;°ðCIïF”.éEàÛyЛ_ ›æ¤ŸŽÎƒÑœG{~c`UI_ ¾Œ•ôTD|ª§Þ33³ÞÖ“S‘>6piHÚ²­H“×|$§Œ'_ˆGóö¡Àñå¼~°gD¼&é(ÒD1gÇEÄü|ÌïH“ÜÜAšŒfVD¼OÒî¤Én֍ˆç$ýGÒ†1©ß33³^Ó“Á}„¤SµH3	íX瘇‘’& çÒú„ W HÚˆ4Ý…y<à‘¤¹–Ïö’ôiRKÀXÒ|îŘóÅ<ì“Hõ#Ï=D¡ÏÁÝÌÌ*¡'ƒûQ¤Q㾘h1Œk¼<bÝ—Húp`-û“ƼHšóýÃå|òõ÷S€÷FÄÛ’~Mª±Š‰¢ô¼X¯Þ¬ff6`õd‡ºYÀ’¶~DºæÝŒ¤­%íG
+Â/Ó4Oð½À!’v®='"Þ Õ¶&i+I”ô‘œþ`;I>Ò¯ÉÌ̬ÏëÉšûùùñRs{½fï×€ý½IcÄ/o?•Ô‘n'I· ¿f—Î;„4û‘¤ùy/Ê×ê?Iêiÿ*ð9šjƉ‡ÔpN)­ë€Öæ–73³”—a¥çõ–îÞ¿©åö¢¡½ÌcËW€Ç–·þÂcË7^M0íéàY»,IËË óH—JËËì:Ûº}žš¼’cË÷dÍÝÌlÀË·7ªfZ/˜Îgñ‚ãLRëh§Ïˆ¹]|­“ÜͬRj‚io×L‡R?˜.NÍséfWj¦¦”ƒ»5SŒ5Ðè|Xÿ!i€ëËJ:¬c:`—¤eÇà,^ÍômZÓŽž?×ÿ?Ö8¸[QÓÙøp7pAcsdm©L{»vZ/˜v4ø­
+Ö.m{˜ÑÁók÷;˜šÕáà>@IìNº«`G`Yà·áÀ^#“Ü›Á³vG‚igj¦³iL;|þâSw¨3ëÑÀGI·'nN
+£Hdþ_i`ö©L{»fºhr¡l!‹wÍti‡.ïš©™u–ƒ{ÅIZ8 ø,©)t(°T鐙À¿£%-Ccj¦õ‚é\ïºim0íLÍtaGß_3³¾ÈÁ½‚ò}¬G' +Óö»#€÷fÞ[œÚéÌNž_®™:˜š™u#÷
+Šˆù’~<OÉïC¤Zû\R3|ùî<RÏà"âÍÚ´Ì̬ÿqp¯¨<õí?òRL›»°i¸ß5I÷ߎ6î–´CDLoLŽÍ̬»ôäÄ1Ö‡DÄœˆ¸%"ŽˆM•€Ó€§õ€;%­ÒÈ|š™Ùâsp "❈¸>"¾’jð_öÉÓçš™Y?åfy "ÞþÕè|˜™ÙâsÍÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜ«cˆ¤å	33k¼!Î€u›•€Ûs€x˜\óøðBD,hX.Í̬Ç9¸WDZ€¤1ÀÀšyÙ8 ?_EÒ\ZýEˆ˜ÕûÙ73³îâà^Añ
+ð
+po½ý’FÐ<ø¯| x.ið­ÔþsúffÖG9¸@ñ60)/-H¬JóÀn4ÿ1Àk´^ûŸó{øe˜™Y+Ü­…|M~r^n¯wL¾¶_þ[ ûæç«JšOËZ¹ö?³‡_†™Ù€åàn]ӁéÀýõöK¬Nó¦ÿíiªý ^¢õÚÿ´ˆˆ~ff•äàn=""ÞžÈK’«Ð¼öÿAš
++IšAëÁÿùˆ˜×Ã/Ã̬_rp·†ˆˆ…À”¼Œ«wŒ¤eiü7öÊÏW“´xžV
+ ñf¿3³>ÉÁÝú¬ˆxxx Þ~ICiÙô¿
+MMÿKSi½ö?ÕMÿfVEîÖoEÄ੼´ IÀÊ4¯ýïHSA`¬¤·hô‹çÏç¿afÖ¯8¸[eåZù‹y™PïI£hü7öÈÏWÏ„¶šþgôðË03ë4wÐ"â
+ࡼ´ iI`5š7ýoISÓÿhàeZ¯ý¿”û˜™õw³6DÄ\à¿yi!×ìW¢yíàSyÛÊ’fQœÿɤá~g÷ðË0³ÆÁÝl1ä¦ÿ©y¹«Þ1¹c_9ø¯ìJSÓÿÒ]ukÿñZ¿3«w³oä¥IK†û-7ý”¦¦ÿåHs´ÖôÿboÎô—‡Þ¸Òc
+˜õMîf
+–ä³y©KÒŠ4¯ý¿øDÞ¶Š¤ÙԿݯ¨ý¿Óù}EÒºÀTIç gDÄ‹Ý•¾™->w³~ "¦Ó€{êí—´̓ÿZÀN4Õþ—¤i¦¿zÁÿÕNféTÒˆ‚ß¾,ið㈸¥“é˜Ypp7«€ˆ˜<–—òuýòLk {ÒüW ^¥~í2ðBy¦¿ˆI&
+$´;°­¤7IÿOdÖ8îf@ÌEо­Þ19À—kÿ[ûçm«JšGËàÿ#à—ÀÒÀ¨¼œ
+üXÒeÀ/"¢nÃÌzŽƒ»™›æ_î«·?ÏôWþk ëª9t©üx8p¤ç€Ÿìþ\›Y=îfÖ!¹SÞãyAÒ†ÀuÀ’­œ2(ïÛ8ø"ð$mt4³îáànf&éÀŸ€¡À`yý5`©óߤ~ ODÄ;’NkLŽÍ–! ’v"ÝW»$ðOà†þ0d¦¤Û"â‹qþö1¾§Òï­4Íz‹¤ÁÀ/“Æܸ›tÿcÀÓ½yϽ™ÕWÔÜ?ÜA*}ÿ X¸´Q™ê„õ»z¢¤AÀe¤Ä­9¥«é·¡Ëy6ëFgFıÎˆ™µn@D|/"®Œˆ›_oïDI_t­¤[%–·ÌÛÿ%éØ<©’–”ôIIWIú¤mòö­$#é"I»”Ò¾PÒç$Ý"釒F”ÒÿI7Jút+ù%éw’¾-iœ¤•$m&é·’.•´{>ô€åókø©¤$‘Ó/iYà3¥t·”tv9¯’ŽôáÒ1—tˆ¤¡’.Èù?KÒæÿHÌú®ˆ˜S3kÛ :Ûnjë$Ikåãö!
+CycÞu0ؘ|7o?’tìç€ý€)yÈÍK€³€³%­œßXØ‹tíÞyû·súûfæªí¥éÒÂQÀÛÀ.À,àBà4R‡žïJZø	0="öŒˆã€a¤¦ÆWókzƒ4H’–. ÝâspJ¾mèàÿ•þö7€…À)±p&ð›ÖßM33³îÕ,¸K:‘Ïjç¼é¤[aN¶ŒˆçóìX #HAn%àcùøƒ€ŸåRÿ¬ˆx‰4zÖ]qoD<ü•´æ’†´œ	\E
+¶úœ™·ÿoù{ø]DÌ!
+Ô1#çåóÀLZo™x9"Ήˆ95}ö˯ù@àRá€ˆ˜@šøcUIëC#âÁ<œèº’~ß£%m#¿fffÝfQoyI߶!­h뤈xKÒ&¤ö%Ý|ÜSXÞž— j'˜Ì/­Ï+åçÒ4˜ïjÕäô‹Î:åsk½X
+ÎÃH3vMÈëHƒoÔóB+Û‡/Ö¤ñl~þàPR¡æ|€üÞ|8š4U裤Á=¦¶‘g33³n1@Ò7IµÓ/ËIZ>o#é˜Ú“$­ŒŒˆIMï[ä²—“Fµš ÜJªíBj~ÿš¤¥%
+Ééßl/i#I«“&Á¸ªüþ82¥yD_ãÀfÀ´Ü§àaRáa!ðFž£=¶^Êi<F*t@ºèPR­þ¼m่x
+ØxWójff¶ØŠfù­H5ç?ÓÔK|°]óÆ•tð5 è9ûÒµîëHÁ}¼ý÷¤€øà`ýˆ˜KÁêDà·À·KuÆ•þVqÏ,¤Q®Få´§’zøךGº5X4æö!À×%M ];_.ï>ø¤_sH­eãr3HýŽÍiüX&ï{¸ø{D…™ ó$Ýì–_ßÛu^›™™Y·S;-ðÖH:˜íõ•0k¨<ˆÍ³áÁl¬ÏÈ}¢&FDeúFÕë-offfý˜ƒ»™™YÅ8¸›™™UL·÷<Bܾ¹G}[Ç흇€­ÝþnIëuw¾ÌÌÌŠn
+î’Fw’¸Y¢fßoJ#ÐAµ­Þ¬tï'>×Õ<,/é÷]=ßÌ̬¿ërp—´„¤Hš×—"Ý.6	¸‹4cTqìXÒˆtÛKzo)™á’vÉC¹þ	Ü’ÏS~_Ik·’%í#é}ùþ÷w;JÚNÒz’–’´Acþ#¥óÖ“ô®š´ÖÉ-
+«Ölß*ߣ¿›¤•ò¶$mÕÉ·Íl@‘4LÒú’v•ôY`[š†“6³Ò¥ùÜ%}tÏùõÀé’N"Ý[¾°
+iÈ×ûHÃÈBªÉv$Ý~WÞ~.ðtNã˜<@Ì‘Àˤ!p¯ž"·
+pBM>ö!
+uûw`WÒ½ï[îAß“4Îûhà"Ò¨tã%ý›4ÜT`¡¤e"â<~üH÷º"鹈øNV÷&Ò ;OgI:—40Ír’ÉcÓ›
+(ùcE`V–UI#J>Oúÿ›L½ò©Fä×l éRp'à¯EÄm’.~—t	°kDœT>8"î”ô<pzD<SÚuZNci¼÷›‹ùzü&ÀW#¢µábwþü¦nVÒeÀaE$½‡4	ÍF1_Òž¤9§¿™÷_*iƒˆx8Xi6¸€%OúqZ8&¡?Ø8">-i$©0ààn•£4ãê´¼G‘
+â“i
+à÷’F…œL‰ˆù5ižFÓÐÍfÖCºÜ?@Óð¯÷“jÕ]QÔàŸÖ)…’Ž.‘¤YÖ®®9ÿà‡Àã’þJ!¯ž;K?2»»Jº6¯Þ%é9RÀTҏÏÒ9OOSóHtÆŸ2çqfîg`Ö¯äZ÷XÚ®uÏ¡©Æ],wÏ#âÞϹ™uDWƒûxRó÷x`SR€oÏ,Ò,eíMPspYžböIk—gk‹ˆgCóuÿsI×òþSçï”'­¹	X*"¾P>@ÒÁÀƒñ-IÁo¶‘Oëg}ZnUj«Ö=’T-î	À¥ùù‹y¾3뇺Üÿ8CÒ?IÓ°þ´çÜ üBÒ„ˆøQ{çNm§’Æ‘_¸§fV$JšÞõMRþq1CÒ›¹ùïVZÎ w-pŒ¤ó€{H=óEê3p²¤)¤æþé˜õAù’ÕÊ´¸W!ÍeP[ëGS­û­ÞϹ™õ–.-Ÿk·»7çùÕɽޗˆ'[9g5`ˆ¸UÒv¤æòȵŒµ#â!Ik’jÚSIÍý&¹·Np_Ô‰o>pSÑL˜ü6%u蛬ל»ðàáˆx ”Þ¤‰åÇ#âIÛGÄø|ÌÀ‚ˆx!¯ï
+ÆcËWKîÜÙV­{8ð-ƒw±¼Tû¿ÒWxly닪8¶¼'Ž© ÷þCÒ`ÒõìÖ÷JÀLZÜ“óL‡ý’ƒ»õEUî]m–7³:$¦õÀ½:°$éÖÎrÀ¾©ô|j¸Ämf‹ÉÁݬƒò I«Ñzð^xƒæûIR“ÉÀóñvïçÜÌw³LÒr´]ëLº²¼ÿSz>͵n3ëÜm@´$m׺W ÝyQ܏×ÑTëžÝû973ë<w«„|§Fk{5@¤;'ÊÁû_4uR{¥Ù63ëîÖçåAŠÚº5l9Ò¸åÀýp5MàÎéýœ›™5†ƒû &iT_BTR[“¬,¤ùä#“hªu{À!3³÷&>ôiÒD=Gzw÷ôßk«Ö=x…æû~à*šjÝóZ¦lff­qp $­G/ÿ0ÒØû»£ì-Fš"
+ºÒÖä#óhYë¾—¦Z÷ë‹“33kÉÁ½Âò0¼{' #H3}7wàü´¸× M…[LùY,w—çç/ÔNùiff=ÏÁ½‚$¾|•4"Ú2y×;ÀqjümMù¹
+0›–µî;iªu7üz½™™µäà^!’¶Žv!õÚ©oFKú/°-§ü\‚§ü43ë×Üû¹ÜamSš®¥«S&{EÄ›=733k÷þ¯è´öd~\
+IjR,MSÀ¬/i¿ˆ˜ÑûÙ53³žæàÞÏEÄS’&QšòUÒÀú¤Nt›Û cH€ JÚ#"jLÎÍ̬§8¸WP¾/üѼ\^lϝèÖ"ýM€£$ý6"&5"ŸffÖ3ܐˆXü7/W78;ffÖC5:fffÖ½ÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁÝÌ̬bÜÍÌÌ*ÆÁ½“ô)Iß—ô„¤õ/3³þBÒÀÍÀò’–tqƒ³Ô-†4:¶XFï*­¿?Sëƒ$-,†K
+¼›33†äçïžm\VºkîfÖ><
+L6mhŽÌ*̵<3ë
+ƒ€1¥õ%•³ÀÁ½{¸X˜×¼Þ¸ì˜™õ;hÞWƒòÑ­Üû±ˆÐè|˜™õWñ•Fç¡'8¸›Yo¸øEi}!ðBƒòbVyŠˆFçÁÌÌ̺‘{Ë›™™UŒƒ»™™YÅ8¸›™™UŒ;Ô
+ ’>LÕîƈ˜&iG`àΈx¦±¹³ª«ýþ5:?fUæš{H:^Ò켜^³ïžÒ¾jö\Ú÷ƒš}»–öÍ–ô–¤G%ýPÒ°|Ìwò¾›º˜õ_‘†X8.¯ïÜÅôZômIKÚ£»Ò´Ê¨ýþY%é]’¶«³¬Ô
+i#é,IÛuG^{“¤!’v‘t°¤ý$m.©OV’Ü»fi<â¡Àç$´3°uiߢ÷W’€ÃKûËÛ
+ƒòö%€+{€õ€ŸÕüÝ%»éuüøiÒ„î²#ðIRÞÍ"š¥³  ²IDATʾIú¾=ÒèŒX»~
+Œ¯³tǸ{GÓ|^Œ>OÒjÀcÀÀ_HˆMNoë¼Fqp_<¯ #Ïæõc€y¤	\jí¬A_ûñü|—:Ç-ˆˆƒ"bà´¼mŸŽfHÒhI¿ôˆ¤’’ôþV?T{ß,Ÿ;HÒç%Ý-éUI÷Júl)íC%M”tjnQxVÒU’¶ÏûÏ"w€ãò±Çå}'Jº]Òë’ž‘ô·Ž¾&ë^’–ÊŸÍDIä™°•t ¤m%Ý‘¿7_,ó‘Ü*5-†÷×ì?$§÷³üý˜œ×Ë-8Ÿ'}ßÖÌ眙ù¼¤¿Iš*é:Ikçýcòþ{sËÖ=’®Ëûޝϙ"é¹ÜZ´NÞ·s>–4Rҍ’î“´™¤+óþÍKù¿$oÛ¦Gßüþgð?¥e‚¤ÁùwfTqP~ŸGKZº|rÞ¶…¤•ë%žÓj1“eÞ¾Ž¤­$­.©YE)§;:¯j#ý5Š<çÔTª4VÒFJ“µåx`=à&àcyù	ð|¿»rNsHÍö‘9Cò²‰¤¥ó¶¡¥ãŠ÷sdÍù«+µª®Ù¾L>~°¤¡’6%"¼tr¾p))X?¬
+Ìþü7ïߥtÎ󶁓óóóKûwËÛææõaÀeyÛ#yÛñyýŽVò5˜ôÏÀkÀ¹À¿CóþGËù®ÉëŸÍëÇæõ§H%÷'óúyÿ7òú|àÒ0ܝ÷ŸLÍÛ µ@E
+ø‘óv©yöFŽu–ÉŸG o·åçsHÓ›¹yÛ:ùœ#€òwðçÀô¼ï¼ÿë¥ïÆC¤Z^‘f‘Fí÷ïê¼>¸˜œ×ÎßåUJù|›4Üò…¤‚ñyûÀùù‹À²9íó¶ gåç?Ëû¾“×›××Ìë/ ƒýùô…ø[~ON¯³o(©ÆÀA¤a¯ÿ×¿™Y¸¡ôùðµ¼ïº¼þ»ü™Ÿù6yÿhàšs¶Êû—/m?9çæ“jÒCò1cJßÁù;[œ³|>f›ü*ÿ/ÙÆ{Rü†ÿÚÊ1Ûæ×R¤ùù÷5ï/¾«?&ýFMñäüÒq?ÎÛ~“×w£)®0
+دt|ñ¿s"0XÐð/Q\JÆ%¤ÚzšÑ#ašwRí~fÞ¶>°Q~þ°TéÃ+>¸©¤³býè|L{Á½¢€UJÛ‹/|{Á½øGûé:ü	yý¡¼¿îÓhºD0Ÿ4ÚXñó|ÌWJÿÓyÛu¤&û1þòBóà^ç7óúOòúßê|Ž£ó÷ô«À­yÿ/ó¾"¸¿DÓàX÷åm'´òý+‚û_òú
+ù»¤ÉrpÿRÿ¿ÛKÛžÉÛŽ*½Æ§ó÷3H?ôÅÿÁrùÿk0øVùµ{iöùÏÊ¿GŲIÞ¿aÞ7T€Šü¿¯üÛPÍ»#ó÷£¨dÁý-R+
+ÿ›÷/M
+R» Φô»Góàþé÷êå¼þþ|LQ ›”¿¯ãJç,ŸÿÆš‚ë~y}°}+ïÉGKi¼M*¼|œ\ Ìß¹â7ô`ÿ¼¾ Ø6S÷ùÀå¤Q×!‚ßÌßG‘ƺ`s`µ¼oðeRêMRh½œnÜç Ns³üâ;Ÿô%Ýw×9æ㤹¬gšröÍ猤å5¬ •Šo •lwŽˆ³;˜—µòãcñâ¢#æ·wbn>*š¶N%5=ý0¯¯Ssøí1?"æ ³I_ÆåÚHþrR©zGàb`ª¤[:Ðf=ïŽüX|_ŠI3¦çÇ1 ’>Oªi\Mó륵ŸûÄÈ¿6¤xhú^µæ>€ˆx•T8€ØË.*=_­ø[¥m—÷EÄ›Àÿ’Z  N+þ"â5RÍ~ð	Òå)€óÚÉç@ô6̓{ñN"Ul–¾Gjš>,ö’¦ó
+àcñ‡ˆøuDü©&íó#âxR+!ÀN9í·€kI—&µ×k?#,¥|8?žg_«9o[`UÒïð `‹üú‘‚rñORáöR¿§%µàlOú®¿I*àl^Jsßšäþ‹ˆoEā«HŽ}Iš5»"âü7—&ýoŒ!½¿SI­»®I÷ÇqhD|ÍÁ}1å‘?æÕÖ:VžG“®Ñü„ôaVsìüˆØ3"öŽˆ/EÄ-ÈÎóãÆ’Ö(6v$ˆæ¾â‡õ `ÙÒRûOõNéùš}³òãðÒ¶yq 鋹+p/)ÐïÖ^¾¬ÇŸeñ9ÎΏƒkŽû©·kDlBª	Õ³uézà–ùqJ;yx/€ROì"¨—¯c.Œˆòl‡ÏåÇ÷”¶mVÞ—¯Ûô}œüJRyÊÙ3óãñ¤Ö¶Û#â‰vò9][”–I¥}÷Ñô½yž¦¾FEo&)µæ¾üX|ç†HÚˆÔÒr"©¶ZÌA0¢£i*S
+¤åÇÂèü8˜P÷ÍÏ'’0õDÄõñ!Òïâ±yó>’–ÏÛ ö"Må4Ô$ucÍúòã!¤–N€sjò:²”nm_”nŸìÂß}ÔÓ¢#]þ‘Ù‘ôOð~š¦d]¸ØE©fwGj.ÝxXÒ?±¤Im©¹ž_®‡ŸNªm϶#ý8ØÆyeדšÞ¿+ioR+ÀZ’>IªÎ'•Jç‘®ÍZÿð4©¶þ]I¯{¶rÜhà1I3Iw©J[ö—tM­IÀÖjüç’zÞo+ié‡|
+R€¹4f/&ÕÌ?G*Tž
+\ i¯HTü¯iZKc$mQZ9"^ʽ.!¯	À¤>7ß#5•Ï#U`Ž’ô;RZ=×REÀš;4§ûçˆøŠ¤c€Ï´’¿ÖÒ¸‹T«ýœ¤ÇiYs4?öˆÉ ’6¤e &ï;ŽTºžtiòé¼kH>§¸dér×”|ÞF¤÷£lvÍúõ¤‚é¤À=“ô¦”î|`§\¡DÒÖ4UÈZ¤ëš{×<K
+̏Dļˆ˜QjŽœ÷Ï Õ
+nΉˆñ1)/·ÿGêÌô^Rп%/­™œ÷ßWogD,$Ýfr
+閍HÍGOåCîÎçŒózQºþ5©ÔøécϼJùug·çmoçõKI×æo£©T?‘Tðù(é²ÄM¤ëü-z™Z¯˜OÓw­øŒîÊëE
+gR^6¯KºýgMR³ã7òþrMÒµÚ‹Hß»qÀž¥Ï¹ø3jÎ9žôÝz‹Ô	sïü¿47sùàˆx‰Ô¬z!©01˜tyì}¹IwR‹Äq©Ðz>©æWn-*jï3IÍ«ÖÒ§€ûKK$Ï"õúéwâ9àxI»FÄtRÇÙ ½Ç/’î,úTÿæuùñHII¹Î:‰ô}:€Ô1¸Ù]ñ(ðR¿¡'%—ôéwsKêÛ’ô=šB*´^–·ÿ%ÿþ?Dz_†OK—Ó|”ÔDߪüÛ}.© 0
+¸("fæ}ÿ&ý_,Oº¤y»¤gHý¼Öj-MÏ
+gf‹MÒ×I?ôEÄÁ<çjà#¤»1zµæ,i)Ò­y¿&þ_oþý¾.·´mTg×í¤ÂÿѤÚèÏ#bn®Eî
+¼Tô’´-é6ÞUI5Ý?Gă’!ÝRvEnAYÔéîõˆ8=Ÿû¡|î4RËÏá¤Ë3?4œ¦&ñDÄB¥Ñ·nˆsk‘*ÓH•
+rË1I»“.Ž%õ3™ \SÖš÷d`wR_‘Ta\JÇíAº_¤9>§9KÒ‘¤~!EÄã5鯜ßWj÷çÛ÷öÞG
+òÓògq]DÌÉÿ£€ßý­ÜÍl±õÃྀÔrù<©ø›½ù÷­gIÚ€t‰à`%RSÿƤŽlŸodÞz‹ƒ»™-¶\ûZtMö±ž³)©2)"ÚêxÕírÍt©#]íõPëçr­ýR_H—. NŠˆY­œV)ÿ4f äÏÝ    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_two.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_two.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mpm_cache_case_two.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,170 @@
+‰PNG
+
+   
+IHDR  ®     œ!R   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìg”\ÅцŸW¤€DQ‘M2˜L2`À$cÂGlc¢1L´	6Æ`À€M9g0YäŒ @B"	R}?ª¯öîhfwfvvgvUÏ9}fnè¾=ñ½Õ]]%3#‚ + énàÏföX…õ~ìff;¶OÏš]ë,à]3»°½¯ÕUéVïAԐù€Y«¨70oûRŠ¹€Ù;èZ]’õî@3’V ¾fÖn6³±’–ÖÆwšÙWéü™u%/€»Íì³\{³ [3÷´rí¾ÀÀBÀXà63û¾àœy€Í€×ÍìÙ‚c âÿ›÷™Ùi7à'ÀŠÀdà!3{· îæÀ@àá2Þ¦ Æâ’t»¤Çså‚z÷)h’n*øL/®wŸ‚ºóàR`°0ÐWÒÀ}ÀrÀÀK’¤ówvú Û¯Hš@Rwà!àd`eà~`ή}4.<}€§%Í”;>/p°
+p¥¤‹²’Öž~¬<'itø§ÀaÀÀšÀPIkçêþ¸Üü¸Œ÷©b$í.é©ÜïíiIs´ÇµêŽ™5Dž,Wî¨wŸ¢´ù3Zð™ÞSï>Eiöù¬Ž[ï§ò!°E;_ó"à- at i{.à`ÅÜ9×g•¨=plz¾#0螶WIß³Ë臀7€­ÓööÀT`´½ðY®íaÀž¹úG –hûhÜ’·§ó§í^ÀDà¨vxoO(ø½Ôû{Ö%†
+ƒ`Æf. gn»#Faî³ôO‹¯üNRv|!Ü*BÒÜÀÁÀúÀ€´B:o%àf6%m¿ |^ꢒû¤¶zó ‹æNyÉÌF˜Ù{É¢$é`)`cIë¤sûˤv{ ‡¦v—ć¿È½¾7ÍlLj÷IOµö-ÂAGóqî¹áóBSrû¿NGàŽ;šÙIÅEÜ’é^Ðvávžsð9¦Ìì3I÷Ó\´'œ?%µ—‰ìu¸…š?>¼¹°'ð.°3nue},üŸm©A4Ì0x˜<ˆ›æAçæààü3}³¾Ý	ð?ò™ÙÓY†§ã·&Ñêü"W÷Y`ÝÜ<Õj”ðÖ“Ôw¹6‰Öœ¸ÓG«˜ÙÀ«À²}|!×ÇûÍì3›
+ü²àõ-&iáԏ¾¸#G{0揀×ðßÛ÷-Ö褔eq%¯™¥pÓ¼wÚýœ™=W«Ž˜ÙŽiBö%3Û¨VíõÃÌv‘Ôx?>Ó†d4p°<îå÷<|saf_HÚ¸JÒ“øŸïòøÎé¸SÃù’6½ýÞËU¿Øx[Ò½øר×™,é*àI/VÐÕ}›$m<‰Ï}ì
+ü¸.y$®ŽGvÝ’þ‚;œ\¬¼RÁuËÆÌ®Ký¸¸ÅÌ®më4jj.q‚ÔŸ´í]pèD3;¡¦i®­žt
+rÂÕ¯Þ}	Š#é( Ÿ™Õ×ZøÞÌF쟷DzáÖÖsÙ<˜¤Åp¯Ágqë½—™½™Žõ 6ÂÝá#’•Tìú+áÞŒã^€ß˜Ù’úã/åÎ]xÑ̾MÛ}q¯Á¹q|ÂÌ&¥cýñ9®áÀH`q˹ÓKú)îÿ8þ_:ÑÌŠŠl[™„«‹«;þF¿‹O8®Ü®=
+‚ Ëbfo•Ø?¸¹Ä±øTB±c?Ð|ýV‹£@föMC|çö|RpîÛ_w—h÷ÜÅ?ãÙ‚ãO¶Ô¯ 2Ê™ãÌef‹gµs‚ ‚ EZµ¸Òdãg­AA#yAA«„pAŠX€A—%­ñ€/rΗ‰ÖšKuа4¢puKA4'பSëÝ¡ Ÿ´@y`U<`ïòøz«Oñÿºž©ÌLN¡—žHåi3û¦ý*§…kàϸ~¯´ø¹ÃÿMÈ•ñÛ%Kr¡
+‚ Ö†í솯¡zò~'pR‘:óák²~Š/t^VÒxpßû:ªïAu”9cM¹On÷A’vJÏ7·‚ü3mà[3Û£•þOüÖ»…2g©c)üK1¾£Lñ+,fö]u/7‚jH©CþŒ/:¾Ø0[˜ÜiÝØõ© iV<TÓÙ’¦ gCr|ƒ¢\‹k©"ûæ¤)÷ÍLEŽ·ilú›T>jåô²IIéZÃ¥Ž¥ºÅ˜L•bˆ‹xŒÃAIsᲄ÷¦¶Ž¢˜ÙD<tÓSÒÇ#S%ýÎÌnkkŸƒÚR®p­‡[\¥h—Ð%M²š¾ÃÇÄkB
+IÓ’þ“ß×'=Φ\®‡SqÑ®Ö:Œ»È S"i/àÜÂZ¦=æ¥Ìì.à®dÑ]‘’Haf“k}­ :Ê.3{¤½;ÒUIw‚_¦RÒ¼_/ZĹKK“ØÅ(œ7¬D§›G‚Z‘¾³ât74³7ÚûšföXŠmx)ð„¤Íì½ÖêíO#:g­<-ǧR3Ò8Kb8?Í-¼–.6Ür¼˜–Åo:çš4|ÌàHš¸OY²®™Õô{ßfö%ðKIC%íff÷vÔõƒâ„pÓHB1‘‚`£m!e°}Þ)&†sáѺ‹Y†³R|ˆz
+ÕÏvé%’6Þ2³÷ëÝ—Z ©p+wózYöfö7I/àiQ¶2³Èb\GB¸‚öfîOS³yÐ4lTj¨´žÞ}¾Ç»ú‹—ç$ý€Ï]V˜B¤³æwoÄs„Tï3{BÒîÀÍ’Ö+׃1¨=!\A§#9—|MSz÷6ÓU–X˜ÙG’Öþì#é<åÆåLÄŽÂW%Zé3YX˜5µõ=ððª™UœØÌî’tp¤5ÍlL¥mm'„+h×%3SÜc´½—XœŠÏΛÊqÀþ’>®ÃElTòz…‹[š/¬R‰h¥¹Öí€}€Õð<^¯àŸë$Ü?$éM<Ãòå•Ì›™Ù•)éím’V/ÝŽ§ÕÈId@îzDäÚSÆ‹Þø¼áA¸CC!™œ‡Åý¿‰-´«^rA¬Æôy	øMrM/·ÞÞ¸`¿\ Ü[Ê]>Yc« ›àk¸N*•9¹Dw÷›Ù¹åÖ© íñÏðÚJƒ;Dä ŽÖ–XHZ8­)x>½‰ÀXà^<‹ïÙ¼œ¤cñ4öY¨µrÊ\ÛÅæ{IšJ™N3¹ç?Ã-%Kk©Zt°‘´p	>Ôû33{¥Œ÷p2)N¡¤yðaÕ—%ýŸ™=ÔZýÄÁÀS’†¤H5ÃÌ®–t%0BÒÛÀe¸ˆ½_ËëtVÂâ
+Ú•°¸:I w_à–ÇmÀ-9H:
+ègfGÕ¸/åÌ–~À¯€'qÒéÄŸ«Êi&ó cpïÕrjJY’ëàq©™Xæk<XÚÌv¬ø
+j½íøÆºÀ¸Ñû©×•rx
+‹+‚NCšëj§jæ
+%ýècfÛµpÎL¸ˆ­ü8xŠÒ^¦ó–8–/³âs‡ß ÇH:‰ÖDp4>wxîSx¼êô)föƒ¤-pËpi|.r)à$àdI#h±ÑÕ\£³Â]„4Ÿtk½ûQ-ÉÂ8ؾ¥óÌl’¤Éx$CÌìš\»Íç¯ÁÅðŠÝü¹çãð˜‰Û3½u(IUG¤IåP\ àÿÙ™ÓÎÒÀÉxLÅ·ñCÚú^tB¸‚ h6 >2³gÊ8÷¯øh›E¦E£É–XŒMK
+ž.1³W[ª›<GG[ZºeD£É‹\±¸¥y‹°Øÿõ¬éqYà/À9¸“ÍDI˜Ù‡å¿‡® …ŸâŽ-"i`c`™öꈙ”ôGà2I«·äònfßKºØÏí•?Öæh4’v.ná”ïñù¯nÀ{¸E6ŠÆGm4jíF34«ãN­q ð3›Ðž1³Kqì 2Nÿ7°{­û;_L“e>÷=î€sðü½›ÕÌ–†úr¬Ï°¸‚ ¨;Éq5<‹qKçýØX¼Ìv× v³†V°>ì0àIç·ädafÏKš$i3{®Ì¶[ê·ða¿ßâ"5wpy¸x|Fv‹+‚F`)às3û¸•óÖ ž1³O[:IRwI§áÎ
+ïâ/Ã×´#éÊÀ·EÌìE<ÀïÆe¼†‡€Ÿ”q^‹$'•‹µ€sq§f6ÐÌv7³ÿÎÈ¢aqAÐ,¼UÆyËà!œZã7øú§Íì³üIâ‘5†JZ©Œ˜…ûákªZâ5`Õ2úÖ³áÞ’]v¨¯­„ÅA#Ð_dÛƒq(‰¤Ù€c€=EÀÌ&˜ÙîxÔùcʸæíÀz%²‘çy
+÷îkföuˆVË„pAД+\hî¨PŒÙ€îe¤9ØOÒ-”â~,ÖJ{¯ãk«‚v&„+‚F ;å	×{´î˜ñ=žu{–NJkœ† [–qÝçie0y9~%i`ím „+‚Fà[Z·¤À…kPK'¤%ÇâÙŠw´\§?¬\ÆuÇâ1[ã<uJÐŽ„pAмJyóC­
+€™ýÏ;¶?ù¾µÞ›\´#!\AÔ3û è+©Xþ°<#€ù%-XF›g™ÙföH§
+4jÅÌ„pµ;!\A4
+¯-
+ëeóHǃËÖ‚ŸâÁt[£º©5fÁçØ‚v$„+‚Fá9`£2Î;ØXÒò5¸æš”fêÇxVæÖˆ¡Â  AÐ(\…;Tœ”Ïp\ˆ™—t2Ðvój/&i'<òú‹­œ7°$­—¤¾xòËo«íSk¤HôóáiUŠ•™ñH!]š® 3{QÒgÀ†x<¾–¸ØWÒ¹ÀafVŽ+ý4$-
+œlTFÝåáeDØXÏà^Rt[菀¹hY”æÇc~ˆÇ]›ÇàÞ‘cðô*§VzýÎFWÄ¥À^´"\);ðºxÂÇ{%íP,JF1$-ÜÚZ®­ÄN´î	`|¸³ðz³Ð$<¥„i^Ü•~L®ŒMíÝšÛ÷Ik•[ðÑù	á
+‚ ‘¸
+8^ÒÒföFK'šÙW)µýÀ³I¼JFfOIÄãžbfWµÖ™ˆww`Å"Çô§I|v >t	ÍE©MVR^”žÍïK¬ƒ2á
+‚ a0³/%üSÒº­YiXîpI/C$}\¼ŒÄ-œ%SÙ
+x¼;¶¥v“ÈÍüþ»³¤Bki^`<.<âëÐÃÝëó"õik¯#¨Œ® ÚŒ¤î-e	®‹p+çÿð­bfWKºøÂi`!\P†ãb²ð0·¤•˜~¸./L³ãpqú0 ø OÒ˜Í-Í¬$I[3™Ù¡mzåAY„pAPi¨lC`àLÜÊi3ff’öÇç®îmÍ:Ê1YãF¦¥ßãô5Í-¢1¸Kü4‡3ûTÒMÀ»fvX×ÞøO™ýÚHW!©?î@ñ[\vlm>ªRÌìeIî“´ГÖ=îf¦¹§Ýà}|x0¥±ex"io<GØNeœ;'°n!@We!i}àP|8n*.&g›Ù6´Ù›–=îâˆ?Ã]½ó¢ô8͝>¯¶}Ú8
+XÛÌ&•QåhàªÜ7è B¸‚ (I²&öÀ‡Ùúâr£C<Š{é«×¦^j)+=™~MÒ»¸“C¶}°°½™}Ù/3ßïíðìÈ[—‘Ï‹3qw<3sÐA„pA0’ÖÆÅjs`
+>”1O¬x.°‹¤b¢47ð9Ó‹Ò£4·’¾(£/û^´‹™•¢©"Ò|ÝÁ¸olf/—Yõdàïföq­û”&„+ $͈§é‡Ï[ÍÚ
+˜	6ÌDéàšDéC3›\‹~%—÷£$= \'é"à´Zy1JZÄ°Ž™(³Þ:xlÅ%kя |B¸‚ “¢6Ä]Ã,(á"s?ð|if [sÔR†Yq/ÂCjèß"fö€¤•oI:¸,EŒ¯IáC}Ç—»Þ*
+¡þØ£Úë՝˜äáWJ”Ä-§ÑÀ¨\y
+¸6·}ð4°)°žZdE\Ìãs[ßâÿ½Ò¥gýè~,i‹Z9F´F’ûEZ‡u8p¬¤Ë»€çZsHÎ ûâ!š®–7³qvårÜ!ã¾
+ë5 „+”	| ¥Ei ž#jTAš{>®µ ¯Yl»ä&þr*ÿÍŸ
+±,þg¿
+°8ÐXxUÒÆföz
+^vY˜ÙÀ¯$-‚mž
+¬ i.ŸàsqSqËqI\ŒçNÇÿ
+lSŽk|!’NæÄ­´ „pAHsJ¥DiA<åüXš‹Ò3À
+ÙvGS™ÙWøZ¨'ð¨YÿçÃÅl9à Iç›Ù[íÝŸ‚¾½Gòl”ÔXX·4»Ñ”sð&àOÀÛm	¿$éh|1óz•F¤jGW´)‡Ó¤¬L¢¹(Ä£gÛc«I‘ÑQ¤ˆc†.KÎ ÏQ$B{-ô|iÀzU-5$„+è¤!¡ÑµòTk+’æ eQêÇÉËiž3éæl_,Xí¤5i§ ¿Ö¯ UÐN„p
+‹¤nø:¢ƒ‡ÍìôºnO|-R)QZŸ;É‹Ò(<“n¶olGyÛ퇤¹ñœ_“€5ÊÍù´/!\AÑæ~öÁÀöÇ“øQÃöûQZ”Â'ð?¢¹(½ÜžíKó>AFÒ&¸ëý¥Àɍ<l;£Â4’~‚»8ožvÍ‚§’Ø¡‚õ5=ð(-¹ˆ‹æ¢4
+¸3·oLL¼Ï¸HZø¾`/3k1sÐñ„pu%%ìÛ÷›_”y‚}ljf_çÎïKË¢4 Êš¥×ñu>™'^«a†‚I‹ákÚvÆÓ´ü²Ì »AÂÔIƒð?‰=Ò®Þ§LnL2êÁôë–îÉ=oŽ ñIkå¶Á‡¦—® –‰ØƒMWPI½pAù¤ãûÉÙb_ÜÙ"[ÀÚ­Äé݁Ùñ(÷Ñd-ÅäxPK–ÀEëbàæ°°:!\A3$mƒ‹Ë¸p L–ô8pŒ™=Ue»ÓðïÝdÜ3¯%áZŸwº0朂öÀÌ^ų8ˆRÁŒË–x̺فL,zë÷§HÚcf˜Ù¯Í¬'>—µ	žA÷Ràà+|xð+<.x\¼=§$ÍSÝË	‚ «WPÈDàRn`e< è`\HöÂÓYTMŠ:0x8¿?¹©/,‡îYÊYxIÒ¶ÕZ|AtB¸‚B
+ÓT<“ÒGü3mÏ×^NÙm‡¦2äy¸$0HRïH#36!\A3JD{ÈÓ=ÑQ}É0³‰ÀK©A0ƒs\A‹HZ•}xÏ_AP7B¸‚’Húð ¾(ø]`ÃpG‚ Þ„pE‘´©ADÅ‚ á
+¦CÒŸð=qG‰5Íld}{Aà„sFÐIÇ'¥Íoñ¨{gé݁Íì²zô-‚ B¸‚éœ{>p\ÁñW€® êFWPÈ0à‘Ž¿ÓQ	‚ (FWÐ3;8¹Þý‚ (E8gAŠ°¸‚AÒÆ@?`8ðVŠ†AP1!\AG1?°DwIãpŽGä7³Ñõëb® C0³ÿÔXœ»ðc`'`II³áž‡Ó\ØÞ2³o‹4ÁFWÐᤤo§rGþ˜¤á‚–•Ò㢒>¡ÀBKå3³{AÔ•® ¡0³/(žÚ¤;°0n¡-	,l—¶ûHÊ[i™°½)P‚ ëÂt
+Rº•©Ü™?&ivš,´¥€_Ò”¿ë3¦·ÐÞF…•“® Ócf_Ϥ2
+IÝp+-µÁÀ6éy?IoSdèÑÌÆwXçƒ ¨˜® ËbfSñt,ïwçIê,AÓÐã/Òãâ’¾ ˆÇ#02µA	á
+fHÌìkà¹T¦‘¬´i>ô¸Uz>gÎJ+ôxüªãz36!\A#YTï§roþ˜¤Þ4÷xü9ðÜJûšâï§ù¹vCÒÀ03Ñž×	‚F!„+Ê$y(>ŸÊ4ä9_Òd¡-	lžûKAñÅÖ_Ö¨kO/Iz8ÞÌži­BtfB¸‚ $ïÄQ©ÜŸ?&©>—–Yi›¿–ô
+Å=ß«ÄJ3³O$í
+< l(éU<Í]á9tEB¸‚ 1³o€S™F²Òæ§ÉB[Ø8mÏ#é]Š{<~^â:I:8X	¸øBÒ	ÀUf6©ö¯.êCWԁd	Nåü±öjqš††Ò’’&2½…6÷œ<¿å€>©œüEÒÙÀáDtB¸‚ ÁH1_N¥’槹ƒÈ†éq^Ü¡d$wÙŽ‘t)pf3:3!\AЉ0³1Àà¡ü~I³àv "UgK ûIzø£™½ÐŽÝ
+‚v!IA×`Nà` gçuOeàyI·¦º
+¤9%m߁×Û1v®e›ý$íTË6ƒæ„pA'GÒVø<×ÊÀ¬ÀxàK`ðð	ð08ØXXØø¬ã{]’E¿tàõÎÃœW¤K$åÛX ø[›z´HA'EÒLÀiÀöx³w€7€÷hZD=º5×zwpœ11³5hfc\ ³6_ú× Ý aqAç¥p¤™-hf+™Ùfv‚™]af˜ÙÈZDíô+IK'éMI›JšOÒÓiZvÞÒ’‘ÔCÒ¯%)é/’>t½¤rçÎ!é_’F¦vo(¸æž’Þ’ôh²(³ý”ôI×HúXÒÚ’•t·¤$½*iÇÜù‡I:BÒå’FKºLÒ¢¹ãHZBÒ¬’^*RúIZ@ҝ’FI“Úš=Õ? \ŸÎßVÒ 4‡˜]c¡Tœ¤×$ý:wì·é5]šúw¹¤Amý̺:!\AÐI1³ïRRÎvCRààd¬¼mfcï€_åNßx=õ©?ð[ÜME<ièI¹s¯Æ‡Ô¶Â׳ý5wl^`U`=à\à’C’Tç8à|XñàfÜaeyàÏÀe’VMçϟο;õCøðŒeYÍlbº^V¾Â‡]'~Ì…¹|üX¸˜%µ›­×»®]1½Iúiª?_jûÁt|rj3h® ZÂð?âÕ$Ínfæb"þئy5î
+\œ«û¶™]`fŸâQ=z&—þMp¯Æ—ÍlŠ™=YpÝcÍl¬™Ý„äJ¹cC“U9_ï¶\jë#3»xØ%wþ£fv™}
+\
+lZô…š}™Âpmƒÿm“úö1ð
+>‡¸¾ä`½Tgrz&¥‰BwpªwŒ™3³!ÀÃé½ÊxÂÌ®NýûWzo‚á
+‚ $I¶Â“sŽ‘t•¤…Óᛀ’VJÇß1³—rÕ_Í=ÿè…»å/€‹ÑtëÔ¦?ñ|ݹsÛÏæž/ ŒIâ’ñ>|—ñJm5CÒÀ©Àϳ(%’æÃÃyšêNæ(ÕF §e¥úWø>ÍSfÛ3,!\A´ˆ™=jf›ãÞwŽLû'ãÌ~À>4·¶ZbnÅ­\e—òVÍH`Ióæö­Œ­´QIƒ«€í
+"í Ühf;›Ù©ø°džÉ”vt	Ì]àu¸Z‘6‚
+á
+‚ $’‘´¥<¥‹pÑø wÊÅøüΊÀµå´ifâóR§KZKR_I›UÙÅ×pìLI‹I: Xøw%$g‹;ñ9µ±’N¥0X^Ò<’6v+¨þ°SrN™=À̆Og$§}u€Ë*©AFW-aÀÞxà»pkéüiÍFâÂqu
+(œ1wÍϘ
+<‚¯+ÿóŸûzjøZЇç€,¸ð[¸›v}óW÷À6v~ifÙðà;¸ƒHÆ·øXÆ“øz·9ÒkÛ¸<WzW¦><<•kãTü}:Xø³ŒmÓë¿+½îsKÞM}Ìøw	Z@”õ@Ò à¥­­ IýðdŠýêÝ— 8’Žú™ÙQUԝ“µÌìÖÎÚI×·˜YYpg$,® ªBÒá¸eqIˆVБDäŒ ˜É/ ®‚»›
+‚ Ý	á
+‚ I=ñ5E+àu³Ç×)ÈÚ\.)´Qt8!\AÐŐ4ÓÔb¸#ÀËøº¦³—Íì£4ǝ†® 褤 »K1½H‰&º©af6©N]
+‚šÂ€¬¨¸@½LΊªW?ƒ #á
+‚"YQƒi.P+àë„2º8·¢&ש«AP7B¸IO{šÙëõîKP{rVT^ ¥¹uaEA3B¸›ÀLõîDÐ6Š
+‚ÚÂÕ
+’ÖÆnÍ¢F§ãÝ€ÍÓñ7Ìì¡ÚÚ
+Oi°.0·™]–êo,‚ç2z¸DÝYñT
+‹ŸwšÙWéئÀsùˆÚ’ÖÁ#VŒªî•Ր¢¿
+TfEe÷¯„ÕÂÕ:ÆÉõÀ“á-i3{.%‰»XOñp‚¤Íl¿mÝ<†ÇK6M‡²    IDAT{*݉ߏGÊ~8XÒÃf¶‘ºûãwí#€Ó$ý8‰èÎxŒ´?g—Ň.Ýö—#gE:LÍ*¬¨ ¨1!\åñ…™m i<Ôó9`\0æ6³‰’þ
+Œ”tQ.ˆf!÷›Ùi©­>f¶RÚ>øPÒyf6,_ÉÌÎÉoKºOFwžÐï&I'¤ì³»¤ ¨A)°¢2
++*êDWyÜ‘{þ"žÆ<½ø#)í7f6JÒÀñdqŸ7÷|M ›¤Ësû&à\3á’´ ™z}`NàGÀ›éºC%}„'ü»	ύô§Ê^bc#IÖΡ˴¢îÎ$¬¨ ¨!\å1!÷|
+нÈóŒx
+ƒRä3µžúáÂܾñ;ùBŽÃ‡·1³%]BóÏïB`?IãpQ»£HI}ƒðT%ç«hw ÓÔ¢xŠ‰Ìaâ^Ü£ïãRíAÐñ„pµ¡À’z›ÙIKàÎÏ•Yÿ\vKC|À4‡B6öH¢5°%pCîøUÀÀ)Àeùö:#)Ê€ßã1®²™ð¹¾B‡‰©¸8½Œ[Qg o†OW0³{%ݼ+é.<ÞÙföj™M\Š{$Ž–tªg}Ü{°0õøåÀ%é:›Ó<Ifö¤«ð4ã{T÷ŠêOr,98˜øøM™u­¨poͼuaEA§&„«uÆä¶ïÇÓ…`f;JZw‡?¿§p«é“\Ý)ÀÖ’VÁçV¾N4³L´~‰{2bf'K‚ÿ)ÿ¢ìYÐþÀ½Ñ)#%$<
+Þn¸§å7À™ÛîÜRVÔšTXQAÐ	áj3{©`ûcšÏSafÓ<x©¶Š¦ä6³ç(2¼hfOl†ž—æV ~ü¼µ~4’æŽöÃkætè[<eú0I›Ð\ 2+*s˜¸÷è+*f B¸ºkàCk‡·bñ5iXïOÀž4¬Œ™€ímh²¢î&¬¨ ˜á	áê˜Ù½4w³oX$͇‹Ï¸`•úþ€/¶ÞÚÌFwP÷‚ èó^‚š#i^IF»àst-}ÿfÁ‡‡IÚ¥ºA'!,® CHnüÇ—áëÌææÂ[ssàÞ•ßáγÿ‘´°»™}Öñ½‚ ‘á
+Ú
+IͼÍìK<òHkõúà¢6/M7?p´¤³"¬RÌØ„p5!y®œÊ*éñnàˆJÛ2³ñ¸÷ät”A!\AÅäD*¨•q¯ÀçS¹8$ÅnìW·ŽAÐ%	áê Rú“U€å€EJ?|aòØ\“‡æ$w8)KïÊ¥¨HÕ«AÌX„pµ)tÑÆxx¦MÏ€§ñ ºãRùèÏãdó9ƒñ¼[JÜÜ^¸ ºÆ}.G¤6³Ú«A­ÂUC$Íì…§=Y¢{7pœ™½ßJõO(ˆ?˜Ú쬎§,¹JRoàvàj3{²
+}-©UðE¿™H]NˆT
+HW
+H±óöÆcí½ <jf“ÚÚ¶™MžLå(I‹á‘áÿ-i8p”™M'xýË‹T6/Õ“© :!!\m 	ÖžÀq7ï­Û;ä’™ Εôw<¾ß)Býñi­Ô<4wš(©…HAÐY	áªIëã–Ê+xrÇç;òúföƒ¤ðöïKú_¸û!RAtQB¸*$y‰‹Å.föp]w Ó;Nd–Ô£x$õM€5“ÌlhGô+‚ £	᪠I³ãžus«¶—›z‘Zÿ¬žÇ­©Ë€‹Ÿ½TÒÏ€[$df7AÐÅá*IË7â}Û™Ù5j7©ü¼Tš†ûJ‰TQÌìþ$^·KZÔÌάE?ƒ …®2´p>_t}ÚÀôŽÝirœ¸øM[Óx˜Ù«’~
+Ü!iPj³&BAPoB¸ZAÒ`àj`ÇJæ³$ÍËôsR5©R˜ÙXIë ×wJÚ.Å ‚ èÔ„pµ€¤þÀxfá’¢U†H]`fcÚ½Ó9Ìl‚¤­p‘¼Ï&AЩ	á*¤Y€[«ÌìŠÜþ¼HeÃ~Ýhrœ¨‹H•Â̦HÚxTÒáfvV½ûAкŒpIZ˜ÇÌžªA[Â×@}<#éšÄªMŽÿö¯D¤RȦ¥ðĉ¦2Wø»ðq3û´­¯#ÃÌ&IÚ>½–§ÍìÑZµAÐÑtzá’48·~ViC;óÒdAm,‰Id¶b‘ʵ= 5¸5ðS<ÈîûÀ{À(<Fàx&à€Ë%  n3³'ª}]fö¤Ý«%­Éƒ è¬tZáJbp"r©;°¶™}[fÝù˜~NJ¸@½Š‹Ç¦m]\œDõàÀ=x¤ÌlB+õz ?Á£Ã_&éCà3û_[úcf÷Iº¸VÒFf6¥-íAÔƒnõî@¥HšSÒ9À»ÀÿáÃl•²J$Í'iKI'Hº=‰Àóxœ?«˜Ù¼f¶ð=pk[DKR?IgàwßšÙNf6¤5ÑçdfO˜Ù‰ÀÒ¸sÅÅ’þ'iÍjû•8˜×Æv‚ êB§±¸RÔŠ#ßâÖÌéÐ8à霼%•
+ûA“ãÄÅÀ~¥"^¤ µ+µ¡ŸËá¹³î–më\²Šþ#éj`àIçšÙU¶g’ö^‘t™}Ü–þAt4
+/\’z‡Gà‚5kîð÷À}ÀI+F“úEÀó†e:¸¼Ú ´’¶À­£ß™Ù5Õ´QŠ$`WHz¸)EòØË̾«¢­1’®Ãß× ‚NCÃ
+WrG?ÒêIsÁÊè	üˆêDªðzK ÛáNÕÔß8ØÂÌž­¶­af£%­
+\<&iK3WES§/K:ËÌ>©m/ƒ ڏªç¸$í%éZIÏHzKÒ³’n”´Sr.hCÓ:÷è;èKqÑïÿúøb÷6\à àB3û¢ÒŠ’~üØ°=E+Ã̾7³=ñuf·¦ÌË•¶1ªqX­ûAО´Å9ã0`G`U`q|Ni[àܪ†¾@oà—ÀäT||;LMuzk o§…¶Õ²D·"$Í•êíkfo·áúcf§à.õվߧ{§×AÐ)h‹et?p.ð>d·°O:¶‡¤CÍì«
+Ûüoff;$uÇӈ̕JÿÜãü©Ìö˜æ™1³÷˽¨¤e€îföJ…ýwqÿ¯™Ý^EÝZ°ð”¤CÌìüJ*¦µ]Cpç–£Û¥wA5¦já2³CòÛÉi`;|Îi*.fm&9%|œJYHªôÚ[ wVXI«áîê[WZ·V˜Ù7’¶ž–t¿™
+«°‰óqÈ® :5YÇ•ˆ‹ÀýµYT)f6¹Â*[ày¶*åÀ™õNbfïgáD*­;˜’¢àA4<m.IÛIúéw^Ú}6)¢S iN`y ¢Ç’–Åç÷þÝýª‚¿«IúIuï6­q‚ Ú…öˆœ±7†©³°ðzë¡vþefßW{aIËIÚ<EöX½Úv Ìl"ãô*ªßlÒ–ëAtm.3»ÁÌfæ~‡_ê\¢PtæÁ-ÆJY
+­4 IÝ$"éeܝý@Ü©åò´¤`ÇäR
+—‹JZ¡ÂzkH*µì ‚ a¨‰ÅefšÙÕÀ]¹v^‹¶;€xب²‘Ô·Ôž©°^wà
+ÜÝÿ`13û¹™mNÂ…ì*ć4×vÕ¦ø‰ÏëTzÍ ‚Ž¦*á’´š¤]²;t9« æN«&šC=@åײÀ°4<W	ÇÓ—lbf˜™e̹ÝÌÖÁTß\åúªÛ-«¨w/°qõ‚ :”j-®E€ÿ ã%½|<Ì–Ž¿ü¯­ë æ¡r‘í|^II3;»´6ŸffC€+ñ€º•.Yx”WÂp`±
+ëAt8Õ
+×<bw`!šÜàÇàEY¹±€¹©`X¢¾XºÖÞ¨ ¤Ô‰x¤#+¹HZ
+p?Í­ßr‡¿A
+MUÍìq`PûR/ÆãBT	³àa¨*aV<|UY¤ô#gânφgS®„á
+‚ А‰$%­ŸÊ¼p¹±@¥×
+,ØêY͹˜/EÛ(—¡ÀÀ´À»F+¬ÂA§ QÓš¬€G³,i6àMÜŠÈ—÷Ìljé&ÊæC`
+뼃.3›*éoÀ…’þ¼ßZ–e3›"é^|qðå\î<àq%ýû69ÙÌRMŽ¯ ‚Ž¢!…ËÌÎÅø"©/î*ž•}Óã¼’F0½ ½Uá¢àñ•0è%i3«ÄIã\|nl[Üð^Å_o%Tcq[]ýqá‚ hHR¸ò˜Ù×ÀÓ©L#å Zœ&Aۏ8HÒ‡4	Ù4k­D´úñÔ•ôÉ$ÝlE–Pr¿4•r™¨4îãªþ˜® œ†®R$«êµT¦!©	ÚZxdŠ¥R\ÅBm"Õ¹ßìNeCxÕ0îª^ij‚÷&TQ/‚ Ãè´ÂUŠ4ïõn*ÍR•$'‡ü°ãÖ4
+;¾¼@ùóhwIšÇÌ>j×’華“«„j…k|4‚ aérÂÕf6_¯ÔÌ)BÒ¥À7xØ£Á¸…6÷ÁôÎ!o™ÙxIÿN¡)fM‘Ôø)°_…Uç¢B±KN0=Rø§ ‚†e†®¸øC‘䘅óh[ã	I¼
+¬-i42©Ô<ZµüxÔÌ*µ‚Ry4ù	k+‚N@—ópµ¤ÙóÂSæ<Ú×ÀoÍ€%JÌ£
+3³Šâ!&oÊ£€=ªx='TX'†	ƒ è„p1m
+ÓxNª!eœßl-­Ë„/à“"óh’zSz=Ú”"—ù;p§™=RÉk‘4;°³°Ââ
+‚ SÂÕÄ¿?P†pá·À-À=ÍìN©Pò‚¶7MóhïÒ\Ì6VªÉf¼!ðD‹ˆÂA' „«‰ëc$mafwTR1E¸Ø8xFÒvföfÁ9ãñü]Írx¥¨ñÙ<Ú
+ÀŸñˆõ ¯JÊÚ›ø°ã—-tgsà¾JúŸX¸°p§¤n5ŠPAP2Va=H‹ƒÇ£²WSÿ;3Û8
+øŸ¤¿JZ¤Œz“ðHû³ ÿ‡[jý¾ÀÏp1ùX8!éCIIº@ÒA’6”4Ÿ¤ø¢è++é{šOû	ÅÏ$&iç*R¬AÔœø#Êaf·Hú“¤mÌìæ*Û¸JÒCÀÁÀ³iîìi`‘bîñ·°>´·
+žÏl;3ËGy/•»rû4͇³ÊsŸ gXj¥æÑ26+–Š&E	ù+ðpŽ¤S€KªH¢AP”KÂ[wÒá—̬ÒhèµìÃæÀéÀJföCÛêl,G“_(=Î‹Ç |÷h,*^kIàq`|¾*/lóãŽ$…Î!ÃÍì;I× šÙ%-´¿n‘}LÆã.žÛZ~1Iýð€ÂýÚòú‚öCÒQ@?3;ªÞ}	ÚŽ¤k[ÌìÚz÷¥½á*ޏÛñ?õÃêُJ4xÑÌN+r,?–/ƒpmà_øìÌ}ºy4Içâ‹­gÃCepp†™.ѯ®'„«k1#WgW|˜ï3«ÆË°C‘´)“±èš¯4öz*ùzÂ_ëÑø<ÛÀž¸ûþ$¦wÝÿ+°1°$ž\Èö–tp’™
+«é‹‚ ( „«fö¥¤_÷KzÍÌÞ¨wŸJ!i)à
+`[3û¦’ºiþjmàr3ûkA»sS|íG€r§Îœ·¶–ô8p¬™
+­æõA´FW	ÌìI‡7IZ-¥Wi($ý¸
+8ÒÌž¨¢þ‚xn°¥
+™ÙÇxš“Grço\ƒ§M)üîôHeC`ÝëT<Š~AÍájä!¸
+pWò4ü¤Þ}ÊH®éCð±ìË«læXàÂÖ^WŠÙx.°>¿UŒÌiC¸¶îä²Í-´ ‚6ÂÕ
+fö{IÇC%mÙÆ)¬ÓñˆöUM¨Kü÷xlé¼¥€ÛqGŽ	xlÆY€I¸[ÿû¸·â;¸«ÿH`¤™}–ê÷ÃקAÔ„®20³%
+’´›™U™¢&HZf7pX¢Zœ œ×RIËàᬮÇjd*£Úê¾AP-!\ebf×Jz¸AÒÀß­ƒ×$‡‘ñ,ÿiC;?Æç¢öoé<3{Ø·ÚëA´ò©’§Üš¸Ý‹’~Þו4HÒU¸;úfm­Ù€«€ßGÒÈ :#!\bf#Íl]àÀ)’O.å5GÒ’.žÀ#m6³çÛØì9ÀЮ¼81‚®MV‰™Ý%én`'à2Iï —÷·%ròà[wSß\¼îø’¶Mm¯ÜÖ¶‚ êEWHs\×HºØرq牻Iñ Kµ‘L.€An¬[WwâÖgµèkŠ°y¥•ƒ ‰®‚ñ^
+\*iV\|6ǽñ–4_ÌûQzì…‹Õü@O`0¸ODÙbàÚJIQ0îN1³kÙvAGÂUcRº»È¥"Ik™æN¥?¾þj0¦•¤mFÒœÀÀufvA{^+‚ #áê ’8}	¼Õ‘×M!¡îî4³ªdA4áUØEIVÞ½À#fvt½ûAP+B¸º ’–žÃEë÷õîOA-‰¡Â.†¤]³CÌìº:öc>`Y<ønAÍáê"¤,Çç  ëwT0à4$¹l*Ë垏»õÇBç jJW@ÒºÀùÀp`53ßטO$™§åp×þ×q‘z
+wéÍÌ>Oõúá‚APB¸:1’ÎVÄ#ÅßZƒ6{ ‹3½5î™	ÔùÀ«f6º­×‚ ¨„®NHÊÇu8°>Ÿõk3›TE;1½@-|@“@]•ž0³)5yAm „«‘²1ïÇ0¼XÞÌ>*£^¦ŸƒZø
+§Wq×ù³7[
+QAPoB¸œËp'\°f.–0³OKœ»lAYèN“@=\ÏCU8‚ ^„p5’úâw×Mei<úÅQÀƒff’fJkµ
+‡ùæ†Ñ4Ìw'>5®Ã_HA;ÂU$	ز;_*ó‹Ï àbõ1°$°°¤eE€wi²¢.IïutVæ ‚Ž&„«$«é÷¸(ÞÀ#]ôJe0°pd:'¨[€Sðy¨ÉuèzAÝ	áê`RàÛeÛÓãÚéqMõ8ðOàu3›P§®A4$!\íDZ°»4Ó{óõÁìf"uî(ñIºAЩáj#vóµ ¾`7¨¿á5²N]
+‚ ètá’´„™µ[¾«äP± Ó‡<ZM“@]“ž¿2#A5¤ÓWŠÓw,îYWáJ©î]Í—¾ÆEé5ÜEýà”õ8‚ è :­pIÚ8X¸ÑÌ*ŽB.©.H…Ã|=i¨€+ña¾/jÓû ‚ Z:•p¥áº-qÁˆ»ŽìÕJ½™€¥˜~˜¯?¾`7滨1íô‚ ‚6Ò)„KR7`;àt\lz§CßÛe¡‹Òy‹1}È£E€÷h²¢.K#Ìljǽ’ ‚ ­4´p%½_§âqúzçOîV•´'.Rƒq,¨Û€?ãv¿ïÀ®AíDC
+WÚÛ8‰¦h…Ì
+Â#O<	\„/Øýº£úAt<&\³}ñt3ÝZ9ðpEXTA3­	C‡‘Rrì‹{ôÇ篦âC‚_á®è…y¢fÃ-³a’–ë¸ÞAõ¢a,.3› é<`3  ©;0…bš"¨ sâÎÏK:8'.‚ º.
+#\ÅH©âǦòL©ó$͉Û|ÀÀ›ÒÁ ‚ Ãihá*3ûøx¹Þ}	‚ Ú—†™ã
+‚ ‚rá
+‚ :!\AA§"„+‚ èT„pAŠ†.I+ +=%­.iP½û´´(| {úL—¨wŸ‚ «"inI«ãk[O¿¹žõîW{ 3«w ô*žz¤;ðð™mZß^mAÒ‹x¾³žÀdà13Û°¾½
+2RÂÔ€µðpk —™Ù¨ºv,¨
+IÇÇàËœ¦ _˙ٸºv¬h¤u\ßÓÔŸž¸x›ïñÏšÄ+hÅÿè²ÏhM<qjWçD4}–™xuIf¨0‚ Ê¡‘„kæ‚í.96;ƒŸiԏ.û{k¤¡Âƒðd‘Ô«#AÍ8øQn{L½:”ä+š†”zâ‚ÎÉeøPoÆTàó:õ¥]içŒ :–äq6gÁîÏÍlR=úåÂAt*iŽ+‚ Z%„+‚ªt°¤/%]^ï¾3äœ40’Öö^2³s;àz'g›Ùkí}½Î‚¤™ñÅÂß›ÙDI‹_˜Ù§éøìxvð±Ù¾´&`6`0Ï">ÚÌ&¦ããÌìû‚ë	Ï<>;ðnîü™~i?Iý€)f6¾H½fö]»¼!U ii`î"‡Þ6³69I:X¸ÄÌoK[Mšó\ÿݍÞ^7³Æ[SkfQ¢´Z€½ îè ë½œ®·q½_{#àOé}¹÷ ³ôÙÌ\—¶³2èê˜ö=<—žO~ŽGÌ0àS`ïܵV†åÚ›œŽ/t=¶àZ¼’«÷fnÿ·Àþõ~ïr¯kH‘¾pp
+Ú¾+µµG½_g…ý¼Wä=¹°Þ}+VzHZ/iØ$3{24I½€UÓæfÖ,»°¤5ðu:ß™ÙЂc+}3m¾ Þ1³os笛~ /™Ù—T@ºö~øÝÀYé®óà#3;²’¶‚¶‘î¼ÅÿG™ÙÔ‚ãٝ÷\ÀH3û"wl~ ?ðM:Þlå³5ð"p*08Ø¡³}€í€ƒsõÖþ|lÜ‘ê\€‹ÛÀ%’ú 7óWÏ ŽÄÿàîÅãPn…ßd\|ZPïDàyàïÀ?$½fe…nÍm?)©;Ð03û
+¦Y"½ÈY”iü»ý‘™}XØxjk3{§Èþ…p‹õ`Lö»I¿—Ùñ|)©/~ó1¶Hû‹Ÿ¥óú¥Ý_YR¢
+­Þ#…ñï¹xè½U¯®)`üÿ½Y›’zã£xði¨¥wÓó‰–¬ùÜûùƒ™MHûºá–Þ,©Ýɹvû¦6Æ3á¡›©ëŠ9>,·ÿÁu^,wl
+0°àø3L¯Ü_“»£Éí_¯Š»ƒ_§º¤í5Óö;5¼Yõõf½ï.¡PÄâJ_öosŸåûÀÏrÇ×Þ*ø®l”Ž=Qðýø’æwûaqÿ2‹ktÁþÒþˁð5=†B“ÅõNÚÞ8÷ÞÀ×pMJÛóë§ç€ž©Îiß]iûð´=$׏
+Ò¾ñ©'äþþRï÷/õ1³¸.(rl&š,ÙÝÒ¾{Òöi{qూïïÒ±Ìâú'¾nÑ€áÀOÓñ>øM^¾îà'éx¿ÜþñÐwSR»Ùç0.º†¯Õ:+W§:g
+š[½ß ûµðž\žÎ;˜¥Ä9kÒü÷<¡à7›õél|} Ç¥Ç+r睚ÿq«t®ÝÏ€mrçJûO¾KïG³7ðÒtb7\)K	׉iÿéñè‚ãÙõ:ü/û¢LVHç”%\øxþ2À’@÷´¯P¸fÅUxÑ‚º=p‘]èQplöô%>ö¿`A½Ÿ¥kŒKçõ+¨¿hêWïzÿ;èÇÞL¸€mhœÃÓöWøÝö<øâGn~
+¬™êl+ý&÷]ö>ÂUêsÈ„ë?û¿Kû‡/åÊ‹é;ž	×Íéü•Óö¹62á”û|ßÏ?4í{"÷
+׶4
+¾TPN¯÷û—ú8$×Çq¹²b:¾þ§ü%pZ:÷®ô>vÏ}7‡¦ßÅo€_§º™pOuïNÛ§ã½ðÿÏ
+ñàÆÿHÇŸNÇóÂõð‡Ô·iÿ•¹ßÚpÜšÎßöÇ­¡±iû`K`$þÿ»f‰÷dó\ßâ{t|ö\?ŽÅ-ípY=“	׸Õ}6þÿû}z?fKïáûé¼p+kBjçÀtÍ/Ió°©ÝL¸¾þƒ‹ë´Î¾š:<gꔯP \éÂïѤ€+x2á:<mÏ‚X5ÒØoîºë•x#»çäêðB:ÖªÅ쌛áYݱÀ†E~è§æžÿ˜ƒ¦»ÍÂÒØø0·o
+
+4~ߎ?öBáúwÚ¾$wNö¾ì”ÞÃ-îEÚ[4µy.lÙ]èªéxWñÏ!®ìϬ„CsûfϾó4	×
+i;®Osçg¿µA¸U15m¯‰ÿá>˜¶ÿ™Îß5m?FºKÇo0³?™…sm/
+,Uï÷/õ%®qøŸmVçÎù¿Üo|40WÚ?˜¦›ð…Š´	×?ÒöºiûÍÜ9«¿þÜ—Ž›Žå…k­´ïâ´}\ÚÎŒŠÝÓö*¹:ýqQÌÄóš[½g·ð¾l„[ÈøO  
+áIDATþk/»ÑÙ„¦Ó¬ÍçÓ¾ÓÓ9™p]TÐn6÷ú+ÜùÀgÒ±=rïqÖnfÕ’ÎÉ„ëø¬Í¼;üßqËeo\Å'àN…¬ƒ…fúXJÒjEΝ[Ò2øYæÁø~‘óŠq$ð;|~ìüÏðþr*¦<PW ½ñ7fW|ŽåzIóœ¾3nξƒÉ6ÞÎKÇ¿Æ¿d¿ÇŒ'âB¼!þ^üō,<WþµË›#=ifÍ¢TKê<\’Î{“¦l ³µKo»>‡â7`‘4LÒsøÄo«iÌÌò¿ÇñÏvüFää´ÿnüÆm-`¢¤+Íl8p>>äö–¤§$
+^~\Õ+k?n4³ÕseXîØ‹4…[ÐÂ,³ÖJ‘…^Êæ€f´$ðþŸönL;^ÀóéqbÁ9½Óc6_\Ö)ûmvÇçB·Æ?—i!놙=`fá¯ñwi÷’æʵÙ#×ff}F¡¨`û’ô¸K*àó¬ù¾öεûmjW¥ÚÍ»Ã?Œ¹Ãÿä/ÀÕµÝÓãµf6YҍÀþÀn¸ªç9,•ŒÿšÙÃEÚ,Ævéñ3;-=¿®Ìº›ã¯í]\dÁ'£³±ûksçaf×'g”ã€uÌìZI×á?úo,çþ-é“ÔæaÀ“À­föj™ýêJ¼Š'ý\Ò_ñáÁårÇ2V•´¡™=˜&Y{áwßâ–úö’–ÅoT‚Öy”&§‡i˜Ùÿҟ⮸5;	¿£¿-òLª÷FÚ›¶¿Í5sþgôyjó÷’îÃoÒfLJ¦.±äLefŸJZŸ£˜ÿ³ÁÌ~+éü~@jï8àÎÚ¼5cž”x1c¬™Jÿ×áS&Cñáì“pç”×ñØ^À’þžê.hfïæÚÊþÌ­àš»¤v¯6³$ØBÿ2G§Â6žÁßó}$
+£¹ó
+4}Æ݁_˜ÙH˜¶ h,JIÇà7:÷á7'Y¬Ø,=J¾Í-ÍìƒToYü»–§Ð	äÜ`ÙŸk›ðÿí{°WUÇ?«ÞÔFÁDÊGZ£–’â8–©ùHÒ™ÆÉfÊbj¦kÆI1•c>’¡	ŠŽ…Œ©)”N cƒh2Š–&䃈^”ÕßµïÙ¿ÃïÞ‹—ß岿3{îoí×oŸsîïì½Ö^û»€9Q¶"þ¾ŒóÊ!æH¶UúM*áh4%5x:·Ói*D«áŽÈ[†6-“9qÕæaRKïB/¤o& L}ìÉT˜Ì‘g6)ëÖT\–©ngO®É<¸_È?
+yFÈG…ü|í»E6æ|3ñÂf×ПÛš
+ÛЦ²SÙ¨ý S›ë³{ô"Z9~9þ^Žüåè“þ¯ÆEÛb*,©W]»Ã_å3C¾9S<ïÄ/Dùd*3êKñ¿›Ìx
+îðÈ,èÈò p4•)u9Ú{rÀ£<7Œ¼«C¾<äéœx0ûœœ3®	y3ÒðV†<±‹{27ëckö9ÿ=OÍƾ„ʤwF”'Sáø&ýçÇ'êfîÛ"ÒîÓ»?9´$SaçR?€<™ÖV¸ûJ3[+?-ä›À^‘ˆ›³ZÌÏêßçîWðÿaÒlÎ5³{]«»1.SDOH³xòÖIn˜Ç¡‰6GWÁÖ:Í^f¶»»'u|³»­¶ND“÷)hõÚŸ±]ã“ .ÜCЄv0š”»ûSw?ÇÌæÇîðhŸrS¬¨ÎBf×™h5ÖFeJž†Vëÿîí+Øåp+•‘cIl%<ƒ^´W¸û›fv:09àîךÙRdÖÚYs’[ýÍháþpÈÏ¡ßMÒR—Äaþ3ÐÂzÚOKxƒê]’ÌzwGûÅÑÇ?Ìì“ȹi-Z8Þ‰^üë£N]ë]O÷Zïw‘vþ)t8û4uZ¹Üý<3»™Œ‡Sí
+ÞU¦Çç'šô?ikPi[	§!ëÍX4,kMV…«Æßp8¼Sãj2KÖ5®…4Ñ0€+#^È
+Î]Ìð=i\£ÑƒM«†ç‰
+NzÖ¸Þ‹Z:š¼îGª¯Syª$kߐ4®È[‘óéÈ{­ÀþFå¹óÃV¯"K*©¤]#Å»ñf¤dœŸ½§®oõØvTzÕ쾞mñp”?‡æ!×Ëëkõ¦Å=ÑÅü©Ì4é3á"*×ÈmàîO™ÙhE Z}¤Ã‹¦q…¼*äd›ÛÌŽGG •üb4Ù¤ï»ÙoÓ¦ëýÑGZ)lÛ'"·÷Tï¤þC÷ãïȆ[PPP°#°9ÄL
+yR.lÙˆv0JX“‚‚‚‚‚
+…¾ `„™ýØÌfšÙ=×.(è[(WAÁ®‰“ÐÑ–‘-GAÁ;F1¼k0³¢½ÃwŸÜêñì,ˆP$†<¹Ú€¹ûª(ìîîÿ­µŒÎÂ
+V»ûú¬,‘˜nq÷²äuwoÏêŒ@Çžs÷Wã{ ïÐ-È`µ7cw¹"ïâ!gâPùH´~ƃ$ÕÌ>@0ç¸ûÆìš =ñqí^Í~0®«“˜µ  GѸ
+ÞM|­â'¶z ;ÚÂUh£ýY3›kfgGþ*3[/tÂ=»¹t?ŒXÙ3;èþo î5³tøs™ý*ûΛ¯áCþu´™õŸˆ~'ÆwŒò
+È	`ð‡(›ˆ<lŸBç…Ö˜Ù9Ñï(äÆü‚™2³áèXÄt}Nôõõll‹#ïØw|'v
+´Ú­±¤ÞIh%Ûy`PV>‚&,Јã0äÉ9°V6$ú|¤O ²òˆìxÿ,¯“ ÅMhúY›¶46tVfXV>æVËÐh—H at -}WÖçàZ›mÈ’ûBBš‡£‰ä¢L^‹<]ÓÌS¢þXÖçsÈë5ü¼ ʇ #곐ׯ_Š:‹BþZÈ7†¼ML¿§â»Û#îiê³yÿyÜnF^¿—ÇxßDç#Œ¾¿í¡sDNDŠ@§‹²çïhr{O«ŸMI}3µ| %õÒƒ­˜.@ú]OÅXýð¬M:§—¿ ÎËÊS?S©˜/ÖÇDù!‘×ò¬¯ŸQ±k<:?ˆ¼;³ðdd꺑Æñ,>íRˆ[Bžò}h’~i/¢<1<ÙêgÓäY¥‰ê+!§s9¿ù—42;D´fSÖóhí^¤‰«j; ¦P]M\³C6ªs”_¥qâš”=1Ä/ÉòïÅY^ÎV1/Ë7*†1(‚€SZý\J껩˜
+û?ŽFfŸÛÑËg>Ús¸™örŽÀ»Pd€£P ÂÁÀUMˆ‰Ï@{Yw FŒ™±ÇÑ>&©ÇeÍ%µò“ў˥1ÞKÑx%¢"»i³£þè û™f6MŒíè¥ú¯¸–=Љ|€	ñwFãl%«Ëºø›ØRP½D²zšè'¢ƒõk#¿NPü¼»§MìÄÓF÷x:ù‡ÒžX½MN¢ÚÙrÞî¡ìs'—e|Oâû;ÃtĦRPЭž9KêD¥q­yÕŠw_´¿™‚@&¾Æ‘è4þ44Á½F#`Ò¸¦„¼gÖçt¯q¥
+CN“ƵŽ,ü	_ÙY!ÉúJÚÚ~Tœm\rQ–%þ­êW!sÖ^­~6MžUÒ¸F„œX_¯fÒ.S¨Œå!Ÿ×–øñþåIãz;žÉîTZÜùQ§+ë±¨gݧiÔ¸Ú²±O Ò¼÷AT@‰¥æܨsx\ãˆ4 ª¦>†"í>ñUþõݾÇ%õ¯T4®þ´ºM«ø×ÝýY—Wâi¡³ V”áHëI¬Ïõ•|â{™Š±y»Vò4†>ɱÈßÔWò/vQ–Ê7ÑÈk¸]Ãñˆqào}'ÄŸãï
+(ÏA]Ô[‡´ÒÕha±Ž*ÄDWØ-ê/G“âw_ÖMý[Q»=Ñýÿ
+íþpCD˜‹öD¿AÖbv„ËÀÝ;ÐÄ™œKêÌ<
+èɼS°ó£Æ iXDo5±XŸjfû£ý‹f8ÕÌf¡õ$ôqôÂê
+“ÌìçÀé!×ÉŽë¡þ‰¼Ê&˜Ù"*SßFªFW#g¥È¼9×Ìƺûfw÷9qÚ“ƒ¾ûBü)ú-¦0B3Ð^Ý#!/DnêÉÜv1ºÇFÞcHûªP?‚œ=& gªWnó3ÉoE­ÍµH3:iG)&×[TôpÏÊÝ·šÙ	hB:iòËP¨ö-A¦|âú¼ÀÌ&¡‰ô0*º´ß è+(znAA×hµÊWRï$¶
+CrPȯeu’§ÙÁȱ=äG»ò†OŠúÉT¸:këÀuQޝ©0o³85ê$SáìÚø?ƒ&)§2!m%¢M£ߎ&¸Ä0ï(~Ù÷'SâZ2Èþœ¨L…ÞA›d*ì’»Ç{U”ß[}ÿJêû©h\ý
+aHФ4…Æ o—¡½‹vwßAõÎF&›YÈâ#è|NŽï#·ùCQèßFþšøŽMÆ3ñ†Â/ˆü¥Ñ¦!§»?hfGæ¥QÈTx›»'­cïhw‹»¿afßC‚™ÙnîþŠ»¿ff³‘sÇMî^xWÐ70™(ï@.õÝ¢0gl7"Ñg‘¶4;êAZÀ愁8èz,ò^Ü8Ð#lAß‚™
+C–€M=V.( ìqô_ƒÎ.½ˆ»–I«Â3*ª‚‚íÁÿ 1t³
+OXx    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_pack.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_pack.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_pack.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,307 @@
+‰PNG
+
+   
+IHDR  µ  
+   ˆ3ûÅ   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìwTTÇÇ¿³½°KïM;öÞ{ï½Å$FMbŠÆXbª½E£&QcîػØ*¢Azï°l/óûC×T0(¨ïsΞ³oæÎÌÝ·ï½ûfæÎPJQÝ? j ˜TFz mÊHŸÀºŒ:†•!Û@ƒRi< S ðJ¥7 гŒ:†¨Q*ÍÀ„2dÛhYFú§ ,J¥y\†l uK¥‰žêÌ.•î [uŒàZ*Íþ
+ê< €w©4	€)eÈ6йŒô1 œJ¥9S†lg ÍÊHŸ@R*ÍÀ€7¤ó ö¥Ò\Œ,C¶ ßRiì§:‹J¥×ЧŒ:ð*•fàÓ2d[hÿuþ¯÷Ï»xÏ—¥3sÏÿ?íMßóCP:£:~ ° ˜•‘ÎÀ/#Ý «T€¸Ya2yzòI©t auˆpÊ©³à:K^ ³è:s_ siY A9uf¿AEeèÌB)SKßÀìü¯‚ÒÿëKtæ¾AÍÊÐùE×â¿t~JY×"÷×¢è×bY:ó߲Εqÿ0÷ü¿ufîù×")q200000¼Ó°ªZ†Ê‚1jï
+ï„Q#„´"„¸TµÕBˆ˜2¦Bsj„žLÔVzJiQ9Û­@F)••Sž÷ôb¨<t´OÚBÜØUµȤ”¦Tµ%!„HxfV®<ðHUëò!S¬—)¨J•XYB€=§‚m𝧋Ýø5a¬°v%Ðd•H‘ \FRšX‘úy<3O®…-÷utc¨tJ¥Q[œ@SÕº¼÷aõ£íÅÄPÕŠ|¨d)(û`„z€jeÔ ss7žwǯ
+«Z‘•ü¤[¸àcìòÊSJ
+ Ò+jÔ ð"‡I]EË•¤ ÀÈÉ?¤ø/U¼ž«~‹i*»z]ªóõ½ÅP,'þÓ,´ÅYU­Ê+©kË"ß´3®*bÍM…UUëð"­Ýz¤ºªõøP	Ώ­ŽI…Ú»Wjc°u©£¯j=>D4yéïÄ\-ÃûÇ;aÔ!| J)c¤þ…iNí]y£î	À³ª•`````¨¶ tz'zj N¨¶^tU¥T`O¥µâûzQòBåC1uãÚ‘Ÿ]Ò#•Q/¥ô?y[20000|TÚð#ÕQ;½x›&Ã0ˆ-!‰ªhÃ܈¾òY•Uu&þž¿ÙÝcó4Šü
+ŸÏ¼Ô0nfÜM¾Rž^n×U†w›T¹Ak¿NÙb-ej(Go³~ªŠ¸¸ytS«»¶)™vsßt÷ã+Úw®È}°aHÃ#‹›õ€Ã‹š<¿qx} ˆ¹½SâÿK½ñ»g»,|QÙ»§Õ8¾¢}ç«:u?¿ÊúuËÙu}›]Úª×Ëd®ïšRóà¯
+F¿n9‰wßêºáJë©ÅÏR´6j©G½#Ò6|¶.ažâ~A€v»ì²v£EgÞ{é2zT|mǧÿPP.a±å/¯ói;j}ïZ­Æ¿pýÝÎYëZ^òƒw›I… pbE‡« ¬bY,nº{Ã~‹;NÜûö~ÃÛâA¦^òÉ‘Âl—Mô¹
+£Eä7Ö›_V¦Ý¦‚7>³<`:®¹2w¦“„e ”í(aå¯í'¹PÇ–Süæµg0‘}ùsº¸ïµ“»uÿO< ÄÝÝ·P¯UvÈM©ãÖÀIYžzŠó’j¨Š²›8ÉbsÕlO ÷O-cÐk¬]êõÜö¢²)Ïת[sùâû!§Í?¿2aÜòŒo+ú[X\¾ŽÅá½tÙ›+0°Ø\UEë6qò÷.A“Öù¾nùŠRiFMohÊ⓾[ öøQç´¼¼£Úúyÿ¥nBˆ€|Ji~¥([I™3’Í>»4å eFq„»gC¥ñ÷üÍ¢on­Ó}Úá`WHƒOüloЪšFßÜÚ4)üD^©‡ÃÀ«Å˜ÉíÆü™tà'ŸORžª”§Ï<ð­·{ƒ~)®oj^¿ËWAM‡ßØ=­¥FÒ~ÜÆ ÐëTäʶ‰ukuH¿¨~«¡ËïØÖh®}–·ý£:ÅyInVÎ
+›n>†ªcé5E³6nܘ5}%A P¨¡Ï݉2ƒ0$]o9¸.? ‚Ót	§C5ÎR>Ñv÷âå À­©–»D\b{@ÞyÕ
+¥ïªÞ’Û!:sWs¶êìc­ógÍ…±\6èùX­­ƒKÝÀSdjï^šÎÂAÂR¥è­Ç4$sÙOæªuQÇÔBƒ¸C
+^–¯#ç½|­,¸|q@ê£óÃ,::Ï”²	a={™ÍI¼Ë»¶srƒ^k֤ߏ‡½š.ž<#Îo6 ÓXr¸‚gÏ36W âðDÚÓkz´Rååð„¡y)¡õüìÓqįQ[Mrk8¢QYg €'4¿6zQüš¼Ô0îñåíî…ž]bëÛknŽF‘Ï:÷×ÀŽJyF=¯–cý›õÿõÙ‚Ñ3k{7/ȈìÁá‰Òû͸¸ƒÃhÙ¾ Ž-kÓMd—Ú™+¤÷˜vä¨Ä¦¦žÍèY\þ3C~~•õ£k‡òE–)=>? 2w2\Þ:Þ[)O·Vç9éÔENÍGú·´8ãز6Ý(¨hß|¯/¹|³Œ¡?†:±ªsû¢Üøv ¡Žµ;î<Éïqeü'„€Ö•6ühTQ¶ˆÄ˜ŽE>5á"EW`´­„êÍQyá¹*
+‹«2hUÞ7÷Mw =_le€}ó½¦ßÜûÅjYfTçݳ]üƒŽÎsÌMv¡ BEAjó‚ôÈ¥ëã	ÍӍ}Ú£‹¢”§÷ÝòÿöoEAjyV´hÇwv›B|—vì»3m·@nò}^JÄÿ{'~ù»(7¾Ã©5=NlÒ öΫ¹.+.p”FYàšðÚC•‡Cô‘ÙÇG9z3 òɳ%*#öÊ»O=ZÔýÐCw‹¿óÇä)ÜÐ½¥ÁöÅ8­ÛÍ$céú%ì¢\%5»›¦³üäpш	þ…ýï§ëòTF^‹¿óÇ®¿­löʼn¢žwÉzÀÃ,½ä“Ã…#'*ì6FãÕôϼ‚Ót ÐvSþèc4µâòVƒTõßÖ9yWY8ŸÓ*eÝ5Š|VüÝýÃÅ–.‡JæŸZÓã”^§¶dq¸Ê뻦$†À±åm÷tj+ž@’V\ò™I¾0;¶W^j˜µ[ãd‹ËšGZ»4z¨.Îozm¯ pçðl§âüäÏJ…[îIAEVÎ
+ °ïÇZûTEÙ^bç/­Û¸ÿk7 Ø9Ëñ¼´ða–NõαØ\…ª(‡•ŸÑHžÓ 
+sú§E]ZÉ7³ŽÓªäG–´Ø ¹É÷Ý‹râÀÙõýš„œYüPj«QÉ\-hü7 ä§=hxw­A§6ç
+¥©‘WþÜ Ö®cˆÎÂÁ'ÐʹAÄ¥-c}òÓ|iíÒð¬¹}­«:M‘ ÿ#€¢Jë©ÑQ>—H! òŸ¢  ¥ôÞ­ãMÐfÔÚ#×v|jûø–ßÁ˜Û;"§­gÝØUùˆ«Väõ·<½/‡+¤‡øM¸ç?h䂘¿·c‘_¯ó—[vŸ™gª')üø'IáǍ:ua7KÇz¿ ¥F«]¿™Ñ¸ÏüìK[Æú€Rþø•™ŸÀŽ™6»/lQ¯~ׯc)5š{4>§ÝØ¿,nš“xw€pƒN]ß½aÿ™Zõá—®â»s­{l“}b)$òÑ
+wçv?|”£7K–lnOµÚ Ÿ/j½9XUkvqäo—º¿Hn•¬ç‹ãEm5T–¡÷XÕÇì( (´Fñù­6‰¸Ä°1Håé$aågq êþ‘÷i\¾A …j4Íâ1Kûí©¢;BÔÞuí8Á**™Õ^t¿¾=§\¡ë>tXlŽ–Ë7
+Ø0¤Z™ß§ÝØ¿Ÿß0ôW ¸°iD=›“9ò·¨Í °{¶KãÓ‹:ɳß5ŠG-Œ] {æº5 ôùÞzË!ËÒßò+[8=î8qkìñíw楄ŽÏ´Hê°×$«.Ν¸ýó¡FƒÞÃÒ±îgn
+ú*÷íJÅævµî O(½–üàÔ@—º=¶´ÊfãVf¶ãp…@pY¿K`f}rðÜ S NmÿÆüzÌ흒’ùy)¡ƒf6gxBsOh~/3öÆ“‡+¸?â·¨- à7ÃzÌU¿½:NÜs{‡®×—'ïOæð@fz­RØaüæ ‰MÍJ[{L)Õ®4£Æ!]—…gŽòk:)ÕÞkMr*«ê†“wgõ¨Eqk¬
+Ø0¤azÔÅ¿.ü32 ¨Ñ`¿gŽû–§¢„ËG¾¨ž@#”ÚÇ7¸`‰ƒg[MÌ흋“ܸÏül ÈMiÉå›…›ä¹éýü´ð– b	aµûw" 8xµ¾µýK °vmücBÈáñ÷Š$Ö5þ:?äð›9åÅÅœ­Þ9\zÀåÝ¡j·9Ń»xðÒ/Äió”Ô¼ãæ‚a @) âr_ø2Xßž“í,eï!=Ïçã…8­­«9;CÄ}Ãòf’ε¾='Ã$ïiÅN?¥qiáÂͱ³òlÄ,- ´påflRµqɝ)-„WÇ(ÂaÁ8¹¹0pjaÜ>ï<6îÍd<¾²†Ã»ÔíñlΩ07ÞƒÍᥚŽ9<Q’FYà™s-ƒÅæ¦ý?]œ¢Ó×|Y=??veï?…[n£Qä
+n=bMSžÀÌÆoô¢ø5Ç–µéV9?/5, 'ñ®7¥”#ËŒj „ÅQ$¶ã‚¸6'ë©A{!<ôYNÂâd&Gœ~nw½NU d™Qü§:*ÌM ›+H6ɱXìea¦Eéú{M?uïÔꮋòÓŽ9´°ñ"·&?ö›qéÆËtª(•6ü(mɽbÔRÏÌ-jg Èܪî@ØÈsþZZYmT7Jz;ö˜z8œÍ†©
+³\tý&Œ¢öSèä	«²?ž°*{ÒèÅ	+ €–J­È{Îȱv§kýf\ºéàÙöÿ±*	ž½ÁX9×ÖiŠŸ
+	éÔE¾Žuƒ€R£äցo] +þV=.O| úϼ|}âïyCuŸ9±0'nvjdÀó½h†·NIÅ±¾‚d;1+ÿQŽÁ¼Ÿ?YÄ%ª«ŸZ¼ú©åÁk“-®ìm :ÃóžŽÓZ
+cF5¤ò9äÙü-›õÿ ã-]¹i‘Ù{Óq|¾Á±Wm~ ä(V*# î¥éíëÚqÒà»v¢¨°éV~ëúKN­¸®ìñ¦ÎÁûDÏϏ†ò„ÒµÚo-™^·ý”k:¢…,3Š£Qä³ÔŠü.6nM.v¿)Ì ×ÖÎK
+ã€Z‘×îUmðÅVF™Í¡ÐsËÿäðDwMf%8;ð‡'
+¾øÏÈñ-‡­¸ŝ&ùý3jaìúQc×wš¸íRçI~©Ñ`þ*OIeaf;à‰5è:NÜU2_(±?Áâðd¦º{}yrCÓ~?e¿¬NBXJ“W¨,3ŠÓ÷Û‹ãWd~iéXw‘,óѐWƒŠRi=5×9¢Ç²Ëºƒé«NeíPß6ÓöâœïMŽ#ï#‡øÎ7è5Ž<¡4\§Qx´ªÆ­†­üÎ¥n_l}ìào¶óÅV×z—o–2üçˆ=<¡ôzԍÍâïùßµ æ¯ò´Óí³wÌ´aïúÞñw ”rzL=žw“O«0æήʼnaÇB4Ê‚Ž^íæ&?8%ºê÷ñ¾Øò¶A¯µd±¹I%ß$ª†~;dýÙ,<,Ùy1y;žr'4$²PÓ’•ÝyKÁ¦NÜä´Bƒy+WnÊ×mD}l9IƒvÉú6tä¤-éaRžvÆ7$lVµ¾WÞ=Oi”¸Y°³½mØŠ[ÉFžˆKTvÊyY³³‚Ótž›KÞIÑYþvIѶž='#En°¨eÍN{u+ 0fIò¿Üî}ÚO–‡_¹ïز6‡¹³ànŸx fÖîžXÕéÑ6'³<mÔiÿÙÞ{'ýÎÞ£ÕàÉÔð¼.æÎ΃ vKm<WžûsÀNÂbR£ÁJb]cûî·rª¿(äÌ⍡g—Rj°è>åà˜ÒõP£^ê÷­ÕQJ©Pjçµ¼tÏ®QÏYGî›ÿƒßkÂbRƒÞ~âêü~/Ó_ ±Ýçÿkƒý®0Š'²x¤”¥b±¹éF£ÞÚÁ³í—-¼.ÝOÍÒó3ç—EéOüQÑP“bt•´à<pú\˜\–LA€‘“0'_®Œ¡©eå—Ñng ‰”Ò„òÈó%ŽõZX¬zÓ¶‹r87ö|ÞX)Ïp—ÚzFwþdWDÉ‹ :p›ôáåõxBóüÖ#Vß±vi¤€Ûþ3]
+2"{uæî¹?û7nÔkNdÉ^šRžÎ¾¾kjƒž_®—{~ãðú FÒ}ê¡ w“fmŸ«¾=g
+H;Þ¬qïyWkøR OÖÀåÄ×™;&uœ¸å¾ÈÜé­m¯¢ÉKgú«¯µ,ûq¥´Úî”@éðSgјoڊߊWm¡†rŽFjœ“eI7nfO^nÉüØ<ƒÈ?B]³†%»pX=AªÉ3ñf’Î*Oiä¨ÃÏئvÕPÂ*ÑwËS¹÷Òô–=jñž{cÞ®vq–²Uíkpó àV²ÎòËEý6
+’¿‘¤³ŸÜ\'âƒÎ r4Rí•k°ôuääôõæg²ÞÒ*¸57V¿]VÞ|;-–BˆÔιqÍ~sn¼öôIQn§(/‘ãäÝù¹çPzôeðdú¢<õ\Þ6±vrøñÕWô­Hû÷NþfçV¿·Ìäm"øÄÏö5É7=Lìœåø‡…ƒ÷¡]¿¹'¶pÖ•.W’̸›üŒèËæ¦)’ŠzTœ“,i>páKzð©%’èË›ôjuV¹†Â	! Þ$ô•F­<¼†Q³ x啼-£VÕ˜ŒÚ¤?ä­ªZ—’0F­zb2j÷¾°ÚYÕº˜xŸZepàgŸ•ò̱ö­çôþêÌÝ7ٖɨõŸyåÚ›l§¼¼†Qc¿±)¥~ø°t¨£³rª7¿ªõ`x7¨eÍVLo-º^Õz0”Ÿ§kÔ¶¾R°¿"ãë·ÑΛâi8Å¢w%J?CðÅVƁ³/Tµï6b–ö£&‚ĪփáMÂ5†÷†w¨B,Ÿ†@a`````ø„.!Äû0j šp®j%ª-\ ÞH at UëÀÀÀðá¡ÉKW^ü?x(¥J Çß	£ö:æÇsSÃN1»eWFeñ;³×Wf±‘·'LmUÕz|¨dßê^[A¡Ì1žú«ïkïUÆðß!¤°Â±HßO£¦Í7Äßù‡ܪVåCE«P¼‘drýÃu‡ýÃuïŒ~¡ ò^)õöQ(
+R™}
+«ã«Ežç½4jZ­6Z«Ízµ Ã…VdeÕS 10®ª§Ò"µW2o-
+Ãy?!Ä@&¥ô•±Ò!€3„Bæí»*QB2)¥ÕõNb©£yU«ñ!CtJcqAV* YUëR
++±eMGf¬§jQd'ä Èx¥  Bˆ@Ïw¨P(÷p–™¥½…½gEÖÌ›V@©Š$FpÙ	Õº»,€€Ôô¨«Ùz\¹Â¯1T>w|aQ\P=/W_cýþ¿É«Z•ˆsËÍã²ËîׄÀƒw¨QJ£+ZÆÓ·¿Â¥Qßjwð}&'õ'1:à_{)UGX"3£­KêÛ›d¨R¬<˜ã*‚V…¦/žŽ
+Å2îªï
+,  „XBžõÚ!.„fSI†w
+SOÍÀ1Bˆ;!d €MxâjËÀÀÀÀÀPí!„°!  ”>$„|
+à€ )¥ÕfÑSCý:skb ÃLÏ Ö ø@<€yO7\«…·uf	sSWzVªªÀ…§z100000üJi¥t³ÉpIL¥”¡”Nõ4­Ü<è-ŸûEñ‚ÚÍù§´Ó*YYeeô5Š|VfÜM¾^§zn
+[fÜM¾F‘_n#®×©ÈÑe­{ @عå6g×õmjÊ‹¼ú·ÅÑ¥­zŸøÙþEe3ãnòËÒ£"å&pŽ-oÛõUrG—¶êùºm|¨dÆÝäï™ë>ïøŠöK¦ïýÁcæ‘ÅÍûV¤®³ÖÝ>4Ë üfX6¥ü­Á¨3löø¹îÄ•ÝûƒÇ·{æºÏÛ7¿Öçþà[‘kô9¾³Ûvn¹ÍËdvÏqýõü†¡
+^§þ;‡g;ÝØ=­Æë”}Ÿxxy½åñí;—þœü½KÛªÖ­,ô:‘eF=ç/ËŒâœZݵ͡¾ÃÎýÙ¿±RžÎ®Œ¶öͯõEäտߊG4 (¥4!„캀O)­ÐbH»‘|¿Ú[%Íx,¿7¡hepfm×ôˆ;º¤åSÚ±emº^Ó#îä”·­²€Uþp	 d%Üv*Ȉì сۤAGæœÔ*eÎzuq™Ë6¯ú}ìsúžÏ­ïh×,§€³ÿ(ÊM¨ðÒ
+yv·0;vÄ«ä
+sâÆU´n{çÕœõººwyÖc¾F‘7± =â;SÚé?z¶Tå|¤¥v«H]F½ÖÅt-ظ6^ Jy:»8?ù‹ÁóîNñkäïuQÎd¡Ä.Œ'¤eÆ^_tâ÷ÎC_ç÷غ7ßèäݹðe2ö­¸5ì—ô:õ'‡Ÿì’yîµt{Ÿ(Hh^œŸÜº8?¹u~Zø¯²¬èqÅùÉ­‹ò›WµneqmǧÞÇ—·Ûe:Ž¹½SrdIËëòì˜.½F’4ùþÉ®•Ñ–F‘ק07^\u½
+ B¼ t €
+À…âE)-w!ûåZõ]Õ°9ü»
+YÚ0 û 0'v$›+¸SR&52@~á÷&n½'2wz¶N%þž¿ÙÃ+5®ÝzB˜)Í£éð‘ÄÞ?ùÁ)Qè™%£X~´ÔÎ+DUœ+J=*®á;H !§Úé´J6 °XœÄ‰«óûéu*²gŽë®‹›Gw4çöYàÉïŠßÇM}{Îwòî¬.©×Ùõýšô~ÛQëîÚº7Ó8zwú ¢®ÿcžŸanÔkYEùI6½§Ÿ6•q¬ÕayÉ:BN/´ËM	³ë>Å?xÒ{½¾{j'?º¶É·Qïî¹5è«Œºþ¹N]Ô¤ ãQöÙõý¸­†­JìŒWü>n¨*Ì´·«ÙòQ›‘$WÊŸR!,%‹ÍK9¿qxýîSü#òÓÂGòDG¨Q/€¼Ô0îå­ã+åé¸é}Ÿ¶ïjÜg~¶F‘Ï:ù{—ÁÅ)#¹|³P”س0?=b€[‡øþM»#KZnHl® Àˆ_"w @À†!
+óSÃ;ŽZ» ê´ÿì†OûÉòËš‹ó“‡ð×(òYg×÷ëZ˜7œÅæf»5軥ý¸	 pbUçöǫ̀aƒÖElá¼ØOáòRÃg'܉×(ØW¶´€Ã%i”…Rûã]?Ý»×Ú¥‘.7é^W6‡λͤÓí¢·Òªd-„R‡Ó]>ÙíoíÒH·{Žë¯B3ېâüäQ,.?ѧݧ«<Û*dé#ÇL»z6n7
+ÄÖò´èKŸ
+:gBXEÃ~
+û¤ä}ô¾Ònì߉ ÀÎïìj˜Y×86xnЩ£K[õ¼´yŒONÒÝÎ<‘e²£Wû°Ä°cƒŒÄÒ±î…îÓs¸BzióUQ¶¥º8ÇY§.vòl1ú@ó3àôš­äُ;RJÙ¶5Zï>Å?âào
+GX8Ö‰ÈIê+¶t	0ëúe“.wÏvJ¸h¨ØÒ%¬÷Wg®s¸BzuÇ'ž…9qÎ:u‘¥FYàE at tFƒÎuß|¯/Å–.áê¢w®Àìê˜%ÉŸV³­äï;»¾_“‚ŒÈNޝOtœ°% -l<ÄʹaDfìõ>|¡Eb—O÷œ´pðÑÀ=_¸§Dœ!¶r½ûNÿ3L7œ€  ¦È
+V rߦ"/ƒâJ©”pF,/€è÷íöàâVF£ÁšÍ<3Þ‡ø½øϨý²ŒGÝüRï乿ùÀñ•:]Ûõف¢Üøöw}ÿ§I>úÆæ	¡Gf姅‹µêÂúÔ ·“eFµÉŠ½Ñëö¡Yφ–".­]˜Û£¤.®Â.Öª
+íàøŠöþÚp§<3ºÃ…Ã·™†6iè÷­ÕɼÔðþò¬Ç®íœÜ!-ê¢(õáÙM ¸µåã[~~ñ÷þš—6Üï[«#™q7ù °ÓÔÞ®ïxùÏyÙ	w†î˜i³K)Ogç$óS"ÎìÜ÷õڢܸŽ—¶Œ9wÛ¦KNR°•Ñ¨·Õªdõd™Qm
+sâxûª½#/%¤F‘_#)üÄ°Êø?ª3æöµd'Üžüà”H¯SûÍlï›ò.o?X]”ӶͨuÓ8<QvÄ¥µ‹  àïÁí²´þ-/,[GôšgCÓz­²
+ 4í˜W’    IDATÿë÷„ÅIŸ°*ûã&}<¢,H›bê­gÇßš$0³yl*“~Üã캾M‹ó“Fò„æwàìú~]
+sãµ²ô;ÇZvÅßóÿý©NÞù©¡s\ôY;jAÌpÇÚï €N«hª,Ìä«y­J>ŠÅâ(ÛŽ^?I«(hziËØá  Ó×Wç˜@ø…5ëÄÎa½§ŸùX«’{_Ý>©/ è5ŠfÊÂ̶­G¬žÌቒnÿØ¥n•ØÂɏ/¶>6aUöÇ}¾>w'5êÂwv5[mø{Þк>ŸÍYV8~ßûDQn ”‡gWp…æ©VNõ£ó3:‰¤‘–NõÎç$ß›r|y»þ ŸÑ0;1h­A¯‘r’´‡—×ï€[¾uÍI
+žcéXï‚…c­’ Å)§?º8_lá|¯0;vО¹nóà̺>Í]ß´U(±{T˜Ûsß<5 Ÿî“›to­V%wµpð¹*0³‰!,–ÌÂÁ'ÐƵq‚¹}ípº¨û_êN¸í?Ó¥äoØ5ÛyY~Zx©MÍ ¤°ã¿œXÙ±# ç%O‰8ý£Pj©”gt>»¾ßç pî¯A¾±w÷l™;†åÄõ4´•ígñ/!|BHK“Q»` €¾ ÖPWtøñ
+ãŠ
+Îñ½±•›Rø‰á‘Wÿ*’:.™WœŸ<©^—é“Ç,IZdnëµ>7)x8 È3£Æ¸Ôé>kÌ’¤Å>[K×éÛknŽ™•ÛYOô`ÔÂØõu:LÙ£.ʡשHÈé…v½¶V¯é§€
+.;¿³ÿÛï[«“”Ìõœu d™Q×j5~öèÅ	+}:|6Cžõø# ÈN¸3ÆÜÁ{íإɿŽY’´dÀ¬ë—þõ£(åOX•3qÜò´Ùl® 6èÐìçÆñ¯lÿ¨5ÍÆ­ÈøfìÒä_9\Ñ㋛Ǵ}RÔhÞ°û·ßY’¼P`fëŸqº{ûqØþcKǺGF-Œ]oãÖXcÔëjz4á7rÁ㍣Åÿ^9ÿFõ¥Ûgû¯êÔEmïž=D ¶>
+Bž-sQfö´qk²Ã«ùè¢ß]ۣשeÆÝäæÄu“Úzîõi?Y>dþý£„ÅÎyY^ÍGqøâÀ‹ÿŒê¸Mª×*›÷˜vø‚)?+áÎY	·ç
+z—¦ý~ö€ÂÜ„þ„°!§MÈNêf4÷í–{c€ÈÜi_Ç	[âøb+cÛQëþ=œHˆ¦ëgûwx5]dãÖd‡ª0»{ÉìгKl­§B–ÖàâæÑŸRv±,µ¿)ßÁ«ÝöZ­Æ¹ÕïsR§.jSÖoâòÄQ™±7æZÐh˜ƒgÛBWøÁ/Jí™|¢ãÄ­±}¾:dáX'Q‘ŸR‹Íá§*
+R{›ä8\὿Fmúcè!Âbç]ß5¥¦FY  Ô(ÑiŠÍZYÒkú©{&y©}­í¾¿q©Í¨µ?hUò^ ŸÑWjãñ÷ÀفÏúI§U´2͝±8¼ØQc×÷ž~:Xjç•@»¨×—'ï·±:¥Ç´#a.uº¤UÊ<ºñÏñ3mý\üÃ*'ñ.O¯)ncåÜð4›+T¥ögäYŸM×X:ÖÝ<hö­ ÷FÖh”  /5´§Äºæ¦³/ô˜vôgŠ·E“ à™æÔ(¥t€I ~ ”Î
+”Ji ¥4¥²êk=|Ս¢ §º(gPÃß7¥gÆÝäzÇfýÍ çºÝïë4Å-@¯S7n?vÃ# ¨ÙdXXÙ5ÿŸF=¿Ïesø‘gÖöi¸}”Pb·ßts+Û­AßU[½Î£8?EP”›À1èTÍcîìþuÇL»­Q×7/ˆ ôšâvµ[MzY{l®àé;_dV\Ú¢d~vüí½¦ÖŽ™v[w̴۪ש<4Š|‡'úpR}{ÍÍ ®@š¢Ó(ÜJ×/2w2X8ÖY}cË¿o­N|("s'Oh~¹8/i®góQŸË¤”KXl °yB
+ې5
+@9„Å.vë•!¸ì<Zí,̍vnÙ0¾ÈêhÉ¡ºÍœø{ÞP¾ØêȝÃsžÜ—Ô(à	ÍY8øZ8ø:Öjÿ¹ƒW»|J)›Ö«Ú3°9ü'×!›k ès󹥌KQ›ê¶võ=ìR§û
+S¾™µ» øbk5¥´Ì½ÐF/NXéäÝyF)÷:¿qø¥Ø»{%¯:ï;bç(Ó÷?ù|’~b&›+(ä	Í
+ºg½"6WðìE„¶L)O·èôÑö{Ï6³åYŸXÙñ¼ÉI
+ $Ö5R À£éðbJ© 3î&ß Syˆ¤©À“k˜vatà6; àp…Ïô(‹îS=·<}Ö°ÃZB4®muc³3¥T$ËŒj#ËŒjcЩ­Û@SKǺI `åÜ@F 0hU"s‡ °­Ñ\Ë"ì7à“Rª¦”^gB6˜> ¾ðãÓc³7­DUáäÝYÍJ¯px¢ï6“žM ;x¶Õ;+äôB; HtÑ—Ãß 6Gðàæ¾éµ 1ôh½ò´cåÒp§,ãáuqîк¾8ðÿ¢í8qkìyÁ'ÄN]ý{žÄ¦¦žÅ„¹Öï½tª쏟~& ‡'¾´§ÉËÚ2èÕuMß5*Y}‘…ãý’ùÖnYì'C^O>9
+û)ü  ,´',¶Ê`ÐòMǃæÜ>;qu~ÿÚ­'~^¹à¿xo¾+x·ýäk—FÓMs&DR‡39IÁãR#„Ç–¶ÊæºÔí¡’Øxœ/ÌŽžüà”èز6ݨÑàôª6zL=NFs…,c²G³{Ê”™väO¦¸ãõ]SjJm=ªymëtOìõåÉû<¡¹Ò­a?…GËã
+YÚˆ;‡g;OæOÿU¥â›FÍŒ»ÉÏIº;J(±;W2»åeé„ÅÉTçÚvž´#´i¿Ÿ#8<‘öeú‹ÌâõZ¥‡©7p៑u»OññÛ£e,6'--ò|™žÀäÿ·Šª8§§³O×uƒçÝ=eÐi,_UT–Åé=ýtð¸ßØÕl9»0'Xnòýv piËX6›ëàÙV#Ø^,È|Ôx2·PÒrȲôÒõZ9×Ï£Ôøì…ãö¡YΦÿPbSSÂR³ØUûq‹S£ñà#£Æ®µ0v}·Ïz™ÎB©ÝeYfT;àÉð©Ñ¨wå9ª$8 –âID‘/üÀÀTT *> $ÌSø*#ôíô2Ú˜? ÿ’ïÊ~àõ§ÙÕJ׺³$iqYéf–®~áçÿ'êƖ륬‡ƒg›¹ `nçµ'%âÌŠ½?x\Ò©‹^j`Lôýæü­íßX,as
+º~_–L×Éûv_Ñ~Úõ]SjZ8xoJ?±lßžW at Xzƒ^m;viÊ/¶îM÷dÆÞX¸w^Íf„ÅV™Y¹…Ôí8-´TUdçwö³8¼,ƒVU¿Å Å¿<×Χ{íüÎ^¾ó;û¿øb«»:u‘‡¹}í³¾½æÜÇJn¤?œ¾÷¦Nޝ&?8õ5_dy_¯U:s¸‚Ð÷uX‰/²4p¸‚` hÚï§ì¦ý~º <¡y®VU íÆm8|mǧü‹›GïæòÅ!Þm'ÍžYžZÝÝéòÖñû9<Q(_d±ƒof­ S3=‡+|®·/”ØQ+òÚ—|ø°¹‚ žÈ  Ö.tR›š+3b®vî7ã’ßÙõý…!§þ~ÿä¯Ö,?Þ U}ÛmòþÈ£K[mˆ¾¹uqÔõ¬DN÷™¿‹Ã…Ìlµ ÀbstêÂçÖ÷;,0³=Ñvôúƒ Àá‹£"«B ðnûñ×	÷ŽÞ7ßës¢—ÚznÏæ	Íl5  [é8¼'¿¡Åà¥Á6hw|y»V.
+×˲¢ûoÿÖ²‹°åB3Û3'neö¬+ÄÊ}OòƒÓkýfXËYlÞ¿ŒMi.mÛ§(7~
+‹ÍK5õVÖ.Ö˜ò´JYc¿ÖA©À¶Fó P¯ãç'îŸ^ø›ßkPʵrª_æ³Î·×Üœˆ‹kcüfXšÙžaqù…Q×6}Ëâpã©ÑhIXœìvc7 ×Æn_ú8ÐOO©AÌY^µ0vý‹t®ßù«3wÍ_æ7Ãú  °Øœ·¶Î˜PJA€K)Ý „• ÖQJŸ“'„Xzþaæì0Ið/ƒg2j%Ó^dÔ
+Œœ„9ùreM­ÜŸód?53Kûzm†®ûW”þÿ°ÊK	±îôÑö˜’é×vNöÚz™†à¢®ÿc}k{³vcþºfíÒHW²|lÐîVu;N»‘pï`­^ÓOÝ‹Ü&Íx|Õ¾ÓGÛc\üÃJ–inòD€3löÚ¸7]Óçësw  ùÁ)Qԍ͵zL;òì¡vuÇ'žB©½²Å ÅE¹	œK[Çu¤F·v뉷ëvœ&žxE^Ø8¢#¥FvóA‹®[8xë®ïšÚ çÇC.kÝ£8/¹«“w§mÅùÉN}¾	¸l28gÖõiVÒ2èè<Ç”ˆ3­ÅΉ'í€+Û'6êùʼnàɺ»¢¼$q»1&@øùUÖ)ÏÖnÚÿ—û¡g–ÔS¤x˜Y׌í4qk8_lU¦@Nê#Î¥mÃ-Ù	ªSdšÒ…–5jwú’߬ïÜ
+o_™hù¬ý?yûÙ¸6þ³Ï7·ßT;±w÷Jnìžzú£5òöoªŠrò÷.6Ù	w’«Ù>!¶ž
+Ûwœ¼«Ì—ÑÿJzôeº8—ãÑtxqyäS#„鏯X´´ø™—ùöo-ÏÖïòÕD3µW«qÿš»Œ½»WâÕ|t…®m¥<ýàâöÞm&e›¼K~~•µ…ƒÊ­A_eyꋼú·…éVQ®íøÜ2ö®_>¥´Bžõ&£Æp@8žôÔx”ÒOÿ%ü£V*jÔ!m ¤”g^íeFímrëÀ·®	!‡'èµJï	«r&¼É¶LFmÜò´Ùo²òµò“w“n}ÿÃ<‘Å…Ñ‹âW¿É¶CŠ¯íütã„U¹¯½v±²ùPZe`2j&€÷Šµ§SfCL±5 z=ÝaZN)­ÐÎlo /]<ZÝà‰,5f–®·š
+\°êM·åìÓ5¼ ýá{ya¿ï8x¶ÕL\_¡(%¯K
+ßAŠ¾ƒªAcøo|´º WUëPÍP8Wr»W u ð	!죔ª_TúmR™žo‹’s1oš§N™¯d```xO¡” d™×ðž¬%P?ý¼—N ï/¦žZ ~”Ò½U©ÃÁdÔØCñ`š°ÝH)UUZÏó4Ȳ®:;00000T„ G“Q“ø¹”Lu
+@Ú
+@ôÓC¥¡/Ê⤆â¿Z’áCCcT±˜k£ê0•Ýj‰ 
+‡ÒO6à,íR[m‚RJ¿Zêÿhu@äõ’G7ýÞÊVÏC©†@§«ös²j¨iRäVRä™÷6zNuG§ÓU›çLid‰!ÆÀ´éÌ3¤ªÐU̯ƒRª °Ÿ €" ¥ÝCÃQŽ¸uÕmqVFj4ãá^
+¨N½ýçxº³{šBšVÕº|àPT£h”Ò /
+FÍP=áPJMÑÖ©JE*)ÞNDh†—SL)­v«øxÛr†Ø(3(/ÃÛ!.Ÿ†iô/#XB켕š^J¥4»"*¼ãò;€Ø©n7{‘Øù¥AXÞòœnNb`*€r… ª*|í¹Žß´åW‹µ˜"דôÒ5ªGU­Ç B3kŽÐÜ…yé©"ÉZ² ÂåÞ	£öÔ+3—Rš÷ji!±°¬©m5jMÅÏC¥°i¸uUëP8lPo[n•…RûЉÈ6Vëé
+Â恙5±¯ÙVñji†Ê$3ºˆ_¡]@! í8„9/YK)-WÐÊ·€̐"Ã[†Ãõ˜]¥¯?D²7Þz#€\€Û/øT›5a”ÒPJ)Š¡
+9ñ{û.²¬¨j9ÂG)ÕRJC9 Z½@&ÕÈ°10000T-~ÉMºÛ×ÂÞ§Úö^߉žÃûÄ¿q>qÁ{%§×vmûàÒïÏæ CÏ.²»wêgû{§Ö<½®[ Ð(óYgÿìÝ"%â” Šò8úšÊÄí”\ñçyu½å­ƒ_»™Ò•òtöÅ-ÃëÀÅ-#ë%„4;õGçö±A;%%e6h|ru‡Î1W¥õ¼¹oZ«Ûw)YÆăK¿[_Ù1Á»²ÎIeÁ¢”^1} $ãÉ"l*ÐXkàçÒؼÞ+RžYè?}KaNlçг‹ü-n8
+ bîîyuÝÖ¤ð£sU…™·Œ¬w௲ÌGݯ옰ïÐ↣$Ö5õ¹Iw'øÿæ3Y£ÌgÝ>4cƒ,+ÚK!OÄÜÙ±ÍÔÆ…ÍûdÆݘ ©Îm¹¹oÚ†¢¼„ö¿>ple«Þ °q`ïü´°~Jyzƒÿ=xf}Ö rÐlçlÿÄð£3TòŒú!ç,©ÿ¥­£ê†ž]¸Ã ÓT›¡HB!lÎÓ€ƒ  $¨	 ʱøÚ ¤¬ˆ^òÍ%mBXP¤®TåóÝY{êì“VZpdBH7 ñ”Ò·¶%xEˆÜ&¼úw;Jl[·¦%w¾.‹œÄ»<Û͵ÀÓ­7ì  bK—Ì®Ÿî­®.Îÿ‘/Oµ
+JÕyhôà™ñ‰r÷é‰ìÆWPÜø³Â(“L_?Y¿´"£µ€msgnÂ×mDá^ÖìêâÌÅPADæNG†Îß°Ô6ìüò] ö !lÙØ%™ŸÀÞÝ’ØxnôýÝ÷ÏüfqiÍ. û:ŽßþÃÅ­£Ž\X¯>›+HôýÝ“ ¸%é쟽ZöúâìÂœ˜ñ6nÍÖ™Ú“ÚÕö0óæù+;&x§<<ó€3O˝ôŸîžs5» #r€[¡çwçòÄá£$-(­wÄ•µŠrã?ónóég--¯NÁ$ Ƙbkõ°@ ¥t€ëx²ö+¡:Jø®¬ÓuöI[6²l+mÃY Š5Ì­ä^[ªé~a'VvìxëÀ·G5Š|O­Jîšvì»—É+åéì“«»Þ2gÆÞæ&‡l+ÎOn}eêöo,.îÿÿÃûß}µ{PªÎãô‹ƒaÓ­¶/ì&¾$âç"®¨tô¹Xw±Úzé…F¡é8En°ßI|aïHó£Ù
+£Ùœ€âv%åTF®Fÿ¤#LßKS¬¥ìÒiF
+¤Ê
+cµnöþ`éP7 õ˜“C©Á2)ü¨ ¸i°IF¯)jiW³U8 4éýS6¥Fi\ð^‰s*‘¹ãºhP½N_=Û1ÝÂÞ{g^Zظ»Çæ8
+:Ç^ŸŸ¾kÊs©Û3 ڍÞøب×Ô×ëTäԝ;ìœm»71ìè­² žA§¬ ªÂÌö"s§ ²ô–g=þͱîêjfЀ'ëbwšºŽ* b Ñ„	 ÜQÎYs–Ág·ô éØc•YPH«‚ôÜ#šö6CùG*CÓò­O«
+2M°pðY6hÎís¥ód™QœË[Ç÷ÔªtýÆ¿nÇi²€¿÷ 5Š÷Í÷ú’'4Oñí5ç"!ÐŒY’´ öΫ9+)ìø(6W°+#æZ} PÊÒZŒY’¼0üü*ëG×6ã‹­’zL;|^dîd>ñ³}JÄ™¦ ”¨yÞ^-Æìyºi(.ü3²nnbpwƒAg!µõ¼Ôæåëo÷ì0˜x”£·¶²Š,„, töàåšòv†ªÝ¶ÞS5Së)ÏJÀ*þs äâ¹ÇZ§Ì"£ÍŒÓE=…¢½ü©å! às`¨iÉVi$x8/ ¸ ÔX‘û¥-')_e”þÖÍìüÕ­óùXm= ðuà$m"½ 5Væ~YÛš“’«4JÍxDµ²·Ù….\Ùç‹}/Äjë
+8D«5Pέ©VûÞþúðeEÕyu½%!¬B÷†ƒAÇæ‚°XÏü8<³àœÄ ú ’Â/¬°!„(<›.
+:ú½³Ržö‰Hê°êÁÅU‹v›5 z}yîÊžyN?ÇÞÝý…H긧d{iQçë7éýÓ¥[¦{°8¼G®d<œìT»Ó¢®ŸøGYÚdHQ¾¢) $vÊÂÌÆ þõ\s­×{lê£sœ^×]Õgúù[¥ó«
+J)ð,
+òE  6á‰óȪ×5$)K•µ©Ò6Ü{•£jõ†Ç—„ɳO;²¤EŸ˜ÛÿŸLÕ(òYG—¶>¥×©Ìùb«¤ #óüCŠ-ë?ˆÖÂÁ'ÐʹAdéúz-›ÃÏËM¾ï^±Z%Ïldnï}ñæ¾éî÷O-8ÌY¤ªŠ²ëùÿÚ`/ ä&Ýs–e<Z¥*Êi 0³‰zxyý¾ë»¦ÔL¾,H}°ZbS3ÈÆ­É1€Vh!#Cåòe+ad±–
+kýžûù€²>§£5ö¦¼•×•·
+•ž¹5Åj_gNʺ[ªzSZã$¬ÜßûHΙ ÜNÑ9üuGåµìš²C7n4 j¨dTCÁƒ iV»9päÇ"5M/}b¹ïÖ«Ý¡™z÷qZ[ Ph©¨Ÿ/òþV;»zò¯¾©l
+ G#5MŽ³8tu²åAÆ ½=²Ô‘ûö˜yïÔ/[DæN~eÉغ7?$ÏŽ™¾ÿgï–n™;m/ÊKàDnYoåÜ觿ĮˆîàÂz €ÃR™¿F%éÛsîÁ’uɳ¢'íÿÙóÛÄ°#k$Ö5w —/	Ɉ¹6cÿÏž3)CM²ºÏ>§S¶ÞóƒË2ÿu>9´¨þ8Sž[ý¾)õ:}5.7ùÞÏ'WwèüfÎÎëcê©IØQJÓl'„t#„§–¯ÜœÓZäӬ滲þrú\˜\éÚVCÏ»»þ̺>sâGÞØóù²»Ç~Ø?fIò›F´d±¹éëQ Àá	Ãîü­Gïé'Çßó×õúòä} ˆ¿çoF)úÍ°>H©ÑŒÅæ¦ÕëüåáÄ°c>„Åν8a ìÿÉ{²Pb·wðÜ S NmÿÆâRøùUO¼¦QŒY’¸ öÿXÛ-=úr×ú½w%Zu¡Uƒnß^vkЗ™{©B\ÌÙêŸY¸Ÿ®7ߦ®5õXÑÈÕ}qÈNÌRç)–ö žrÙ„—UÏÝT½{šÔ(›Ò\x{D~
+ ðÙD;¶‘ 	 ö„©kzÛrR¥|¢€V®ÜØ#‘Ïnž¼6qbca Œm$ˆí·CÖ
+ÀÅ~>üN›&Ö·ç$Mi.éQ‹W¡X{¯‡{ƒse™<=šŒØÛ|àÒt ¨ÙxØI£^ólx¸ÛäCᲬ¨~×wOîаÛ÷›ë´Ÿ*{|{›Ô±V§Ÿ»M> Ænþþэ
+>¦2\¾$'Põj1þ9·û]fÌH?Ú¬Nû©;v›• CçG¬¾¸yXS­RfáÝ{þæäˆSî àÙlt‘g³Ñ6ôUÊÒÜ=›¹ ^¿ròîªôj1¾H$u•qÒóÍŸ©Ša2j=ð|Dê– ’ Ä”·"Ùe­4éWåVŽ9+°ÞóM•¨#!Ö TÕ(ÂÉ3øb+ã 9·Ï8¸M¸ÿë«×wMÙ­¥ùPj0“eFµ O”([•=/HˆºÕ°•;ÕØÔÔ@bØ1°9ü(“ˆNSì)6w¼a:f±¹©éQ—j€ÊbqRLé<¡yŠBžÞ¡†ï EÆƒ'¦=º0áÒ–±³DæŽ~#~}´
+UJ'Ž¼‰“YpŠÜ`q1NëöSñ}	Ÿ(.byUª/Í" #žKÞZx§¿ÿ¹ëˆË†ŽË~â­\Ëš-?öHól><³Ø(máÌM +.ß nâÄ‘Çæ̬D,9 ,ëivNу!êšSšfµÙFÌbb§¾af6ªßÝznx¯Y¿ÿzFXØûèûϸ~Ét\»Õ¤ÂÚ­&…›Ž]ë÷UºÖï{ .¨;IY˜1Þ§íäñ¥ëqðj_بǜ3%Ó8\!í9íÔ³¨Ú­&=(™ßcʱP ¡¥Ž uÚO•Õi?µÚŒÈB¸ j™†Ãñü"ìÚ RË[™ü†N’8_¹…-!¡
+Κ/ªD=M4ÆÏÌjǍ=_¸›¾Û¸5QÐq…R­G³§©Ñ(<7è¯Qc׏Z»¾íèõwEæN€èô:Õ³‡¨w›I…&ƒV+÷‹
+YzGàIïΠ×Öê0áŸP 0赍bïî• €BžÞÞÌÒõrQn§ÓGÛcÆ.Ký±qïyÔòŒ]äoŸ/*}w¦¸Ù‘HÓòkÊ:wSuÞã|Ñf,»;kìy×SÑ¿ûj÷¿ï¨¼ ÀËŠ±åžªþîPu¹‡úùð3rFËÎû.¿¦¬’®óšÐD lB?ž/n¿'LíºøŠ¢C'×3N7¿“ª·t°”B.ÑpÙ¤:ï®ð^`åÜp™³w·üÊ®—'4O÷i;y|i'+Çzó%Ö/~¾¼'p Ôà  ¥4‚2†ð4s¥ô…®Æ%Ѥ¸	³›PQ=ö¹ø™Å- @Ü€”àš    IDAT“bÿ‘ £24¥”^¨ŒzÞ‰¡G¾Š
+ÚÝ„Å榍z[Øú@«¡+Ò  >xÿþ}?Ö:Àb±ó½ƒ­{³Å}¾	¸-0³öß=ÛÅŸÃ?h=|Õªò´ÓrØŠk6Žèæ7Ãú (åKmj®|b ‡usÏ{oîùBÇæò›
+øíê-ÿõÒ£/¯bsøqF£ÁÂÌÊmÛ</§¯7/É/Dí³õžÊ×Í‚ÿç éÁ6nÜ| 8=Ñâø®PµûÖ{êFb.ÑŒo,x Ë{™îQ{^Iкõ$÷¯Ãñ²fÿkçƒAuùwLßY¸>ÙÒoÅ
+eýD™ÁâÂÇ–ÛÌX ౡßXzð¡¦î”æ ±¾‚d  ô¯ÛÊfvf¬Â?úIŽ›Èûþð«rú~}ùÚ›¨·tÏÏDÿ™7«í3´²xj³N“ŠL›B,=ÿ0sv˜$xæ#¿¡“$ÌUüUZVèÁö÷ö“”¹cuA€‘“0'_®Œ¡åî
+–_G‘sݶã,Þf”þôèË‚ÔGç-[Z\¦¿{l¾C­–ãr-|þóÃ"1ô¨Ø¥^O%‡+¤ pv}¿&Ù‰A_ŒY’ôiìí]RŸö“å&Ù¼Ô0n̝]v{ÍÍà‹­ÞÚÛwÀ¦áÖ©NgPJs_-]5BêŽm$ü|]³ÂªÖåmá¶<÷«äïmÖVµ&=ÔXþ|Qq-M®¯´5­•!ÄAdîhcãÚ„ÓåãýÌã[æüÆAZeafö[ßOͼ·È÷ºÅ=´åäÝYíäÝù…½R“‹}ePÃwP™Û`p¸BZÒ €µK#µK£ê¶–„¡ŠèP“÷àÕR%1è5œ[M –º×‰Ïðš¨sH$€×º^«Mˆ†×ã©å'U­Cõg×péåªÖᝃ	˶ØÍs™¤Ì…ìo‚¢pµ9ÏŽ£á;p^º­:E'4(Œ±ÿ6(l `‹X†WÉVùW•’´Vìë–'Œ!Ä@&³ýCU på¼5oÐüËz߁­}U›yç‹œTÉ:©uwqøËä^—ô2÷¬Cr°µ(yìü‘eâ›h§4l	ÛPÁÐà ž…{ìùN5<‰xÂìÀÀÀðÞCõ”PHþ…ì–Ò®(Lí ¬Á•Õ^ìp, ù¯|¯‚«
+w®5[Á³ã( ÷l‘}¦a-¡W^ã{›ÈÌýrW®[k7Hšý]fS÷o¬
+\¸/íù•&cŸ¬žï·s,>1Þ˜Ôçmµÿ€Àƒw¨QJ£«Z†·Aq„Ú†cÁÖŠŒÜ¼€âÚ¾‡ÝN=þ>óìÝw|Eû ðgvo¯÷Kï	Uº ¤ˆˆ"(M±ëëOA_±÷ö׆
+RTz¯Ò¤'„ôÞ¯×ÝÛÝùýc%\˜ïçãG27;ûÜ&wÏÎîìLŸšÎp‰–ö[ÿtÇuþ&zljé%Ã¥a¿Ff¹®ëϱ›K¾²$–|aIŒ¾Û˜wtbáXÛ>O1æ1U?¡›R<\ô‰LݲN_Fo“†ÿÓ;¢‚V×^v\¢D¨oª•Âó I âZ¤¿^YÀh¿¶§¢ÂqØ‚yL©
+i%èoPòQVù»=†·‹ŠS—
+À i¸Ä%ÑR|ø$]zÁš!N&Ÿ3éBØ­Ú,Ìý{ÂkZ[ï¾ýÏ5 at D!ÜšZ]$©×, UN|ZË“ùH/ Œ‘®Ÿ²²êw{ 于ûÂå	R›éFMyÍFWbçobv ¸Eš«æ¥Kí]"&ëþΞ_٣ˆM»ÆUøbýÕê
+‘†Jöý­¤x¦ç#[«6øöb[e¾t×â9†–ŽäZÅ:mç,mҝ¨ô›g¬ðËZ:Žk˜Íí#÷Êë“Ç2NÆHs”‰2/㠐†J¼ƒ„‘ê*óWìáq…cd‘‡<JâRÄ3^ÓuÞ±©ÅñˆQÈhM®¯Ó&<²/tœ¦"ãÒþîÓ¬ZÕAv61Åÿ_HÖÅâH~5|_þÛÕ=0 $½Þjfã?„ Ú+~øúr4öák„Ðx 8})÷ÖB:  _T-ύ1nð™ºÖàÌ<qç,_O\uBkœÓ5ððµ!"Uá3dNUwCä9µ«Äï%öuô.,ò7æák„ ¦KOm\úèG7ÔŽ–$ZÖU{®å2I¡v
+A¢eù  Õ%µ Š–
+¡ôM¿ÂÉ–ŽäÚ¡  Nó·Âc/kÔvc' ,
+Š¤Ö¸39E¤*,‚\zlI~?v[KJ àªMUvä¡ñ½"µ¡©äòWñzÊ™²ü=Õ `kéXÎcŒTúXò7r!ŠÂΚ|c“Z at P$µÆP( %t¸‘oßÿÞ ¹±ÙÖì_ú¸Þmmòi=›œL¡çÏü¼ÉgJ'.́eÏêÊò÷´êÁ"¼ß#Çܪà-˵¢ÄÔþ¸ÜíÛ\R @HCcRÉLã-ÉP㧠ˆVJ+ãÕ/Ð°E–äifÙUœü=~¹í
+n^Å“¡Ø3@‚ â!B¨oP$5 ˆ mKAA´Z ¤Aqùc¼·¥c ‚ Z/Œ± þ–žAA\T“ôÔÒoµßç¯Â£°€u´
+Q¤Ðë’?Ӑµ›â‘ùçWºèÔnMH;2@‹hQM’ÔU îN½À„RNÇn_çAþÃÊï|£ÂgÉÏ»tkò×ÒÇc«%Õ/—©LÖQýq´%bºÖm¡8¯ªûRpôÕ±ïôü>•>25sØ=?e6ž~žÿì´7_oŠ¶‚ÝÎÅ÷$ùýÃ^g¾oÕºˆ¼¿—©­zþöÛ_Îü&P¶ìåÎwyíc1tÑÎö½¦ü÷†iŸ^é¾üñÌ'‘›Þyÿ2ò˜òeòýqÒ¿¯Ð+ˆ@uŠUÞÛÏxÁÏñºSΨ±©š2  –ÇÔË«ú U´{lª:?-\·&Mrù1e‘fSü‹ªô¨‡EÖ.£d(Ó²Òm  „"„⚪½ú¬§"]–¢ë]–¢ëÍÅG?uTçvYŠ®wTç¤5×>¯Äš÷Gܲê½ÁÏ~ÞòÕ”´ßÎÜäqTtösîÐ’ŒMÏ4Õ¾X·erSµìLý$oÔ#«oõÈêÛhF~Z¡X6ê‘Õ·}lã$  ÞïEy/SÔžxýã¼3–T”Ö/«ÈÝ#+:±VY¿Ü\rŒ©_ `«È<ïIiö¾4ÖòSJ½rJ lÇw³’ÝÖ’Ù}n}óÁ™ï[oJê{çSÚÐöÿzžó|m:kò%¬ÛrÎ÷EC<_í³¤®Jwt›ªÍ¾µ‹ö”Ã'^ðØ
+à½Õ£?ûü"½#×ÕµWœ¢D%¥ü¯¬¸eK–+²ù#oBj„ÐŒ&(bYÏ\Gù0÷Q¾'æq¨a”tgSµ
+ y Ðlgcÿ³á    øîÿtc㻎û|à]_ä/{¹ó´ßߝT–µc¼!"u§D¦òU‰áí¯_è
+­Y8l€LipXÊÒû" |ÝØg—&÷›îäý^´fÁÐQ{Yo„h_»ž“~îwÛ»¥K_L­K>b.=>*4®çº‘¬8ˆeÛ¢i+ó÷‰½nk |݇£úÒŒ‚µWfu `Ýæ~¢àXò\Ò#!ñ=·Uæì¹Kiˆþâö—2Ÿiæ«@{¬ÛBmütü£2µCÿ™Ë®û\ ÀÒSg‡Æ÷Ú[‘³ûµ1nÿ˜Ç6ì’0
+ °ñº›KŽŽ
+ë¹®¹Žy0’0
+‘8€­ý	ñˆ¢„ˆÄìOOǾ‚EA%ø½¥JÃæ“Û>:f-Ïx!ʳë‡{!:uÄÃçürjå;†Û+³fa,ª0•ŒL½ÿηŠ_ øa^øg‹j LIú}w¼–óñ⹡‹)Zbül `Sl÷·Ç=±mOIÆ&ÅÎïï~†÷{S taÉ_MxzßƵŒ¼Þ\tä1˜A€8ZªÌÄ"¿xnØ72¥~ŸLe,¤(IUDò@7 @ÿ)ÞÛ¦Ï'v­ÌÙó =¢h[rß»Þè7yAÉó¿D”Ä*ø½©c¹)¶Ûk7Ïݱ«"wlë—S^ä9OW ð`’ܮоBo»±©šôáɪ
+ €Á‰ª³sî/ò=bël÷
+Ê›;iÓ'tÑ¿»­º‡Ïe3)¹)ÞÀÔÌr˜BOì¢- °{ù†Lg’FN³N9Ýœ(Ë5ûÃWÌŠ[±äˆ­ÝÆLWªIE;ïêi8Ù=Zn=Zê3¬8nOqs¢¬Âá׏NÕ¦Oï©ÏEàó½–ÔÝùî$–ÇLßxeî¼!!ÇZê8]€ Ö6Ù@‘Êo}cÍ+Ù½9Âó²8ú›Ð)²Š¦jc\zf^¯«Êm-¹¯ðøšgTº¨£†èÎå.KQŒ64qÆ”p øäºÛ¿™ `¯ÊQš¹mDª°ˆ"¯ükÙÜ Ö½?r¨³&ÿ–¸ž«Ô¦øý¬Û" pY‹Ÿ©*80Gmˆ=P–µãù¯vŸ °ìåÎw–œÚôœÊs´<{×Ü_ŸO¹ À^™5¨<kLJˆ¢üÆè·$2U%‘–é#:î
+ëY%SylåÓW¼ÖãÖ㛘꾇%Ï'/ó¹jÚ)õ‘éÇ6/ønÿoÿ:óÞž,ÍÜò€J}ÈRvòѵ‡ Xþj·É•¹»ç©
+±*rv? 
+öˆ:0–`QÐÜùNÙ¸©¯ç}0töâ?g.4ß6cAõtSL·ÿUdÿyç™z”À³i£^5uÖûÖÑ~Ÿ«ßÑ
+o†îønV2Æ¢zÆ‚êé3ÔÜyÇk9Ÿ©Ï Š±Í|ßrsb祐š‹< ppåsÃ0`fæBó¤ëÆ<s¿­âÔóµõE$ð¾ëLýdÖŒ…5S;Þ0ç3DI
+g,¨º{Ê«Y_™õÝVDÑößßìsð‡'#>^÷Ñè>·P‘½ë¿í®›øÎŒ…5Ó´aI+ò/ŸQf(ZbŸù¾e|TÇ¡ó¬eéw ì_þä@˜žù¾e\§a> ð\—«zÌÛ )êÌEû-ƒŸXY>hÕIGL Ü͉ô++GÏêc8þÚM;~:lëgæTO=,gûýÔ˜µ¯Œß_·­|§<Væí©(·zxùúLgïíÕ?ßûû®\wØŠãŽë^¾}X²:÷Ùuc  ¬Aº)ËÙë†öª‚wnŽÜ¼6ÃÑuK¶+²ÊÅË6œrtùzJÌÚe3ã~›ØE›sµÍ¥À‹cs“%µÔ¥ÚŸ®Ûg3W1„-ffÏqÞÖTm·¤Øî_Žj÷¶¾ß.óèºÍR…ÎåqT´§hiaeîžÑzr•qímÏùmÒ‹'>x_½Œæý^5Æ‚‹<5æ?ëÿ<ãë\  ÀXšÔ{êÛãŸüs{Dbÿ7ݶ²›  ¼öŠq±Æ¼:~Þ®É}ïzÞçª9{Ÿ†‘©wM~ñäÏ#î[š.Uè(ZZ5ú‘5‡»zªfÒÇ5Åv{Õc+õ÷ê—¶ÿøTÔÞïE»~¸·=`,ц%‘ʵ©\»»àÈï6©Žï{küS»·iC¿uYŠ† xleãbÒF½6þÉ?·Ç¤Ýø Å22-M¡
+ßèé¦oÿ$âǧ¢,žò“¹ä؃~ÖÕ?P‘ªvz{©<£èĺ.}n}#b¿Ü°vÉóÉeìüL¨¯KÚ
+ pôO1Æê㛘ÜÖâácüV €®#çš%©Ø¶hZG  šQìOê=µÁ@}DG~ú{•t9o”\òWeî_ýñfß1;?Ó~¶GÞá/,žö½2k&çu©³ÝV €Áӝx¶+ €ËR4LmˆÝ Ðëæ—+)‰4½Iè5hF/}î·SbÔJß´õ»õ›ÂÛ1øí¸#AÁPìêtgâ7û­däÿí„ãœ1   ~Q”ܼ¨àŽçÖUŽè«(¸½».  F'­¼¹“¦D&Aâæ,W»!‰ªÓqÆ;6US¦`(öH©Ï  ª’X&vÑÅèï$õéÙî£RÂ
+¨ùk+nؐéŒjo’¶ÚÕ7 šaF‘°iòJ‰žÚÁUˆšºí–pÝ­goÔ.{¹ó;Õ…o‘*t4#/æ9otà5F¡+¨½D… ù-¥'¥ãŸÚ½ZšôCeþþ‡|2r󖯦ÔÞ£CÈŸÒV @xbÿQà  Áß®]ÛJ  RÝ_.Š|T }©RÁewnž»c×ô÷*~ï’~<çé¾ñÓñýÌ%Ç:bÀŒ­"³¿­"³?E3¹:$p–åëuóË•  R¹Æ*Š¼ @ü		Ý'”  œ‰…Lyu	hF~öÞTî¡_Rã6ÍXPsgXBŸÿui!öŸ­ƒR%Ìx¯jNڐ‡ïÁ¯ü{õ‹ïj°nKÄ™ÿScY\—›ì4£(æ¼öˆ@,òaÉ+  EŸMhF.BŸñžã^¨šüâÉŸÚ°Ån[逄î·8EU¸ïׇf,¨º{Æ‚ê³>°Þxö½Id,  -U`¨}Àh©¢„ó9Âÿ‰Aˆ¨¿¢ñâŒ÷É¡¡G›·œ0³3×Î
+¢D¯ \×Ç+K¯W–ÞÝÇxp|'mnCÛ3ůž“°ä§»bWÍzLÁ  @¯ Îþ}
+"Ð4…ÎNùE!ýBí‚­‚³å
+D^Ä”„ømvü¯=c¥¿±whyéˆæ;WîŠï©q¢¤â_RÜ3ÊL €ò/¼±¼E-¢~¼òðj!„Ô ÀaŒ¹¦jóRQ”äì—ºŸu
+÷øÖ¡	½¹žŒ}Á3—¹žðô¾ °qé‹i3«Ž€À˜ùkéã}Ç=±mwî¡e70rÍN  ©\½ýÈú7'tŸ°n×÷’H•{ê4w6©BWãuTh?ïYòh|ßÛÞ)’0
+×å& ™ÚÓíÆ'nùròü‘¬øÂÓÍpáÁ  Œ\³ãøæÚ÷œ¼ñèÆ·À™/1âÒ!Šòxìå=×}4Új.:<çbõ·.ššê¨Êi¯L˦EµÀ³goÅw¬Y8¬ÂQ;H"Uî×GtäÃÛõ[_trݧ«ÞXⶕ^GQLIÚàmù‡—ÿ«Ýn£žª9²þ
+揷úÖGt̵•ŸJòy,íôa)û}ns¨ÏY=9¬]ߧ•º(AªÐmÚöõ¯‡Æ÷úA8)ë2‡ÞúÌÁµç‹92ià¦ü#¿ÿoõ{ƒ]Öâž‹dŸ+´ø-q`{ey;£Ô³¿Èkôñ¢´[”ÜÒ#Fn^~ÌÑ['§Øž±
+k™ƒ—s‚HÑ@.¡¸›_£g.y¹­)ê¼/ÿ2÷»¥‹6ÿT«wr¢²OœÂ²=Û^éâC6g¹"»G),;rÜ)Ó{é•9x¹Ï/ÒwöÔçöŠUT=½¦örekƒ’ @Ì'5Þ&JÌ+ÙÏÍ° ðcB%F´2ùsÍ¢&ˆ3`0 dÀEWkmNruÈ’uŽZ @ÑLñžî×<ö?œ×~EIjD‘7$÷½k.  B”ÓRvrö÷O˜C€øö='Ï ˆNùMщµÏÿ„iÄGuÖàPúžã^8¸åËÉ|ÿ„i¹>¼Ãçn[Y¯ì}‹o¢hi(ò!ŒLuðÆ?  1µûpÍÂa?Qm>D–´èÖùÎûe×yìwy‡W¼õý¦9%1 {¾º×2)~³BQUûï„-Ú°¤âÀkÝGÏÿäÄ–…S­eéc#’d-;Ñ ÀÕé_g×jSüFCT§|©RÏVåíK+=µy˜Li8Òëæ—_	ÔчwøÂ^•3\®2¤ùÏú· †Íù9󯥏Ï*8úû4™ÒxzÌ£ë> 0Fw-æ|Î
+îIè>áÞʼ}ƒ­åtlç1‡r.‰©)>rÍÈË"ÌýèÚ¿ ¦½YôÚ†OÆõ¨)>r+Bˆ7Fw]  6ÆþaŒéZP{B©ø `ðÌorh‰ì¾ÂkfÉաǤ
+ÝÓ!±Ý.i1G¢af7¯œ·ªbÇ‹L„–±<Øß´Ý ¤ý  ó‡‡núþµûë[ªB”RÊ÷ø Ý	ðÌè¥ßûÒÆÊÁ%íziTø_	FæœõZt
+šÕ3gW£š¤ª(²résW–ÝhTJ\/
+_x-É$+^yÒ‘úù^‹áÆꌑ4e>Ý뛫†rfŒJÚùèÀ]Wçˆ4š z5ÙÊ×æU¬É_åúáLµ<¾`ª±+_7†R©ŒKì}¿ªÏä×íMÝ6@íPi}DG64¡÷%õ³÷ý qÛJäÝGϯ”}ûÍÑÙ9»§oÿÄÐiè#ç¬9–sðÍùî‹œOuÁAiÞáå!=o~©<po§®C«_ï2Îz©qgìüLŸ6øÁËZçjí§cL•™»J0Æ­v=5„)¦ãˆ¨^inéXÎgñ!¿Ä¤Ýøò°9?7É3‡­ÍeÏêNüÂ…=žâ‹×¾º+_kC“tµö;ß¼QƒÛú,ýÛ³Ýáß²öú~jÌyOz›Û™Yú­e¬q‰µü$ט•¯šlH¿i¼¬Õ~94¥ä~Ó•lÎÔop›† @c @hBo.4¡÷yWÕÜ?»T—›Ðˆ¦#W‡lц'·Ú¢mQJoRÒW}”ySŠ	Ûšž7¿4¼¥c Z¿Û_Éüº¥c ®}ã•æ¾ñÊÖziñ’‘	[@בs¯‰^-AÄÕI
+!”Š
+mé8‚ ˆÖ	!¤@
+Š¤µ³ZK¬AÄÕ' @YPÜSÃoé‚ ˆÖëÌsÌ'Ô°#ÑŒ¯è\ì¹²í/Æë1Ó%ÇÖÊšsÄùaVŠ^5ë³Ó»Ï1´t×*¯­†óŒ&ˆËÕè¤V½œçª—».^ñÂü^WÚHC¼^À¹ÛQEîvus´O\œßïo–ßmóU¬¨.8ØÒq\ë|-À¥È®áä2	E¦ŒkfNáŠW{hlR³9±MõPs3ýxKÜÖ’&¨›h[0Æn hÕ³-•yÙ'ûE4Ïy8QÕ/»¬ƒB À4*©áÚéG®úÙ
+BèF ÈÅ78‰g]¸1S¤A\ #×xú޽×$šÒæ/&\ÎÙj ˜Ö¨i²Z
+BÈ  ^ŒqP\ª "¸¦É’)±J]$™Ôû*ÂPe«<åkÌ4Y—ÕSk)­yA‚ Ú.ž·EKÇÕŒÇIÉÄÞWƒ ¨úw¿)ïø}c7=s•ŽŠ¤FÑR”)R.tœªY&H?ŸÓK†tù!fGSÕ»öƒ^}ѧ殘ÇTø­ºìðÛ´¥Í±ŸºDÀü»õŠFOÅÐk‚ ˆkIìÃÆc  Þ<NÉ;D‰ë„OS÷uo>§`Ëx[î×ÊDSžlNø·7ŸS  `£@yc`?¦ž9šòFÄþÂjú±|P<&=5„P ¸ÏŒX#‚hÓrž«ÔkK»•'f—Œ–G3VJAùiâS?‰Ú—÷zu'×)_(B8³  (_b­^íH’†J\¢KÒþõשGˇ¶.ô¯òŸíÉŠ8Æ‘0/äìF¶½£u·;¼î>Õ©rkèÍšŠÀÏúþʳk°Ñ*Šõ[F!iµ—aBR èI
+ :@ ä·pAW ¨ãû‘{¤áîЈüñ  –í®Ä^[Ú­`o÷œé  å?Úº˜nTçÐrÄ—ýdëÎUóÒÔO£¶¿³ø&ycIý(ò@Ýf%Ê/‹`<uËcÃë`æ¾ZÕYÕQV©N“]ñÊÍŒ€¨ Hjãí-AÄÕFÉ/
+—’
+ Àâ™ÛF bjžYQ"5Ò>$CBÜ#¦ý”‰~Ë™™»é8ì3VþfO­[¦ë«,Öø§w Pð^MGo_ßùëèÝMüÖšÆØ ƒ"©Aµ4Ý奙•÷Á@ä°  |¢.½z½3Ñ4\ï>ÍÃnÖ–Ÿz¬|hÚ§Q›JYR?4§Ä?fÊ
+´5S_5S_x¡ý”ÿb‹-ýÞÚ'b²îpî+U#¦è
+TZ}o
+‚â95‚ ˆ«)ðœ-¥ú…?,ŽPu`¼Wsÿ®“>ƒº³ÜøÝ2  ÇoÅ   Pæ·2Û~O„<–qÊcWÍ+TÉ2;¹Ž{šîŠF­ãè+õ+}…~màgUšÌÂè¾DÙdD€ò/X7]žú½2³QÏ©¤FQO ©Iªò(…±¥ã¹–P	G	úôÆ>|—B= c\ÞÒ±qíЇtÈvׯµtך˙&!¤€1A‘Ô À ­v()Am“³&?åø׃o§i,ß•AÏé£<~–Ú –‹Vþ7 Å/
+cœÓÒ1qíÁ€©ëÂù˜qää¤ú*ðð"úêoVmf卞ocÌ@AP$5‚ ˆ–"¥‘&%“©_NV¤ Ø+š@šL“EA´AÑSCQP;	3ªIAœãLž0KOm ¤´tAD«¥€ñAÑS€@ÖR'‚ Îcì€oƒ"©aŒÉÈ#‚ ⢂"©A´u2Q»r=	NVÇˆ“IÐyÇl:튜¨ªÔysku§O”«d;4¿o¹U    IDATIUØ?AYsõ¢o=‚åžAD›µ-Ûñénó ë”EÓzê p‚H_h›vÕµy…³wnÏquI02–h­ÄñÞöš!ÿiîÔÜq·FAÑSC% €
+clkáP‚ šÜ¶lWBŸ8EÎ͝4%  ×Ç+ÏN>œUÍ©üÛÚ)ßÌ…IReÍêcÌúñ-Éá5sW•ÔÈ(ïg“¢·  j¯*í.sj4ûë[»zê³^ÜXyC´Ž±í/ô&¾ySøÆb›_½ü¸½3À“ºéOOVUxý˜š·ª|h´ž±-ñÆ÷o§Ì¾ÿzS†‚Aâ'±+O:º¸8Qo`ªßùgK§AÉ  g°ôÔ" @ÝÒAA4‡1©êœí¹î../±ø-Ñ/à³ ÿwuùØÁ‰êÂÿMŠÚðw±7nõIGìÌÞú­œr.¹9Ðª]‚l{Ž+1%TVÎ	˜Þ_äIS0÷ËôØßJš[°³fØý×›ÍéküûmÕ7Ú½Ë"u°Ø“ÊP ~19zMv5þÕ>K* À×û-Þ±mÙ̸ßìo:|µMcERÃï×´tAÍa@;UÍï³âì©(ÛtÚ™6ö«üe^~¤ÔgðòX¶¯ÐýÑŸ–n!¼5Û•|¾vžXU>þ¡¥7…ªhçýÇ d4Å=4À”.“ qý)WlZ¸¬èºh¹µg¬ÂÚ1\V´*Ý  ¡ÿÐ Ó	ƒ’öOî¦;y°ÈÓ À¤’8^ØP9pÉ[»x£Ô}uŽHãaŒYŒñÞ ¸üHÑÖé´ÿ¡ÆŒ‡3æüZ2ꏎö×ÅÈ+å4°×Ç+KÏT+5(éóŽ_8>rUÇp™3ðs¥“—«e”[r¦û‹"E!8;ø„F ò"¦  PµƒND×vz¾›³nMº3zs¶+yÉ{ï?îŽ_Úäo¾	EO ¢-ûý„#îh©Ï  [éJ|HÏXEÅõñJ³€|¼H
+MRUôŠ•×Hi ÂÔÛÑ2o£ÖzßIWx²‚?UéÓž(÷éÒ+Ùø[:k ü–,ÚgIus"½â¸#µW¬"Ÿå1ú»Øk×ISúÆØð?}<–º¹`ii¤§FÑÂ|¼H¿½­j“•&¥ÄqsšæHß8… àõ±~9lï´hŸµ?C?­‡þïNrûÌ^†¿—³uùå°½ûwScÖŤåJ)Å×mWJ#!ÁÀœ]d3TM³÷7íxg[Í
+€ ÿçÓ6£’本 1($Ž*¯ºëÇâÛúÄ+sî»Þ˜Á‹˜úàÏšNŸ¨ÔÈ)ÏŒ^ú½*)Õª'Š•¯B c\ÔÒ±ÑöV¾–*ô§v‘z¸¿ÆÕÒ15''+H&}W<mãý	‹[6‘š¿É‰ÒÍò_ÝÖ"scV¾F©`r°ôÔò ÀÑÒAA´EBؤ¤‚ý‘) ¬
+Š¤†1.½x-‚ âr¨¤”ðóô¸U-Ç•À‹ `&E‚ ˆ6ƒ$5‚ ¢ÍŠËgn rc®¥c!‚ Z„ b‚¥§6 Z:‚ ¢Õ’@¯ è©aŒ×¶tA\»„ÖÿäS›À‹ÿÌyÙXc7 ,Š¤FÑRÒ«±ûÉõviKÇq­p°û•lO’AÄy0r]qoZüÅëMÐÛeŸ I ¢Ïb?ëpûY2ïCKü>ñr¶–i²R c\ÝÒ±Ñö!„B@ÛÒq`Ç×\JE„ KOòLAWÉ™hr\ (ŠžAA\
+Òû!‚ Ú’Ô‚ ˆ6#Xî©AÄy!„ 0AÑSC݈Jlé8‚ ˆVK
+ ³ƒb BÈ  ^Œ±¯¥c!‚ ZŸ@O-(’AA\Š ¸üHA—‚$5‚ ¢ÍŠ¤†R#„f4PÞ
+!4 ò‰¡ðzeQ¡[¨;!Ô¹^š’×+OA
+o 1¡„ze:„дêö@õm |2B(¤bNE
+i q¡Øze„Ð
+ÔíêÝ@ùgîwÖ-‹Ek î3ӝÕ-“ž‰YZ¯¼)bî‹êÑ@ù4„®^YBhLu‡#„Rê•ÉÏÄL×+ïŒØ@· „¢ê•… „&_Ř›âóŽšØ@Ý¡n
+”Ï8³¸oݲD„Ѝ
+Ô=g ùÌ_QÌ×êg¾7Bh`Œ[ý @@xå* Ð6P ÒzeR 05PW ªze  á @Õ+W €¾6  o æ°êª@sž˜™fˆY	 ºÚ0€¬^™ B¨«9OÌ¡  ©W& ãybVÖ+CgbFͳºò0  ë•ÉÀÐ@]= (ê•Qgbnèo±¡˜M
+ü-2 rcnªÏOC1këÿ-ž)oDÌçûüÏüåÅ|-æÃÉ@‚ ¢ÍŠËAq)HR#‚ Ú’Ô‚ ˆ6ƒ$5‚ ¢Í I ‚h3HR#‚ Ú’Ô‚ ˆ6ƒ¬§FÄ5!„Z:¢ùMRCÉ@Ñ)°ŽüA¶E¾S6Œ-ö¦h
+!¤ ˆQ4E[Dkã  ‡cÌ]ÎÖ!DËSi&>h¾ûˆK'úó=Áô‹¥ÔºÑjYÈ,2J#ڏÐVëËÞ¦k1F¡Šy0F*‹›®M¢5à\G»òý| ¸¬¤ @3ñ]û¥ä{¤y+rÞ%	¦¤€Qñ䋪A²ü&¿·+“w(å|S·K´,䯢/^‹¸–‘"AD›A’ADàëµ>ËbÆÜU[À{Ë=U£°èjõ9#¸.?!G᝽y÷±X°õ„XD©3UQo¾-ÓO±:‹ætÃØ+ÕÆÿt°9ömÏ7L`³`Á•HË’Wê“wþÞû!š†·úýHÖº|ÈWt$·Ð²vGuí×l ðT¾+Qt³KµcM½_¿{Ò]þâPÑ_ԐÔŨlQÇ||!)¹ïÔJØónâw¼c_< Å9KžP0ʾÏë“Önv•>ÄÚWO6¥¥¿Ùû6gtš/ú+&¢îŠ7¤mÜnL=ü¢Ô­òVP«ÏºÁŒsnUsöµŸS’lEØ÷ɍ³æ!Ú”)ú«e  ¼çÀ@Þó÷ÈæÚ¿ÀåwGHf•X°F7×~ˆ+ç©|=Î]þÒQ0·§¤ñû%³óÞ£gBôVò²·úÃþͱowÙü1{j"¢õE1Ö¶üC[Vßûšc_DãaÑEù]{Ÿ¡eÉËCº”ÝÚµj¨:òå	Œªw6 €è/3`ÁÒ¯¹ö¯¹ç{S§Œ>¡]«†j¢ß½Elìy“ÏYìµµ =µfä©xùFDI‹õ)ý(Sä  ¸Jç%‹|Õ@ Qj9ÕñD©*
+þþ Àž{ãÍ€D‰²÷*mÂ’}  Ž‚i}D¾<€æE6gЪRuÔ»‹Îwön옾 ÀœžÐìo–¸">ËÓ(‰i15³îÙö"  wÙSI ~£Àw±çÝÄÓ²”buôû§ \%¦ñžCÝ­3«c>ÚAËR8  gñ}]ii¢E`³M‚/=M¢ìuLóqFCûÖ¶[ö%	_øÙž7.ÇïÞû’ÈW.¢$áB3¾mâx«ÿ…1«™½3Ð{V„>\ àwïUrŽ¯cì¯9ù €®Ý¯wJ”=¼Öì3D¶`AKѺýêèw^—é'Ú\eÏ·÷Y¾Žfâ6löL  ZÑùsCòÖ?Ú¿2쉲À¿å¦Ù5®ò—3EERó¿óËCzj͈Ñÿ‹¾ëéëî÷T¼W÷5‰¢»QŠB@ò2‰<íO‰¢ëa  Kfçÿã½Gqû(&ò(çÜü¦#â@  ÍêÄ{=%°YchE§õ˜·uvÍþöj__'š¢”,ºRëÿ  lvÆ‚‹®-è&°Ù1  –ÌNOø¬?*
+ÖxÞ{|š-û†%‚/C À96Üë­~ÿ=αúE‘¯NõYÿlË8©¡}Ÿ›¸h°(C´¡U^^ºÖ(ß*A”â„«ä©ï-™½ç¸JŸJ¼Æ¨ú{ÍЗ’ê“·NÑ'oÂ¨¹­Ù#ï¹Â	2ý­óµq_Œ XgÉÜW °`“cÁÙWä+®SG¿u—DÙý#ÞsôEgñCÏƒ«ìÙDëéwšÓ“ß,(!s–_÷~9HRkFªˆõ GEåõžªw7šO„­´å™€E%7ÞeF”¦QÊRm»ßþÔÄ}{ÄïÚ©¹â{d†ióõI;þÐ'ï^JK~ô{Üy¶Q,ÊŒ=¦k¿v‹¶ÝÒG°èëà,šÝ«ß&Ñ”aO.¤(ôT½·Î|"tõt{9Ç:- €¶Ýï»’Jä©«©étí×lu•ÎM¹’™êè…“Œ©™o™:—Í 8gÑ=ÿi3ÆNÅ·Ór^`T}çó¾“óD¾ò‚Câyï19ïÞ;–µÿ’ÜSk=ôIfÐòŽßŠþòÁÞšE¿×œˆûÆUö|{  „¤~@€%ò4V"Oc D6ÿZš°‚–%Z6OŨú¬Â‚}hß?-7ÎøTnš]£OÚ¸Ñêœs×MçÛ¿è¯ÐŠ‚9®N€h/Æ|«=‘&I­™éÚ¯Ùjê\6K÷íõ”¬ÝrÞsä%gáŒ
+Õe­¿& `Šµüô¾ùDèzó‰ÐõWp'`X ¢UGm  Õ ¢é"W•ÞÑLd†©S§ÂÇTQï£å¿ýe#…w®Ø,iCõyϾî€h—§âå'-íß²d´° óÙËBˆÙ{örUÈ£{ ZŸù›¨óÅ °YR{ÞØO€Ræè“w}Óôï’¸\EWŸ!eÇŠ.%Ó51† `ÄZ—œ÷¾'Æ\”ÀõTü’§úã—8ן÷"Zóï9¬ª­|ªÈ
+õ)ZŸØz¾ö´ñ_1¥e¾Òµ|<B´Û[ý¿šðí5)rOí*‘éo³Éô·ý`NïÅ{€?ÀgÏx(Y¢ 2òµ™Šû«lHäþõ¥„1(u“L/E´<EÈýUŠû—lÖ*kVß?]%Õ%nÜxnMh;£öKÝRZ–hùç'ñìçcŽªÝHÒà%EËgl9Ã> 8CÊžy­udQ{_Ë[³h3Ïfß  ”ŒŒÿÕGHZLIc7;ìû¾þö¬} `¹«ìùöê¨Wó  DÁÚQÚÓ—²DióD¾jЕ¿“æAzjÍÈY4û:WÉÃiŸ½5_„aÑÑQªr  Js‹®ög?”asË%?å­^xïù[  ò•´§òõ³÷Y0fÛ;gô °çXTËw¾ºïŒhjžÊ×ãêÞõ»vê ‹rÀ"
+ €(y¹(ØM×ÕÀ¿1fã)I¨K·èXà?E裥:X0÷ümyk>HbV˜æTÔß·è/‘ز   OÞõÅĐ™XZWÙü$sF§ÿ:‹èê³.3Øó§ôØÜ»(Z{  @öx&Æþp{þý]eÏ·Ç¢‹¢å)?lÞ[ÎØQœs›Ú]ñZœ5{ø-ÿ´ŠÖòó#žª…QÖìa°àê%ӍYÙÐþ-§ûÍt•>™â©ZeË9Nð—L£˜È­WçÝ7é©5#‘¯2ùÝ=ç³þ,E@;0æb)‰i½&þ‡E  Ê°§þrÎoNÛ†¼ÀÔ¹l–"ä‘'¼5ÿ{Ë–3|/¢dùûCiiâ7Êðg¿ @´f7çÜô”ùD¨c.R¢ìý¬Üx—¹¡ý[2’_ùÊ;  Á5ǵÐòŽoRœsöF´,oÍWÿç©z¿3Ek`Jì×#J}Xûé  ZÞy³ß½ûsz\?Zš°CŸ¼kçÜø¡·æ³_}ÖŸw#JQ…[ZÞùG}Ò–µµ­J\–ôö Z}JäÍ£%ÊÞÏ.]×eÏŸ4¶áˆR³e
+8{ÙQ½à1™aª¥~}âê’(ºYXÛJ	k_õ¢Ïö›!ÚJ1a[4q‹> ÈÓXF=àiÞó÷x¿kw´L7æ~CÊ®¥Öìaï=>ÞÇbª)&úŸ?¢-”,a§§ò½ €bT×?¥Ž~7«¡ýcÁç3ÿxAƒ¤š–%}aHÞüãÕy÷‡0Ž{Á!…:ò¹yèSAwY„µ­Ð\žJ¦½©†>s#÷b8çVµà;®‘é'WÎœ­§{ÍÆ‚¹“1-žÏò£‰QpÐÒvþ捾ù‰žKÅãÕØ™Óð%×FB(ÖhLú 2˜æ~ĘCî’ÿKãÙ¬ ‘¦¥í
+5q_«[G`³¤žÊ·S)iœMñb!@íCÙ~×ö΋”DÑ=Ký^6 €9=îcš‰þ‹QÙï÷He”}N©¢ÞÌmhßÞêO"üî½çŒºTE¾t4ðˆ@ká³}I»ŠæaŒ]—³=BI5#;\Ë;‹MóY—|Úµz`KÇÒ”ÎLhÌ‘žÚU Óßf [c¶‘j†»@3ü¼ÜóõÎˆà„«cÿ— éç«CËR¸ú‰N>¿ÂçŸo›3‰¬Ád }¤BúÈ9—%	"‘¤D$Š®GDyIKÇA´~­ËFSeKÇA´>rãÔ,zmé8šIjAD÷ÍÑ–Ž†Ž'>jéˆÖ‰Qõ÷0ªþmö»„Œ~$‚ Ú’Ô‚ ˆ6#¨.?r¬•’z6‘DÜÆ°¾¢&ÿr¬
+Éä…äo¥­á<W<=í¢»ò úî#.( Æ>LCú ­@ÛÒ¡͢ć1ö4EK!
+Èû›¢-¢µñøŽTaŒ½—³5B @Ñ´1­ˆ4I ‚ .†\ž!‚ Ú’Ô‚ ˆ6ƒ$5‚ ¢Í #€ˆ6§vP\p1L"haŒñ%ÍŸÚ„
+ Ê&Œ‡h]|A“ÔB
+FÕ+QªV»â*qy0oÇ~ïÑ"Œ±¯)Ú£¥qzF7*”¢´dT›"‚ß¹Ý 9WÐ-3Lˆa4ÃÉUª6FðoÍWA“Ô  ÍHZ|³ôæ.{ò{›pÖJŽdÚñHª¾áœeVˆ &rÈîÞÅɈ¢ 0Ü4+8—ÆÃF{jADB’AÑf¤FA´$©A4¿û@£¦ßâ}2Q°6z”®Àå3"_I‹‚•æ}²Ænl{œHR#‚höüÛ\>s©õùw<ì.9¥ñû™6ÕYôpwé;;ò§ÝÛØ탍#ÚýîÒgÒ.µ>IjAgðžÃrGáÝ=l9£Ç8
+gõ”Ûs'±žp§»üÅvgëzËm9£ÆZ³‡Mùʳ=	Ëgl¹ãFbÌ!Ÿu‰Ñš=|‚ϲØxÝYühš5{øŒÅs ÆrÎêi=ÝÿNoõçá¬}Öš5x’-{ä8αYs¾¸…sº[O_?Ýž?¥Ýr¿û€Âš=l‚5kè­>ë2 €»â8gÉã­Yƒn÷Y—9Çf5{ÄxOÕ¨úíÚó§ôw?šfË5 ÀU2·ƒ-gÌè@ò¶çOéh‹µ­Ô9
+fô¶åŒ8¼/CfË5ÖUúd
+ €«ô©doõçáãç(˜Ù €µý¦·f¿Å[óuèÙãTòxGkö°	 b£F铤Fq†ßý—žµ¯þŒå=‡Y³N	¼Æ¨úòš?î©|/Z¬´-ç¦/­³S’ˆ
+Ñ_É  ø;tÖ¬áïÑLL¥§âõwÙ³Ïвöù®²^aík´¶Ü[†rÎÍ“(‰©Z䫇×ß¿%£ËK›—(Qö>"ò
+Á—¡¥eÉ9Qé(ºïõ†böT¾ãwí˜ÆhFìA”æ_+]¾tÍD—Ò²ö®Òyo pÎ-=Xë²çii|¾è¯”9Šî}›–&y«ÿ÷¸»ü•øמGü®?GH”}2-§ûÍäÜ{ú!Ú`³e|½öõ½÷ùÛG JcsÝÿ“Àå%Š¼9Êž;ñ  [ÎèO¥v±ö5·[³GŒÇ‚Sî©þd €³ä‰®0Þ]ñV¬«äÉhYûwÅk/ú¬Ëö¼I9ûºi”$´JôWÞؘß!IjAu JuBŸ¸r›6þ»Ï®x( €(XÂXǺÛ0ÍÚW
+p=Ô‡bÂöèÚ-Ý£k÷ó>‰¢« ÀUöì—Š»hâ>?ÎÚVÝ„1fü®=7ˆ2OÕûÃߩነ¿Òµ[º‡¢uëîWô—H0öFRv-ÕÄ~˜¡Š|©€b¢½¼çà`¿çÐh½‰
+Ý·“(º80挜}åZ–d®û-KôòÞ“}ýî½ã sažÊwb  hiüZmÂYÛŠ Xâw gí«ë'QÛîç/ÔQ¯æ‰\ñX,8¢yïÑaXpvaík´ HÔ¶ûù+}ÒÚM€h·!e÷UÄùÊnžÊwb’—ëگإŠ|åSÍ©‰ûììi¢`¥6g”:úõ¬mÙXbà8I½ÕŸç½'‡ËM3éÚýºÑúýùýÕÃ×AÍs!  œ{!©Ù]þR‚ÈWw0¥zÕ’ÙçŒ9…DžZÆ{œÓƒ åißùÌ?Ü£}øDëË$ÒèÓúÄ5›¯[NuØÓ& (ǘ3ÕÝ–bbx  0æBR à©|÷NFuývMÜçÇkŽG®ý%ç‘jÇ8B:Íq?–æ­þø=UÄÓg{—®Òù·PÒ¸}âÊm5'ã¾y‹  Ñj;  %	/,ì0tØósƒÇQ>‰<­ý§¼X÷ù‡Œz;ð²=$^D;këiÀX¨úY=ÕŸk xïQ#¢ä•µï3b¯=wü$„¤vFÕ߃hC¹DZ¤OÚ°þŸãÔ#L`óŒ P„1רµIR#‚ø,1§'½‹± iG})ÓO¬ðÖ|hNïð
+ƾŠ‰Ü£Š|¡Ðg]ê1§§¼
+ˆâ5±ÿ[   ÿj½«d®ÝšÙçuuÌûo¸JæÎ3g¤õ,È¥º1¿ÈôWzÍßÎãÉn¨—Ô  $ò´e–ŒÔ÷ )ªe÷í´4á8ëØx/—žäÀ
+Nè(º·›ß¹s ©ц¿ë¾FËS38çæÍéI£ óçÜ“Ó&|»×’Ù{¨9#õ9 L3Ê^ëµ	?hh?Œz菎Â9Ï ’Ús:S§¬g/tõ 7%ÑgšÓS^,¨dú	_  (Bî]é*¿A¦{? €&fá&{Þäù挴ë r©vä¯2Ãí«½5_<eNOvfÃ/´Ÿú‚f‘P„B1?L“Õö¸Ë^@žêšjîG‰¢C˜:zA¨T}™
+©-9dÏ¿Ud{².·	„Taš¨ŽYØà÷ˆ·úÓOÕ‡ëÿx’˜xJ. Ôàð»v«¤ša®ºõýî
+JbhY2w¾}rÎmjZËê`ÑE	¾,©DÙ£Á¿w,º(¿ëOµT;ÆP;x…’Fû±4„÷eÈ0_#©Û‹ªûB¾PŒ~÷^%¢Ôbà2ê…°¶ßôRÝ8{ 7y1¼÷¸üRÚ=ç8añž£rFÕç’V9÷TF»Ëž)$÷Ôˆkš»â¸À}gу]¬YCo½ûuÌìeËuSs´m=Ýÿ®º£ôêr?–fÍ<¹1í™3:ýW`³¥
+¶Wô`—Ê«÷—;
+ïîјý_M飘ˆy[7‰ $Åõ  £êã½P²  j†¹êÖA”Z<_B¼Hh  eß… €DžÆ6”Я],FFÕßs)‰ @¦Ÿh»Ô„ p©ížsœ_jB«‹$5âšÆÚWam¿õÖ|&Š%]&OÕÂ(Þ{\^·ž·úóp,ºÎù¼ø,?™x_†ÌSõad L¬´«ô©äú_ö—ϸJŸLý%,:ÔXpê 8Çf
+çܦ®»=kûMï­ù:40ÜSµ0ªî3PsÈSýqdÝöyïq¹§êÃH,ºÂDÞ¦ð»÷*yÏa9@íY0ïːaÑ®À¢ëìe/Ÿe±é|ÏV±ö5ZŸå'=1XôRýz«? ¨íQpέwxÍßt ¨Ær•>äwPø¬¿ÄpÎ3=•ïEcÑE‰þ‰«dnŸuI£î›4™~¢Í²kiKÇA\>rO¸¦aÞ’„A±Öe6Ä„U‰þ²>ówZOåûÝT‘Ï?)7ͪ¶dt~ÑÚ"OÕ»!.T†Ï+
+lï*{æM„¤fD)ª½5Ÿ+Mi§^säO½öÖ¾ª=%‰8iHٱ–3j¬Àæ
+B’Á—¨ööˆ£èÞn~ÇÖYš¸/^´é³üæ)ý+$	Ù…[wÅ;'¢xOåûÝ
+vÝÃÙיܕï¾DÑútOåÂcêáÿs—½Ôµ¯z¢5y"_= 6¸JŸ(™WŸ´a½«ì™I´4.QʳgÍæŒÎO!JêÄå¯ÆI5C—hâ¾<xÍ–{Ë0Á—>
+Ü‚Ew'€Úg”XûêˆÖyª>ŠÒµûåM,zâ_úõ¬M ß©Ÿå‡­Ë÷V}ÔÞÔ)ûiGѽÝ8ÇÖÙvÄïÞïD”Â
+Øé³-A1‘k\eóß¡™¸-1¥H\    IDATœ{Tn¸ãû«ñ;¿¼ç°œ–§pˆR7ùí¿û€ârz —Ûfc÷'°ÙR$	(Ú”«\žqM£¤1‡iiû]úäÍ« ­;aL=¾P¢HûÕg]ÒßYxO/ ‘¡˜È<DNû¬Kιd(3Üñ•1õøB,²!¬}VúÈDi,É-—7 €÷eÞjè°ûYc‡¿ëÿØ  øKû;oקl}Jªéüw`²RSÚÉw$Êî‹02¦_H1á»Ýå/wõY~É(º/1¦ý˜¢u§]ŏõàœ[ÇÉ
+“>6¦"ÿbïÛSµ0
+‹ÎdŠ‰Î¦˜èCœsçmu_ç½ÇoÕ&üü’)íäÛh  ëXw;Å„ ˜¨\ŒÙ0Ö¾&Ѻ©î–?tí–îamË'"Ú˜E1‘y€™³øÑ4¿sçeøão;ìûސ²ý7™þ¶ÃˆRç;ìû0‡ ‹RŠ	+Ó'­ÿñr‡MÍœ‘öŒ½`úcœcë%_V½KfßفÛó'}ÜTíÔ>
+à(œñäù^wÜõLcÚ³çÝ~¯«d^×+ìòØó§ô<¬}9HR#®u¸î¨2D©*kÿ¯vèÕ`Á©ĸ(ZçÈ;•éÆmªß Eëj‡<#ʏùj©«äñg(iL¹"ô¡_óúÚ½`цõ#$qbÌ«0î¼vÉÏÄ¡r#J]U[&õ`Á¡Æد Jqfµ„âG È¥	ÄÁÕþŸa1ö×½úºí‹þ*% å¥hƒ–ÆKucë
+éÆÅ„òg‚©ÝæUˆÒØ(Z琪oøV¢ìa­=~"ª}‹~5¢UVŠÖ9uÿ_õ€
+ AFIBÏ®T(Fo¹iv:úÿýåq–Œ®ß`̵øÀŽ‚™½°`íK3Q¢¿DQ{rèDOÕ‡‘gf½˜˜Ã[óe˜³øÑ4kÖЉŽ‚é½YÛozkÖàIžÊ÷¢ë¶é*›Ÿ$r…­YCoõÖ|pæÞföð	~÷Þ³«p;‹êlË7Rô—œsÍgþ6Äš=|Bà2­»â­XgÉÿ¥Z³Ofí
+EM µ½,[öÈq΢ºf‘(¯[_Ûþ#\¥O'Y³O\"öY—­Yƒn·åŒS7–ú3‡Ø²GŽ p•>dË560÷$ƲåÞ<ž?­_`¿Ž‚é½ï¥îL'îŠ×âlÙ#Çž¹óÖ|jÍ<Éš5xò™KæãYûº[íy“6ö÷@’qc”=3x6{Ìù>@šø/þÄ¢7Jð—E‰|‰g³Ï^ì­ùê~kÖÀ)‹ŒÜ4»@d®0ÖSõÁ À  ´4f«åT·çìy·	” $á‡eº›¾´åÝö^Ý{j#ӍßèwïiÍ6AôWöWǼ»QöÞà³|ÿkÖ Û±àì  ÕÝtXðeM´fŸ òUƒê¶¡Ž~+!šØ‚DQ°k6'¦îë´´ÝF[ÎØÿZ2ûÎÆØ À¨.Øìá¢àÐl^2`Ž¢˜ˆS¬í÷;œE÷u“jG-Ù‚Á¢`Ó	\A{ÌÛ‰¢ÇïîÒgŸ³åÞ2Ôž7q°Ü8ÃŒEoŒ5{ÄxgÉã½5ßF’°R@´ZAR“({”P‰²ûiα¹#k[úÅ„W  8‹ÿó	ÍD–¹+ß|ÅUöl"çÜ’ÌÚV¼F1¡•œkçý®ÒùOPLt‰§êÃ×þÕ¦¢›í’(»eJäÝ€•ß½{¢TNGÁÌ  ,§®{˜÷žLC”ÊmÍörÝí=U£\å/¾C3‘e®’'?ðY›üέÝYë²iil!%1øýî½3  ¬Ù£ÞJéñ{ö÷»v?
+ àwÿu7  çÚ9šµ-{€b¢‹=ï¼
+  ø2µyZ&¢õvGÁôWÏw\ü®½÷û[ÇJT½2­Y7ÜÁ9·¥$¡5öܛߨ¿ÛsXô*EIçÜþjí6{¦ñ¾,yÝl9£Ç°Ö¥·QÒèr{þ”w ܯ?+QtÊ”ÈSO‹¼E”¼š¢õ%e÷ÂËù’¤F\ÓÔÑïd«£^yb¬
+ã]§ä¦k äÆÇäÆ™›(I¸`ê”õÍÄ”"JíR†>v¼~Š°G>£˜èbS§ÌÇ tí–=KÑZ»Ü8ã¹aê³  †{R„<°‹#ÕŽÉ—g‘glÑÄ~œ¡âuÞ{âì¥.™v´YnœúMmÓO*L3ÖŸ‰i³Ü8ó¨*ò…B]Âs)Ix¥1õÐ=´´_›°ø "ìÿÞ£˜ˆREØãsäÆ)Ê°ÇÊ•á?MÑz‹2üÉGäÆ'ä†;³äÆ+ Lrž”(»ž  DEÈýÿz6ɐ²ýw™î–%e×Ã
+Ó=ÿßÞy‡GQ}}üÜi;Û[zƒ„„* Šˆ4EAAQ×†+*XD”&±,(Š]‘* ‚RHï}ûÌ–i÷ýc³qÄþ÷ó<>nfîœ{çnȝ9÷œï™FªÒC·×º¯Ÿ€¥î›Ë/u™{nÙÄZ®{Q±}ÒsÆŸÍ eRÕ«µ^×lLÛ°K—´â	ÀEë† ˜z|~+ɤ԰¦+ª	:¾!B1¦®Ÿõwì_ý^413둼.qi  AÅm1¦~°Gp=€T¥}nèþî>Z3p½àþntëùŒ©í&¨øݤ*m1uý^DhªCÁ4  ¬yªÉë“ž+F("É”þõ:SÏ·„°©aŒ"µ¤K¾ÜXv
+Wß8>I©û­7twÉöÜèkym$  Á¤|mèþî>J3€î(´©Ç¦­ÆÔ^ïìþhÝùïS×ïE¤¶„oX’LPÑ~‘ß3Zòe.»³`¨V°>eÍ]Ââ9Pq)VøÑ{p–ù^~ûÛV,ó©æž?|nÎØùB¤ëDó+ù'`,èE~ßXÀþD®nn‚Ô—îÍ×)R£…1\ä!]AÇUkã«ú_ DE"D ÖrƒµÜ` ` Ü  *ÓD ¸ ‚¡Å†îoïïìZ„(·:êöMô=õ¡c”æ,¿1íÓíÛjbfÖkbfÖ‡r „_ @ªz
+Úø  *ã¥nh“:zFc¨
+­ÎuÃjg?úžzè`Kó@Ä<P~,|ÿNŸ¼úhg÷|›ëxŒÖží3õøâ‡ðcÚ¸GÛþøPê¾~SM[ÃÏ«L]*ÓÄ6U
+Js–ßÐíõƒ  FÝð½'êÿDhœ  ß(ùŽt Pd§‘ÆàwA0^  „	š î"B2Vø[‘f4,] ÕõÔU¦›–µ†´?ÝîJÊÒ„e§  Ëœ…dRŠ±ì2!BëoLÀ$ @ÀõETès;[¤¹5쟐 û(oóÛ׫LW~ Kx²¬ùH̬ð¿-#$ÑÚ¡Á{%Ô5ºÄg_hýÝ  ®îqca©‰ÄX6¯a\’÷€‰Ñâ@	$·^[§Žºõ5Møïd¢U~Ç3_÷Øýîò«ƒ.u,ýáµ)ò¦F¸xéé W7'=\IüŸÄïØ`v–Œ¿ðßèû	kNéìß“³áôDŸüâ!,sI¶¼Ì…ŠPuž6vö¶ßs=Ašsmy½pusÒ;;OëÎ]ï,?ß–ßû![~¯yáçtñTÄú¶¼Ì…Xvdè’–žðA€b{}nËë±Ü×¼v Úy¢v!H&ùpÀþÞ=¶¼Ë “æ²…`¾ËÕ<ð°-¿÷ö¼ôg‚ýæl´çg-s]ðB” €ÒøÎÛ¼z®-¯çbhuëLW½çk^s—-?ça[^Ï%"·SkËËXÄ×/¼cÁ¤2]‘ËèGÿ,ùr'„×ü"Š"a¸+®lèþN§Oäÿ‹øZ^‰Qĵ6~Þò=ÿD~Æo¿»>ù…ü?k+¢(¡KüŠ"§¢«ê¿cƒYešØirsWúöÛß³ªÌ“í®Ò‰c©©›¥×/kOÕ§ÈïS“lOá÷†ðœMŒá"wÈm,ùŽ°“,Úú­ê]5 ¨f®ÌòÛµ›Œ´~8Gfcœ›L¬y²ã÷ôß‘¢Èá~´ô›‰±`ÀŠ?š ÌX	˜°â‹¥Õ}?3öøl»½ðì›±ìê€	ÖrÝ:mü¼Ê–£©Ï#D{ d–R÷ßdLûd§Èï½ öÛ܍o€Ì"ÂPaÉ:¸ÚqlèuŠÔÒ@Q©cf®ð5¿t`™E¤¾ÊÒëà˶¼Œ'ÕQ·­‘…2³àÙq)­ò½ì?–eÎÜýž¯yM¬·ùÅiÖì£Ï†ÆlËË\ˆ ¢Žºý
+_˺ëK‚ŽÉ7gìüˆ«}¨gÀ¹éz LL·½¦ž›¿´¼+|, 0¦mxNðlOS¤Æ8¡xL?‚Ô»iŸn÷TÝÑGôhH^ý»ò¦Û1˜b–¬_Ÿw•]u¾ä;r	 iÝy›B.   DZó®	Þ&UÆËÞÖ%-?fËë±ãÄŠ?šRç|.Ì*r{Ì"÷ã( Èo9Ú}
+BŒcQÏƼjHYwN<Õwçž­-Y¿.FˆÁ­ó~5çØ|€à?TWù”‡
+Ý^_r¿„tò*>Wÿø÷Šd£}Í/2glÿä÷öoËï5Ïš]¸Ð–Ÿ=ל±mÉÉ”#\åW5¦~¸çßm×Çó×ÙËyÄÔ㳧R´8]ø;4 €“ýaï’„•cC¾~áH‚ŽÉ×'­ìRšÄÍ™S™&µw¶Ž bÚögÛÄŽ»vbÛ¾Bþ³Z8g„û〉T¥ÿÕ»ü^E¨¯2MúÐœ±åAÑwøJ  K¯}¯³Öë_%è„Cç'— `…ÏÒ&,ZfÉ.˜-z÷Okµü¿ßDÐ	‡¬9%a…‹÷6­HÀدG”¥ÄšSò`ÀñÉP’évÀšS<Ë\ß°$Y3ó%oóóÎ/féŸY­O~þWY¬
+ àkY{­°­Ã˜­´fðwÖìü§}-ë®cô£¿Ô'¯\¡ˆuƒE~Ÿ:àÜ8]÷ÈóÖœ¢ÇL=7鮜Þ0&õI+Ÿ#¨è®æÁ@ñ² øµê¨é»DïáË nÛ$•aì®öá1ˆŠªÔ'­\	 ØS=3[òå^Hk‡|jÉÎ]¾  ˜3w¯WGݺ–T¥í
+–Ø ÀŠ¯»&æþµ–¬ƒ÷K¾£íò˜°â¥0˜Z?gš3¶ÎÓÅÏ{Bôì˜ò7|År $K¶îʛΠ¸¾˜ªÈŽóBáå\ͬ±Ì¥sµs/]ƒeW?]ⲕ€E•§úž»å@©N«ÏíÌ>ß°$ÙoÏ
+|»åjfe†‡lcÅ›Òúÿ$À"êrus{„oÚK¾#¬Èí¾ÃÛ¸,Qävjƒöö©΍&è€,”Ó‚ûƒ·ù…øpe¿ý=+W7·GÇöÞæâCaê¡ñ„Ž‡·ûM)åC›MÇ9PÌð
+K’ÃÛ†©‘$†ÔH"üý{|¶Ýšsl¾9ãÇO$›õwcéuà•£ßgÄ›  £;¿  ¦A—ðdY𨬠°å¥?KP1‡Q¢"{Ò  ¢\aOH‘Ûç
+‘ª´
+  D+Eî§4  Ší•  HÍéŒá¢M¡ó¿·‡!í£|ã³€Muh• ¢÷¹Ê§UdÛY†îï¼ÔqÌšØÙ¹  Xqg‰ÜvAävȈÐUJÞƒ¬bƒáá­wâ/ÈÁ²³'W;ç  ‚Ž«ÅÏ £«¸Ú9„¯ù¥8¬øâµñO”Ûò{O,j¹Ú9I €d¤{äyoÓóSmy=ocôcVº½v(dß–—¹QæR‚ÐÛ±ÌuåPGÝÖlqâ곈`K	:Ib­7µpõó—¢öÿ÷•Ä'ùó,¢Ûæ]
+×Æ=6›o\¼ 6"Ee¼Ô-r;ø:]ÌDn§ÖU1m	AYsË4k¹ö%Oõ}S¢öcïfM“^Ô%-?Öñ:{áYw Vh ÔN¬ðŒ>é¹  Áóƒ°dõ;?#‹5ûø†ÅÝä@É@Œ‹oXä°ôúeMȆ·qEÏ€óãŽÃÛ¸"Ue¸ømâÓù|ÃâéˆÔ5¶}÷asÆö»iRƒ–"ÒP†AR©£g, P¤FÒQ4âQ’N:¤‰¾çː]wÅõ£Ép}‘BO•™3w¯çjÅ#‚mñÛÞ4Xs
+t¦Fr&£ÈR멽•üýb©…>ÝÕ@NFW•QÎø'(Œ„•@´:zÆ·Xv%üv\68KÆŽóTÝÑ€ä;þˆÜ®Ë½Ë±a¸6n΁àQ Pê>?
+îo'·ž¦‰{hŸãØy·L÷Í€(ÞY:q$ €&úîE϶ù¸£³±!B­  L·ï€P»ôÉÏ¿Aë.ØÊÇÚ	Êr(˜Œ¸OímZÏZoþ¦ÔQ36¨£ïüˆÖj·F±Ù_ð
+‹—’L·­  ŒnØ7  š¸¹ï©ÌS7ÑÚ³Dßáh}ÊÚ×(6çcÉ—; ý<ù’4Q·¥ÈÎÓnQúÓj ¦<UwL Um‘}Þ¦	Q¼:zF#BŒox*øV……DÛÑ+ÎOf¨Œ—túTÊÕ?q!©JûÁÒëÀ+–¬C/ °æ«¾DÈ1Á³¥Ój¾XñERyÔ–ë¾-h ­QŒSgÉÜû–>é¹É_p¹)ýëyÖì¼ÅŠØ4¤ãC ¶Ê’udk¹æ9Û>‘ Í2£þ`… ÀW;g°§jÆDY
+,Y‡^´få. “ŽÂ¡KiÍÀïL=7nR}×ÏihAˆuÊBÕØÐqÖrÍ+–¬#+0öÅc, Éwä
+cêGóÃÕHÎdøºy™îò©wþÓýr5³ú¹Ê¯¾%ü˜»ò–Ëùº¹Yµ÷5¯‰u–Œ÷ό«J,gÄ¢F±Y;(u7  ©Êø<tœTe|T×±šoxæ6R•q€b3¿ @„ª
++‚JôîjHY=·ãµ“tÐg{óÖzÔæ,?Åö>@iÔ S?ØC©löÛß¹Juó-!‚õ˜3v|lîùÝr,;¢‚Š	€èmÜÜÏŽsæ׈Š’ Léßl ™nEîªÛïù½C¡QLé_½„Ç]9m–ä;§Žº¥Ym¶Ü×òòT_ó‹×(ˆÒô¯ Ô}  èS^ÜNPÑ?kã|üyÍÆpÑ|ýÓŽ' R+r $É]9m6–QúäߏÊpñ*¾qÙt’I)"ÙŒÏ:›ËvãW÷sRlöÎSµ;] Ô½¿—üwè“ŸoG÷ÛÞ¹+‚Õv´Ç
+Œ1ÇGW  ÄÔZ{—>`Í)ux% Fˆm{ªTÄÊÛüÒc´î‚ý”ºÏf¬ø«¥ `É:ü©J=Æ7.›ë,½´Ct)
+P¨Ðï „±ìl÷o!2¸¿A€e_??Upo¾–5OùŽ -‡±d³bÅ«Aˆö¶ïa@¤O‘]耧zæƒÓ¬‰¹÷ ©í<c¸¨)4>,; L#ÊÛi·—æ,7ÖqlØÿ…”A®/
+žª;ú8‹/﮸~p¨]HAD*ã;ÚàjÌàjfe:ŠÎ¿š«›“Î7<•â(9)X-:ˆ»âº³]eWŽ87ƒØA\e“‡]ÉÎ’ñyªgf‡ÎùíïYELVÄú˜ŽýÒÚ!¿ÒÚsê}ÍkbƒŠ##¯ðTßÙ Àïüè\É_x…£häÁR:;µÎâ/ãžNéhÇ]yóY\탎¢‘“B AE’3ÇλV‘$_¿°›³øÂËD~&¨(2q@08ÄU6é¾~~jhe¡œvU\;Ä×¼&6¤Âr…+b
+å,¾h¼£hø”âJhÞE#'uüwpn4¹Ê§œw¢ïïŒp?†ç™{þðyÇÏ­ÇE5š3¶}Úîç°kÝ¿jãçm
+ýÜ1Oɘº~/ ´…Öš3~ü X½Öœ±ó#9P̸ʮ¼› ¬ûÃó9B˜Ò¿û*ô:¥5 `Oû6ß| ߆~ÖÆ/¨ÐÆ/XÕِLªhÉ:ôbø±ÖÈĶèDÖ<y3 lîx- @«˜m» Îæ2DkîÑÎSµ;]0tûÇ€sãä6W"5Ž´ôÚ7• “$Œd;šúþI’SÛ¡Ž™ù-WóÀ
+gñE4™2¦®ÿ°¬•¼2%ñX„˜N7ƝÅ^EPÖ&Dhjˆö²Z„®Ä~ìœU†‹·“tÊDZa³¡kB„¶œdRÅð¶Xöôs
+›ªˆõƒ)ÍàO  0Ì÷7ƒ©é|‚Š®Ð'?¿Ãqlø+ŽâQ<`™6gìØ  Š%ëàãöÂÁsÅªCš˜­ViY¨I●‚“<“Lê÷Î’ñ!B_‡±pÜüÿe°Â€hÒ<ìm~a>¥Î™-x¶$œ—Òº¡KDþçËÝ7€&î‘#žê™«ýˆn÷µ©kç9<ÛF(’­/­=÷]¿ííEˆ4ÿB©³wsÕ÷>¡2^z¿­ Ï,‚Ð7¡qÛ,2gîzÌS}Ïýz€›}-¯EK¾ƒ—À.GÑÈçÝ°·DnÇ(gɸdmÜ#»¸ÚG–3ú/	܏7”åèqýŠ‡°Â«Eþ§{iÝ°•××wôSÏTt“"TÛ(M¿B¬ð„«üšµ´nØj¿íõ{$_îFcêûmy"·ëJ  J3èwÅ
+/[s
+§	ÜŽ‹±Ì'3ú‘oyªî"y\Ni}æ*›²Î’{ƒ"6ts¸R‘zSlŸ-€hÙײîvMììyžªbÅ«”‘Ûý ­±8àøp†"T¤Žšž(““$­U|ÃS‹UÆq·\_[øú§–0†_À
+§‹ox*Å×òêÚ˜ûÛ©¶„sF,j„PÈigX³N8a]…Tõ,YGVüY;þ^Xë?cÉÆ B§„°U¦«*b=Åšÿo.A'I ­Z–ë“…*ZešÔNÆHešÐ„ÏËíìš';hí Û¸šÎ#éÄf‚Š•u‰Oßçw|Ü_÷È"ElP °¦ÉKƒí§¬@TŒÌèGïù½½T¦Iý¶7Ä’uèY¾vNAÅùÌ™»ÞçžNQÄz>ù…7:ÞAÇ~KÐIU*óÕ;BÉÝKKeA7÷^DšD’I-ÙG¦{ªn?:_h<ˆÐ)Öì‚'Ý•Óûc…#B!ÛÆ›æóuÃèG~€e×g  ¬åêH6+ÐzËiVÌÛ6rµ¤+²MËèGN#Ui§ÍÛ"tŠ"5v“Eà 0åm~i©êY(ËncÚ§ÛÝ•7z$_î ¾n¾Š ¶º¿³ßUv+Šu´EkúlL]¿×–×£šµ\ó6îѪ–£Ýn À’³·¹OÐåÛ’›| ©/öTÏÌùŸÎ¡Ô6yªïÎ,ĉރc +Œì/ìÁ7.•I&å{C÷wö;K/5)b]§yo  ÿƒ1õ£ÝÎ’‹
+‚{Ë Z;8WòåÙõIϸ+o>‹ ¢~6¦~°‡«™ek
+k—ÌÏƾ§O~!ß^Ðw(Wó@  Zwîû†n¯²åg=®2_½V—°¨Ô^Ð÷®æþþæÌß´íñ:"õÅÆ´
+»  |-¯YDn§VòoL]ÿ ·qÅ@‚ŽÞnL}ÿ'OõL—àÙr™ŽÍ<(Êr$%7°ÂruóûÈþüÞ”fÀ»áûþ€%£¯ù奆n¯Þ^o®#ÿÙE-B€V	£è“Wå tä)ltÌÍ£Øì€.aQiG;$“*†{Z•K¶´³ÙÚ‡.ñÙb €ÖœÃNóbpø˜Â•<Úµ#X	ÃS?h÷æß:Ævã$H³lLýhwÇñ  º½úkÇû4¦ml·?¬KXܦ:º‡àçãÕHNÜ•· % µf<iËïý (`ô(¢Z•C	°L“ªîM’¿ð  EvtêJF„®M½ƒd’Z?‡DÈ€"ÖP­M2AšeÆpág‚ûû+°Â¥™3¶¾é·hÜ›ó¬Ùùm
+#žª}E¡º  –]'­A‡÷Ž]ðRˆÐ	 
+
+ @±Ù"·;
+ @ë,!!ïp±6  +~+©îÓüO at P1A•BÛ¨•V (ÅŠßL±Ù|ݼ€(Ë\z(¨ƒb³?wWÝq7"ئ`JÌ
+ÀŠ/:h¿&
+Ú&wå-£Áº-½¼bËë¹+¼QQõXj‰k7 D¹*ú W7oŠÅpÉ«'ºï3bOÍYzÙ˜P1Å¿¿ým«³ô²1äÚ€ëKƒ³dìøÐ\í#>Y¹+®ì,;ÎU>uè©îÅ]yË gÉØñîÊ›Ï:.@à”¿óû‰Ð]âÒ¢;¬út…1\\¡H-gÛò2žÂ²»Ó€€à¶¼Œ§å@éÅ'jw"hÍ€E,±åõ\ÚÃÖ'=W€eW?‚4å#B§¨£niF¤¾Æ–ßk¾-?ûQGÑÈIºäçs±Â'Úò2ž–…ªÑ¿§OMÜ#U ¬¶¼^ÔÑ3êQ^[^æBÉ»ï*ÖrÍ—Û‹Þ_'Ùò2žDs¥ÜXË5_ŠÜOSƒù¶4GëFØüö÷æêŸ}œÑ\*wcèþúEjº”1\ÜVx+¾[^Ï%¢÷àdµõ†ohÍÙEr ê"[^ÏÅXñ% è“Ÿß¡HM}mù½æÙòs	]kéõË„¨€½ ÿ½'ºÏ3BQÄS™…‘í    IDAT=3[ešXÕY¹õ¿Á³UpnJ	=Áÿ<Õ3³®OgSlÖ'  ”zÀ±Îžb[Žv[G©2>Wdg¬"֍!™n_š3÷tš<i;ÚcÁ$îÅXd¡fTTŸêï¸þiZŽ¦¼z"—oDQ$B—ø‡E°Â’ïJ¶?"¿GÓ•v¡È…\Ü'BÊiÙ_†kvþ™~Ã9‘J‰-/c‘&vö*JÝ›;Y?§R9	87š<5,Šê]q €«ìªóe±6UŸ´üãp»ŠXC)bÔ¯ü
+Á½YOiúzO&JâŒRù/ è诼ËÏ•Å#d !X²óÅ
+O8Š†ßJÀˆX³žt–\r±(€•éò7t‰Ï·íö
+BŒ+þ8Jý‘(	X¡ô)kç‰Þýf‘ûq ä·í¶!Ɓ±¤SƮӧ¬9â(y…"V
+Ä8‹:kNÉÃáãC„¦2<0 À^p֝XáÚšSò €&öŒá·Èï{ÏY:n‡ä;ò±ÏöFwÁõå  $›¹%¤ê¡2]¾Kó@]Knü’÷ píkYûPkÔf­Ó_ÐÆ=RT
+iî
+€	mÂÓÏ„ró|-¯Eó
+OÍCˆH¶÷W€*Y¨€	Ö<õ-mü‚
+{áÀXv¥"õ5¦›^ušoÍ)z<àÜhâê¿Ýš÷Œ«ìŠ’¿p`L1Æ‹?ÔÆÏ/rY@ˆˆP9ý˜o±âO³åg?Jk‡~ÝÑ­u:ðgÔ<ä@1Ã×?Õ×Ðý­áÇùú…Ý©51Ô¹+§÷—…Š”¿2ÐÆU6éÉ—7Je¼t}g9qÈfØ<Øúß«Ÿ÷vGe‰ÓDè”®.fa!H³¤ù”íH&UìôW,h 'V)!èØ#à?U?']Ð\_¸ÚGïc-׶ÅLr3 Fít’ÔÙâ~\ñÜ.pF,jX	±â£1ökPÙ¬Y¹ËíýïájîËQÄfB»%'¸)‹±€$ÞUQ½«¦{›V$øš×Ü­K|öQ¬x3,9¿Žæjì#¸¿}(ªOÍ5Áâ€ÏCiú—a0ûòeZ²÷	8>ò6­¼K‘y²P66ªwå®fV¦ßñÑ#ǍOrœg;Úc  ­¶QcAoÍ)šÛÙýÐÚ³}ˆÐþp~/¸¾¸I7w©Êr­Ív4ý5h^ô6½ø°·q¥QQ»(ÍYþ€k8gí]7ÙS=3ÛoïjRÕýuEjhÍ)uü¤ùIÀþkïú‰r ˜q]jHyéq‘ßkõ;>¼Ž ¢_Å2—`Í)y¨µnWfëüµª®à€c‰Þ_¯2¤¬~TTª½MËï#¨¨—dVŸüÒ’Ð/¥ß¹¡,|oà
+oÓªø‚¾¯å•˜PÒ¹¯yM,¥éëiUó¨dô£l’ÿ¨–Ò⎏âµñ*øúÝ	:™WGÝÒ²‡±€øºy=T¦	u‚û‡hÛy£·qY=uKC('2àúr4B´ÆÍXqk±ÂY¼Ë㸖ðD^_óšXÖz]3"tŠä;ÂbÙI
+Ü­=ÛAë†ñÞÆeÉšØÙÕáz‚{³^ô˜¦Žºs>k¾²1àÜdIJDbÖrƒÍ×òJŒÊ<ÙFfY‘¤èÙ¦W$Za-7ؼM+TÆËZÂ{%¾*4”æ,VøE¬gù†§SÂ÷÷°Â~Û»ÑáU"œ^„¢¹ÿ*ã¥n•ñÒáÇôI+ ðÏÚ>gÄ¢IÅ  ÒÐ(UñŠØ؝T¥¶¹
+×7 Š `­75zW„J"”¤Y&Ué6Dê
+ ÊlSĆd h‹BC[JP±²:zF#߸8^pÿ`@ˆâ Øz¿ã#è¢Ì»­Ù…msŽâÑ—tÌ	Ÿœ©‘Ä
+ŸCë.höµ¼Ó¦,‚’HR[oX©HMÀ¹ñ!Ej$ƒcÓT  °–«+®Mi‚ëËtD`øí^ô¹  >ۛɀý	mj%Tt‘Àý˜†HC5  I'×(bc& @°Ê±dc  Ž, øº…®ETT6î±*‘ßû­§êö…@¨­ÙyKN4†oóñ¾¦çg"ÒXæk~>Ã’uø!_óê«ÎO‹¡ñJþ¼*ãåëCjû·ùš_Y€U#Á$ÿ,WÞl‘|¹g5Þ¦çkvî2OÕ}îïn!è˜C"ÿHƒp Îïüx­ºh}JŲ3FLJ.D™œŠP=ÖoÛâmZÕ_—¸ä~•i¢Ã^pÖ“ˆ4Tz›–fjbX*x¶õùŸî"(ëϾæÎF¤ùW„(Ÿ¯e]ϨÞå÷„î+àÜØ!.àúl–í{ü¶·W"ʺ›Ñ_ð_¿h&"T¾aqšÊxÉZŠíÛÌ×/xQQ;°ììÃ7<›‹!yWö7glZØ÷æ6UZ¨Ü àmZù "´u~Û±Öœâ9žª;úž-S©¯õ6¯Šú+"‰ÿI0ì/TuUãQ3ˆ4È+KÞƒ,©îø'«6ÈB9;sÝuÉŸ¯"™±+µì:S0èºÒV8B”1§šÛßûtäŒ9*ãøÍ"¿jÐÝötJPHSa¹Ú3\¥“&TÔÏÆ>kžìÀXf]×ájç^×>A¶,¸ºÇÓ¸ºÇÓüö·­šè{·Éþ’	Þ¦	!•
+ €€sSwWéå#dž>CP±_2úQA™s%cÇ{jîË@JHÏ
+‘AŸ¼*Ÿ`·¹Ê¦L Pd×`®ö‘tOõýW“tÂn]Òò_©ù®nn_óšØpÀÐÈ Z£âccô£7ë’V¼Ik‡üª{ô "6õ6.KùŸ/ úµÚÛ´*Þ×òêU Áˆ> Ô´öÜú”Õ¯ÓÚ!û}-¯E3ºáún¯>ŽOV8!ÚÅÕ>’ÞÉþUü¶·.C¤¡œ ãË ÉSuÇ@SƶՒ¿à2Ñ»š©ÇKt‰KJBjÁÂ…˜ÔÄÌzÎÜsëgšØÙyP
+ at HXn†±€ÏÖÉšèË,™{ß2gìø˜µÜð"4e–̽o…»]:þ ©ê¹ÝÔóû¯  iþÕ’udÉf~ì·½y®»òÖ! ˜ èø2DK|¶·Æµ¶ûÅ’ud%AÇí ¨¨KÖ¯Ï#DzÃu õ)/ç†ÆLPQ> ˜FkvÞbŠÍiPhKÖ‘•¬ùª϶˃ƒQÕY³>Ki¾€IKÖ‘·“¯_Ø/dS3³¾MÕ¤5”1\ò¦%ëðsKz9PÌž-Wt¯P‚¾{x±ÌÓ˺XWÙUzP:b/<ûfg鄇½MÏw·åg=~¦èÙÑå
+æGÑùW;‹/~Œ¯_˜ãª¸vö±á*›2“¯_xœhgðu÷rWÞ4	+a?vδ6'Qúàëtw•^> À×¼&ÞU6å8OVGŽ
+wÅõ3º2¦Î8#5ŠÍÞE©ûÛ)ußBJÓ¿ €R÷Í£ÔJµñ*T¦‰«½M+o\_ Ð%.yTðl¿ !J4öøt-ÀoJ”º·‹b³w?;(u;Åfï
+o @µ~6¥mœ¥5)_‚HmyøØhMÿ&DèË×ã×ãÎOû¨L]ꨛžôÛÞœp~:.dKä®HM‰´~Ô;Öì¼Å  Æ´O^ÄX¢EnϹú¤s  H6ó;Šíã 0¤¼òa¨ !AZv
+îo/A¤ÞfLÿê‚Š•5q=,¸¾¾ØײæjÀ¿¹¬I6‹#Ù¬6õ}ÒŠGD~ÏÙžê»ïUÄF#¥îëg­7<å³½y
+AÇå†Ú©L“–ùZÖ]OªRsI¶×­cxTòçe¹+o™¥µV ùíï]驾÷•qÂò`$×+nûy¾–uiÉ—þWBj7AÝ´vÈFF?ª<¨ÎÑZ`Q­)a+‰!ך»âú›@ñj5±³> „¥&@VT´ÿ·ædÛn{¥-Ä ©k @„–ÊOÍ¤ÑM±Ù¿¨Œ—n	¶ÓÝzˆöTt«‹ôËB…æD·‰M €";hUA¤ÑXVǨjí[ã…w#Äø°ìÑv°ÔÖ¶B*À’‘'AÝŒnø+¤*ã_Õý“ gÉÅ—„j*b
+Rù}jwåôþ\탊X=‘ âŽÊþ¢x,;‘tâQÆp¡'àÜhržèky- €¯ŸŸê©¹¿—£hø”pE‘p\åS‡ºÊ®á*»êüߎ]=4¨:råp  wå]eWŒÀ
+Gpu§É’©p˜1\\IiÎÚ,å´«lÒ Áý,Wù5ç ´*¾<$¬
+ ੾³·£xÌ„Ž…DÏV§ê¶~ AU“€s£Iòç«Ü•7¤µç6К!‡¸šú(B厢‘W„Ä­Ý•7t–Œ/Š™p{÷·ˆ¾Ã“œÅ^:æ,7ÖU~õАh¸"ÖPáª)”ºOiîüm®º¯®pF¸C‰~áåôÉ/æµ}jèµéè±æ©vÖ<u]¸Ð}«x@[ÎPë5“w…· ©-xjÞ"ÕÃT†1íʨ³Ö›ZXëMí”>‚¶Ÿ(×Æ?±¢£­Žªž‚¹ç–v2[¦ô¯¿}¦Ô}ýæŒíŸðõóS‘~K֯힚4Ñ÷Ôk¢ï9NL™Ñâý¨¶Ê*Ó$§Ê4éð6º„E¥º„EK¹º9éççé ÇÏ%@p3—1\ØÎ搜º­ò‰&vv­&vö[Ý㿉Ê4i£ÏöÖ,DmXጲXßÀ—\z+­9ë Bq–\:Ûš·!Úé(º`2kžòc;ŠìHð6­¸
+c1 €ÒÞÈ×?9×ïüì„ŘöévOõÌGñè‰ú¤•ß…Ü*”ºoaÀõù®ò)n†RÖl³v¥,Ö' D	z~'ڸǪ|-¯Ee–jΡ4C6üžë¡/²¹Ie¼x{gç)퐏$Àf¯HMIˆPåuÖîEvŒ$‘j«ä=8ÜQt~º6nÞ×"·çÿ `¿Èï2‹ÜWhãç=°ÞKiúT/ò{¼”¦‘·ñÙ$_óšY´aô›|ÃSóÁ.<[†ÈÊKýÈI:á¸Dt¬p„àÞü"­9kž¢p{Aÿ–¬_Ÿ<ÛQªô×T¦Ë·Ûò³%™ä_±~{áÙs´ñO¬ ü”¦_ ‰EnÏu$“ú³ä/ì,HȾ£—1Ʊ¯sµ¤œßFëG¾ÇÕÍ}Š ãô6­8W”¡ØÞÛ%ß‘Ñ ðqh,”:Çç®üîNfˆÜ®‡©åM‚Ži™  ’/w0k½q¸¾æ(M¿B‚éÀJ Eög¢WÙ•w‡‹N¤±Ë®æЈ"Û/ QƏ’ïÈ(WÙd•©Ç¦möcÃVUSvŽr–\ÜMešôK«¢ÉAÁ³íIRÕã-ÖtÅÖŽóv"ΈEíßÆœ±óø´˜ÖEòo	ÄÐ%,.Ñ%,~æï°ýo£_PÁZ®ÅÕ<8”P¥–©­7Ô)bÍ!MGOõÝ6¬p„¹×þGøºÇ{!*&R 0elY멺ól‚Šq1úÑ[#Sßÿ)àú2Ï×üòZ7ò €)ý«Û½M«²©oMÖ'¯Ê§5ýŸ½cÃØE¨, P[§T¤† “$kNÑžÊ[aůÒÄÜŸ+Õ*E¬/ P[®ÿŽ`ºy XËÿ½¡2^Ö~o¡q2ÆK›±â3tÜšsìOå-ƒÔÑwÿÀš';d¡œV¤úׂ}ߐ'J*  Xë´ÍÕ%ëà2¾nnO‚Šñ©ÌS_aô£\  *˔Քv×h¸ð'‘Ûy„o|v(­pðß*òg@„6×ÔcÓVÉ{p³lÒs ðuÇ6¬åZW7‡‰NûZÖðºÄg‹í…ƒnÀ)‘Û=@a|-kG ªŸw”Úkß'SnÉM~  !ªÅœ¹ç]Ej$½+†…~q°d?—5O^ÄÕÎâõIÏHÞƒm.}sÆ+íý?&èÄoôÉ«ÚúͬЭãQy–\ åçkb\¡Žº­É–—þKø8‚[HòTßÕ—`¾RĺþŠÔâfc¾Ä²C Àš§4y—s¡{Gˆn1gî^ Ðr´Û+ííÅ5)RK“.qi‘·qY"Aö›z|¾…«}°:àúv‚§úžFÀB¼è=8@¡%Qº
+ mLQvKæOowýÛ‹,j" ©ê){|¶=ôs¸Hq荅}†0@P‘ãývòB moüm:›”º¯¿äO+­oò¡ÅÈ
+оø"B¯ÆÞà PGßÕ:®_PÑÑv(ŒŸb³T˜×¡£M’IµñO” 0†KÜLë8~+;ô1X—¸ô¸<±peZ7œ7é†wª1zZÐá+ð»Í16’M÷ãÖ2V"à8ñßpÒRKPÖÚðGÑ°©ˆ4œ4íc)
+ @òd‘Á D¹ Z‚­²=™®öáþ€Ô•ŠÔ<H‘_C¤±ždR‡ÿ~ÛúfJþ|+ 4a,§JBP1¿îïîQ'®Üß]‡W–.ñ™åžªÛÎ @„·nÇADXx>n/¬M¨À2ýÛ‘ 2 VPhZsV“àþþhxdt¸¨qh~‘E-B„ځ)[^úRŒeµÊ0ö’I¡®³åe<	 kBÑӝ¡K~îWéÚò³û–UŒaôqîÝ–Ü„O¢úÔµ+º‹€ðÙòz,ÇX¡iÍàõ¯¡Ô}6Úó{?	ˆq Åš»¬c¿ã‹àÞr·1í“;ù†…ÃœÅÎÔ%=÷Š§êŽ‡lùÙCˬÊ4á]Æ8ñ3¿ýÝû×W<`ñ¸D9Z;d¯ßñþíºÄÅ…~_1È-ªðÅ:š[^¯šØVŸl&5q8ŠFÝjËÏ™£¶ÞtÜk½©ÅÛ¼ºÚ–ßk> )Ttk¹æÇÎlu•3BQ$ÂéMDQ$B—ø‡E ‚¡îe•Â•,Dn§¶«îT‘Û©%èx±cø»ß±ÁìmxúÚðŠXá[~ÎË–ÌÝwaÅGt¼¦ãõá±]EðlÕ‘ªÔ@(‰+!û‹˜?’ðwЙjÊï%¤(rFD?FˆðwÁ7<•b?v΍':oËï5ï÷سô½?1v2'³kËÏzìtÑü<]¡Øì@Gi¦ß³?Hë†ó-N¬y²£c‰(@&¨˜$lA]ßÕ1„ÃèGqáª$ˆÐ)ÿ+@Ðþg´p"‹Z„ÿ<Xáˆð|*ÁýAòa¹º9éŒþ¢fÖümѦÞÆg“$ßÖïØ` P™&¿týȁb†oX’j«È’«}¨gø"†o¼"sí$¬xS÷f}¸è3V¼m{7Áþ>°„K’ýÅŒ·iED8íAˆÁ–^ûםºe„®ÙS‹ðŸ&˜ÿÎl‚4ó6­H¶æ”ÎæjçLSdG‚ŠúËž]‚gûxMÌÌgmy=#BÓàkY›€Ö<ùA¿ý­Gu	ONçjç<íFkóÛßÔ[³ŸpW\?J‘lñ×)ùTY(Bì81ÆS}÷ƒ€ÑÛ¼ºÊ’¹·-õÁY:q¤ì?:ÛìmXì·d^ ஸv>"ÔM¾–uZkvÁ“ÿÐtE€“+hH¾#,©Jº¢ÐÌÑjž²­ÔH*’¢Øì€(f¡Vºr݉laÙ}œ:È©ÆŠ±ˆ:êPžŒ“Í•,”ÓˆÐ(áoÄHöUè-²+ê%‘7µÿi×ãýèu–¬Ã« 1.®ö¡ž  ”*s“¥×/k¡ ‚rZ H¶d^Åè/z³3[¬õ†µ–¬#+°âK ÐDßõ3AZb²P5öÄ£PTæŒ-­ÙO*B]»$SÉwd’¡Ûó­ÙyÏ(²£O(¹UeºòUKÖ‘ æp%‘?¡²*Ÿ›v‹ÏöFl×mÝt±«bÚøSµs•ÿß¹ŽcCŸáëæí8vÞµÎÒËæxWvI	Ä^8䦎Ǹڇû»«fŒ;u¿S‡r5³2 ÜUwŒpWÜ0©+}†8é\UNÏÕ>ÜŸoX’*í%zvè\7œ°¬ÌÉÔKBDÞÔ"ü§ÁXb©o}*$ýXv« HUZõ	/B'A«ŒÚBà1§zæC´vÈ&Ö<uW÷èIj_!‘¦Ö'{ÜAyÓßúdŒdE
+î¥!Ò ´ŽET¤"üeîÍz¾qÉ(•qü~MÌu~dzÈmK”üEi´öÜ£”fÀ7 A·µ«üÿF!BëÀ`Lýp¥´‹Ötñõ»aÅ£ù}}iÝ°Cº„E¥"¿GÃÕ=v €&úîí'«nஜÞ_‘š-†n¯ì\_›E~ÏMu%ËBÙdRÕë-Æpq»âúÁR $‹Rõ,0t{?V8Â]qãyˆPû
+ÝßÙ啕/K*'9ŠF:ÕÑwníÉÑÚ¡Õ]î’üù*oã³½ÉfFˆ©ïÿé(y™ ¡\§\V±  c‘uœD©û†Jq	ž­:¾áéQ*ÃÅ¿hbg׆ßGh®<ÕwöF¤Ñ/r{°æ)?ª£ïj µçä’t2ç·¿3ZkÏsÖRÖ|Ckn pWL$Š²(ÍÀƒáb§"ò¦á?
+£þMÀ¹éNGш+±âÎÔ%?ŸÛY»Ö"‰„½pàÁýý4 tÊúN ˜’…š$¾qù-pÒk˜tzŸ½pÐmˆ2
+?C2©ß9K'<l?vî
+±!׋ßöÖtGÑð)+lgùdþr ˜qWÞ´† b½M/<⩺­ŸèÙœp|²Œ 
+.JÝ×!ò?Ý `/<+¼NâÏÖ§ Dîlj‚g§Uðl9Ûoÿð‚N¨õÛÞž'x¶ê$_–¤“jI&µÒSsÿ	E¾í…ƒo•|‡Î,ÒöÂs—“l¦!ÊMÐ	%”ºo
+ á£4ý
+΍ÝE~ßeŒ~Ì.Dh  ö‚þ‹BªºÙßJ«û5"9JÓ¯RõhsÛ	îÍ‚gÛy’÷€.àúj%`IþcC\¥Ú<E„º‰ Õ”f@ €"T#蘆€ë³™Þæâ®/
+îÊ›—’L÷*_Ëš{¹ºÇÛÉà…æJðìpl¸• jø†%Ϗm=Oðü(KBªZÝ¿Pòå«E~×T  Œ­;¯àÙz¹«üê¡]ý#‹Z„ÿ4úäÕGõÉ/Ì%˜Äkvþm1˜µ\·‘µ\S
+  2]UÃZ®{ ÀšSô(c÷=©ÊÜLÐq‡ ~Sí`ÍW¯"UiBðó”e1ØØcÓ|‚2ÛYó”Xó5 ¨Ìÿ·†ÑÛ.Ê‹µ\wc÷9­9ëgkV°DRÈ®9cÛ§ê¨[_£ÕýYsŽÍkµ¿Bsïj‚Ž¯±æÞ÷ÏÌÔ®v΂NØbL]¿—я|Sä÷Ž @”e—1mãŽðèC,siæž[?3glÿ!ÚÖÑɦnL}ÿ'‚IÜækYÛ—T¥ú$_î‘ßs)`!ÎÛ´*¾³1(Rã9¦ž?¬ÊáÉA=O¤²Óš³JµqV"y}Òs”f@#ƾDÁõÅ8RÓìwl0cÙÓWòž§HÍŠX?’µÞÔò[ûÎ÷©¡;lJÿj3k™úa°¦b»sMWò è¤o©î!Ué_ÎÏz—] Ð"¿gÆ
++¸¿¾èDsËèG­7¦¾ÿ"4•Aw~ë<Ññ͈P7w¬ù‡e6àúâjÀ¢^òå
+;‘ÝŽD܏þó´ª´Ukw¡ÐÚ³}´öìj  {á Û°ìNDt	‹^øMµ#¼šyHqƒb³Æ´;ÂûÒ%<Y謀gø1MÌu P×Ñ~¸¢H„¿R•Ú(ùÏ P¤f"ô­âΪã]…ˆôËDy	ŒEëq§‘Ú €€_÷Ø太ûQcÚ§Û[r“ßT¤ugc@@¹%þ€&⎩•`QGÝÖÄZoœÎUßÝ×Ûð̳æÌoBS||ÝBtÒ •Pé,Dh$ÀJû5QÆb›""oë5Æ"MÐñu€;Ì™?µÓí´ÊÊ·v(a™ÿ­B# (í\è’÷ +ùó'Dõ.¿ÇY:a´(:ïTöCDµºˆ¥×WNÝ*ÂéŒ.qiQÀõ…Ú–—¹@Òjã[,ò?%v֖֝÷–£ðÜe€È BLý©l“l¯|Á³å6[^ú% ò	KÔк¡ï{ªg,  ý$²ùD‘”®ò©C%€hž ¢ö+d§ì´åe.DóˆPÛ-½ö¯C„¾Ä–×k:júºŽ{^§‚яùÙg{ó{ád‚Ž9nŸÙÐmÝÏöÂÁ£mùY`’Rø¾3Ù¸“¡›SdwnºÃ–Ÿõ¸.aÉó mrp`Ëëµ cÁŒæ¸7áQ‰ð¯Q‰Ð%þIEßöTE*ýŽ
+f•i¢“«žÙ[ðl™bÍ)züTýKþ|"ÔÊ©Ââ1"TÒ§
+¹—¼YŒ%æTýÿÞp²@”¿‘ߧFˆÂuB·àÞ¬ïjRvHQ$ò¦!B„èJÕeÁó}
+_ÿø½ˆ0Tkãç?׉Aˆ  ÒIDAT%»lv +íbpWrÈ:[D¡SþÉ
+ è¦ÿ;ìþ•‘È¢!B„ Cʺà pøßG„öD¢#Dˆ!ÂCdQ‹!B„g÷c„"t‚·iU|ÀñÑHDE5è“–í"U=wÅ´Aëù½hí_ DºÄ§?çÀŠOËš¯Þ©Ž¾«Á]1m&vÖQJÝ×ïk~)Nªuá©þ"oj"DˆÐ	²Pn¢´ƒ–Hg鄇 D~÷”€sÓõ”ºožàÙ:ÒïØð ÉfÃ
+O"Bï¦Ô½óùÆgɁbFk=Õ3Ç x›_º@A'ï1Â_AdQ‹!B„N@„VÜ?\*eç`ÙÕ7tœµL}#¤EH©ûn0t{ý ­;Ÿ“…Š,Á³í
+À
+Ã×?Ñ_Ÿü·²Pv‘ä;Âb…OÖ%>[üïÝ͇Ȣ!B„°¿·>iéZcê‡KËÆÐq’íÝ.Of €»âúá1^kvÁ“ˆÐT`Å«¦Øì "tå®òkf’ªôoþ{ø/ÙS‹!B„N at TôOõ½(4 ò¤ùR´ö¼boÓªi¶¼Œl¬xÛ
+ŲæÉz›_üÀ˜öÑ'»>Â_GdQ‹!B„N°ôúù
+‘Û©¥´çxCåX¬9%ývþ—µ¡ÏšØÙµ¬õúéŠPK‡'Dˁò(’Nø°«I×þ<‘E-B„N ­Îwµ-AÅÊáUœ=Õwö½.4¤¼üüß3ºYÔ"Dˆáo@Ÿ¼ú( =eÃ)‘@‘"DˆpÆYÔ"Dˆ!ÂÃiå~”ýGox*²ŸaH¢Ó£þQ„3ŒeP¤ÆH"ô™ÀéUO  æ”
+#œ®㿤VEÅE!uzTÄqæÅZAò—W=¼« „hJÝ;‘†È/Ç™†À¢÷—†ÿ<9ÖoÞ5´    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_unpack.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_unpack.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mpm_pack_unpack.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,301 @@
+‰PNG
+
+   
+IHDR  ´     *91ð   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìwXTÇ×Ç¿sïݾKi"
+ˆ(ööލQcLŒ&ñ—Þ5–$ÆDcbL11jb½;ö®X •"é½,Ûwçýc	*(,–ûy`ê™eÙsgæ h`¥•¿ ´зšò` ]«) ¨šò± |«)@ãjÊß`S¥LQV.¬RÞÀ´jÆð0±šò †WSÞÉku­RÆÖáZÇ7ÐZ}ª)­ÖX‡k
+¬¦||=¯õµjÆö©Ãµvj µ²UÊ]h­Ãëp­Š*å6Xkp5å}ëp­`­ƒ«)ïú¸k€ Ü«i,­º ²r9 Y5åV $Õ”Û USn@PM¹}5/SVNª”s ì«CÀ¶šr1 ë'a­eÔÕZmª)·ÄZ…Õ”Û=åk7ÀZíêy­ÒZkÕ1
+´Vë:\+S¥œµÀZåÕ”+êp­\¬ÕªšrÙ㮕 C)Uƒ‡‡‡‡‡ç)ƒ¢ ЉTÒÈ<<<<<<O„)€¼Bãááááy&`Z žº€Wh<<<<<Ï!d,!Ħ¡ááááááy8 7<Ô‘"‹Å)µ"õ/ÏýÐ2%zªR¥4´<<<<O
+„k ½9JiLMû°V.r¯ —tNdªOáxª'¿(Q"hh9xxxxž0´ b¸Úöòl3Fåèîo¨xBÔ™Ò”ˆZÿÍxxxxže(¥ ‘ü‡#Ï}!„`ŽÂR'PJêj¬ªð
+‡‡‡‡çAì†	]úË*^§rÖ´ êO¡B^ðo}jMž§¡¨ý‰îqÆ0&S&g²®DªÀI õ;O=A±0ˆ£”Þmhaxxxž]!ý¸®lCò£¡ÄŸ§¡”F5´,õD)€ur‡vqÛ‡s’¯ú¿¶þ¬Â¡© nÿÅ.ñúŽÖ¾Ý¦^óíúZqMƹ¶¾SÜ•#ÆϏYuàç~]Œ:µdøgçNfFsÇÿš0\S’Ó.°ï‡?µê÷q^u}Ó¢B@ujÚ)¶ó˜Òe-gÿy³ifüù.ã¾¼µé~mnŸ\f{óÄ/^ú&öG™#')TèèÙᱶï<<O¡~–=›r%
+-ÈóÊÖ[zA|žþTCËQ_PJu ’êD¡¥Ü<0¤´0ýóãMxkäÌKG à江ÞÒ(ó¦DÛ^ôíúZhMÆ)ÎŽµÕ(óúXÅr"-5 8³azUaz÷€?y)ª®oRØîJrßJ¬C
+3¢^9÷·bÊÒü‘µ]+YV¨z`NdbXÁ#Óî_ÚçìЏwç•Ïó‚­˜Ñwk"*mh9žWöEé
+-ƒ%¨3+GHv¤8'a<€#ª¢tV§.îÉ
+D×Êëµ¥ùÌ‘?FôReúûtš¸£ý°¯³ À W“ýK‚¨K²d¶îíYDG©‰9¹z²oaFÔ4F›“ÚåØŠqíڏøfŸgÐÈR س°Ó Ǧ#Í}Ä·&.Lþ Ö~h{øÐoƒÛz÷àU 8ôë EYwººù÷Ý×ýå‰åóœøk¢_VÂÅáË•tùÝV 60œP
+ Ø‘eúÂ̘Ž„aµ/Lüc‹«o°†ˆM••^ì¥
+Š‡¾Ã
+ÄÅ=^^¹ßѳƒîÒÎOÝ2ã΀R¢.Ép÷ï·»ûË+,íÛ”Z_õÒ[¬@\0î«Ûý6¸}aFT0¥F‘½{Ðþoï««¿O}Bõ”ļZ2ZŸC[³r’ìñ¥t“¼5× ù5BÈ›„ûLjJ(5Z…YìplÅ‹=…bÅy€Ëë·}é÷§2?¥‹Xnwëø/›CVŒk	 [fû,*-¸ÛSjåQ~ûÝòöé·ÛfF¿àФ}ÉîrBq‚­kÀ5¦¸ièÞ9# 3þ¼¨ 3êk7¿>¹•e	;¼Ð‘
+.b™}	 üó™ë‘ýž¡‰7v~³ÿ§Þ/ ÀæÙ^¥EûØÊÑû¬Pb}7?ý–,7åz“’ÜÄ‘ P”Ó#ãΙe¬P’O©Iptùè} ›rÝF™Ÿ2 .íüÔíü–÷vÄŠlj2
+þ:p ä¥\oRvë'MIŽ¯XîºesNR¨Ð¡I»d¢±rò¹lëpýÚþùNÙ	—¾²qö;eëpÄhЊ÷oÁÃÃÃc)n(þL}Çø« IÚ㨸·•«©ž6HˆDÀ ÕãÕ©µËîès)ÊŽ}ɹY÷måå©‘G%F½6`âÂäoGμtDfã¶:7ùê ƒ^MZe÷!Ÿ;âó!2[÷-UÇìó~>'§sBÙÝ~on¿Õ¤õðªÂ´‰ p~ÓÛCbʼnòÝšA[Úgí6ǯXpC¢pú;xꆘÌøó"ƒ®´³[àaV ÑHfF miþˆÎc—|4äÃcG}quù®±2œHv~ìÜðíãçǬ"SxrÍ”æ•ë“ÃöJ¬NKN™r;XP*8³aº 0¬ é¥oã5ëÊN(¹riçg:þ>€®Ãˆ7ú¾±í¶NU ¢Ô$×k•ŠöÃç‡~ÿÈåºø[ððððÔ7Gt6úlÓ$ÛAÂi-vZ­ößl5Ú¤¥¾	Ÿ—v´¤„{BÈ4†RšG)­“PVmÏÞ§.É~ÑdÔ;÷~}ctyyüÕ­®„asÊ+S:•Wâµr¢³qö3 €TÑè¡—Ý^ú-™0láÑ?G·RܝèìóÂúò:N$;þêÏ…}<‡P+s¦„YìsîïÆ”RQaft×ÂÌè®FƒÖF,w¼”ró€”R“¸Yçɼ¨æ„ÒÔòŸYNt·(+¦iåz½¦ÄÏdÐ5*_$³¡ÔD €á„ÉåíVP¨×–ü'«A——ÞuiÞëƒâœøÁ~î²û»öCöðððð<	äý«ë<U bOVÇI¬&ÞØ΢ø·Nó¡ùt˜P"µvÞhãì÷kåòž¯üO©É&òôr (Ήï#µv>Þ¬óäBå•=_¸ @Qvì5™ÇÊÑgCƝÓs@©°ïô­‘Uëû¾±í¶Dî¸îÖ‰_?ì9eu!lß¯o}iAܲ—Ä-ëûƶ]CT,'ºsôÏÑ­4—VUØÍ W“’ÜDΠSµmÙçý•ëM÷ƒ0šò±GͺòG‡ß$=hL†asÓcNZ@af47à{Â^^œþ‰«_ïwKò’^ªÉkÀÃÃÃÓÐ
+MDˆd±'[aàÆHqǤ†³%å ”(¥Yuúêů£WWWnÓÈ÷ûÐ=³×†îc`Yaj«~Ÿ [·–?Fž^þwÔ™*†ár«ë[•þ3v…lç÷ÂÞóûûµé8zÑêÓë_?{eÏËì-ˆù駈¥J2±Ìîäøob—7òê²$3öÌgë?v¤”šD^mÇ~^uBÕÆÏ\÷S€•X9oôé0¡$'ñJÅN«÷ëOíû±Çë>²ßÉ0lžÉhpm3xö”É/µqÛväû?#B–d+½öfFȲÂd“É`oëÒbyM^žêÑ(³úšÆëd‚®©Á&È…KŸ×[vóA}6„i<&‰S @©£ìŒ½%= ÀIΔŒÅutZBö§
+ÂLÜSh‚‚º¹Æªµ< ¤ 4”Ò¦„!„eNMýz¿¶½ðq¢íÇ…nVøt˜pÏ1Ÿª(M‹:.}Øñ_9±—6(ÎoyçPß7¶÷soÑ¿ÆÖ4a‡::x´SVí~d±ƒ}ã Òªå›¿hú	'’eöš²f›º$›ór_sþÂÌh..t³}ÐÀ™Ùœ@Bk* ¤Çœß½}Ø®ì~í¾DY!½vøGN[œý v<<O„ßö•OšÑYòÿÑúà«ã¥­Bâu~t‘\rÄx:QïþÓ`ù}]‡&ï%¹ï$êð d+M–¿æ½¿ Ÿ|gZ±I±1LÓuÑ ù¾±-EäÛú$ðùa¥bÕUõ*JiDmûB¤Î“„žÞË­ŒUëâ?Rv*:­_çó»¼½Ug³+SX×Â}Bgf_‹]VUnkL¦Ìí—•Æâ0͝G_Ƀá L†Ù0Ä"o¶ªÊ ¤Ö®Æš*³=‹:,ÌŠy_aßôçÚ(3 8+§ºòÖ>{àΰÌ_ì>c6Î~†êŒJj‚«o°ÆÕ7øÊŒ‡‡§fœNÔ5 
+(N€þ¢Œòº8ãŸWÔm‹4&éK­ÄaÓÚK?<PÒI­§âžŒõ¶c³õ—_b	1½ÑA’  y*“dû-¿\Dô»nkšk©8!ßè|é-»¿]T5ß©
+l$gŠÞï*½ÞÕC,^ç¸%\ã—¯¦Ò¥ÑöÅ–âv“Æ ÀœeÐɽ¯Æ@…ý|„·
+_o˜W©np{Or£øœ¾ c¥¦‡UgÁÁŒêÆ&mjՍ;eI9!€€°€Æ’“?#g^:à°%æšð]⏖˜‡‡ç‡ËRšä°ÐCópÑ­_.¨ú]HÑ7æ+Š™ÒVœ Eʽ·¿dä_£¬v6¶fÔ£7éä.È]:Dqy_´¶Ãéi¶; ó­|¬Èlƒ<4Uï5¶¥øF¶Ò$Ù©íöÓ`Å–±¢“»#µnÃ5þg½çbŠÞaÚîâÑ‘ïÛÿ•Sjï‰ÒvýqbkAÎÄ­E£½ìØâ '®è@Œ®Õ…7mÿqÄ™mxꝝެNêÏ}Wnø!¼Wá0£’v80[Ü?–ÆYX; cJ©êaǍ<<<<µ…Ò•rÀ–Å>c>ì&96Õvµ‡5[ðËEU6Ëò_1Qàïkjo©€h6†k|Q‰9¢[}Mí_Ý:ü’÷ú´Ý%Cº5ƾÝYr šØ°é“ƒÄ)1íÔ6Ü\t³¹[:¥­8YÄÝŽ- 8+˜œWÛŠ“|ØÒþÍ„·öFi›¹Y1Š^ÝYÜ{û-{ËFÏF(0ßuŠ_{²ûí'¶þ¶Ä( °Ï‡ÆÃÃSgBšxÀt eÅ_:HwKÊácϪÊîÍB[ü’7mw¤ÖMk œ­„”ôñ¦ @oaŠ·[­R2Dû}û¿«–ÛI˜Šöe¸JŠš! z `Éÿ•à˜Œ&01]{Ûnõ—ÕÍ~¿¤î¼9B«Ü3ÉÚ"§Mõë;’d ÉmXO”mÊTuj¶ÏÃÃóüAq$„¼K‰àS Ž  > pÚ’ò,9§ò»•e>Î;¯sP騸[Aî[%wì¥D3&@”Ö֕˲0q¨„#Ú¸<£´6ó÷Ý9£m™Rh”l½©qW驸‡§  R‹.»#µ®©EFqHœ®ÅpQl\žQš\h”|ò‚4zaù‰»…FÇúXÿóWöª¨®œ«yxxž}! Ãü@G &˜-¦ËÑØE)ý•ÒÃ’²å”š¤SvÔ¨Ð͊͝ÙSvÈYÎh`ñ@ù¿KÏ«:~p@é$õü>²-œ |»³ää[{‹8ȘâåÃg¼íÙÿypMS[¦Â€ìÅ@qjbñæø-E#eLñoÃ{ÊëZ8rñ…ªÛ.8i²ÕBtcTQÚ¹d½ý'‡JèŒ8HIÑ—½eÇ,óŠ<?p FØ
+]Øòðð<B ½ ¼	`Ì;°êŒ Lµ˜p•X4@~}Ñ Tk=8Â_”QÙ걜w»Hcßí"-ÿý۪ܶ¶ì+Êì+ª°df0«§ìö¬ž²ÛUÛŠ8L±Ù_¹¬‡§ ïÊ»û¦¥âyt! kŽRú×C[—wR©L—ÿ™n[rñ< 
+JˆN× Q¬yž_!V >ð  fÖûQ
+` ¥ô©±ž®KäB¢·—2Ï„ÁÇS„5€±µ1
+1(•Y)Jå#¹ZñÔ¼E*E¡”BæXÀ¿ì«=€  > *'£VC)m0†f˜Ÿ(s˜Ÿ(³¡åxž ”æXQc…F)5Bø§žç2+²„²¯„Î 6ˆàWÖL	`¥”¿âij¬Ð!VB¹sc€ã-#Ò‚Ô ©mÈÃS”Ý£Íð.€· Ì-«Ò 8K)m$ f+GO é”Ò†v k®í°y
+t’ˆØ%¿±£AçñðBÜüóZ;Ji!dÌÇàÙ ^lHùxx8 ]ÂCb–ãпFíxêžÔÈÓÿ	ÊÃc	!£ ü	à˜M„[ V05ö§”*RFžçBˆ €3G)åÍHyxxª¥Ìßl)€~ FPJ/Uªö‡y·6™Ró qL 1ðæL
+}°Uê³€@0úŠ‡‡§Z!­ l†9úGJiq•&¾ RJ÷ü§sN$h•'´µŠÄÁSw¨tÏöî™RZ `=¯Ðxxxþ!ä] ó |L)]Ÿf) ÖÕ`¸ð“	zKG_çù/UHž9x…ÆÃÃS!ÄÀ N ºPJ靖(¥Çk8,ÞòIà‰· „0•³¿BĵqÐç!- $<¯^ý<<<f!}¬…Ù’q.¥T_ãŠÅÖ6öÞݬÄ{>^l‘—r™-̾SŒ'_©}A¹I)ÝK`ÌñBkó9xê)ÉgfüyQuåÎÞÝ´õ1_}P˜ÍEŸÿ»‘_·×³lœýêäŸòЯƒ:x‰~§ .ÆãáyTÊ,ľ0À”Zì¼jŒ}ã¶êöCfñˆ]ß´yZ"ûà{BÈ nÂœ­á¡BD <9Jéîú’,úì*ëË»>ß &“Á a. ºMü}‚O‡	OÔ<3þ¼(dù¨e“Ìž^^öÏg®‹z/Ã
+²¢Ï®òvòì8{ðG/=hœš›rí
+²" ø«;Ï£R–¿l€ A”Ò܇táá©O\ 4ƒ9åPk˜3Q×$Œ˜@`½Þ¡ùuŸ^ä×}úP Ø<ÛëCPÊNø.ñÇ«ÿ~ÙH™—$>½nj#UQ†í ÷…ÿk‚¿2/Ùͯûô+¾]_+€”›¤Ia{œöM”é1'}zLþëŠÂ¡©0ïš.nû°N]dã00¼ÝÐyÙç6Îðtðh[pc§¯K at zçqK²b\K;·ÀìvCçe@jäQIüÕ­®6|‹’Âö´‘Ù5N3è5í/ÚVbÕ¨HS’£0ê5þS–æ+#')´"={af4waëûí:ŒXpÃѳƒ ÎmœáÙÈ»k^µm>Rk×Âî/¯H,ooЫÉÑßGt²sä#}ð48„) ~ð5¥tYCËÃót¢M5
+2Wkš™46ýNö˜Ã
+ ð?Jé]Bˆ7ÌA±?{X'Ji!€
+bwéŸñZUA†&I¬>òû0CnÊõ9¡4åÒŽOÞ¸yl鎱ó"¶E]Õ<ãÎÉe+Še¢”Ú,3çF‰µ³qï÷]÷
+¥6'êã®lôl7tުİݟÆ_ÝÚ˜JÃs’BýÃv_œðmÂOIa{d§×¿¾ˆc2îœr>·*aÒ¢»_F]åyt%Ã	ã"y¸A¯‘ƒRQaftWuqf’³¬Édt8òÇÈ ÿÛ åŠkϢ΋sâ&ÄV×þ:è#{÷V¿ýèÄùÄ°ÝŸÆ_ÛæÈ	$±ý…æé1'ÿæΟ·O.³½ºoÞ?œPz=÷îu/“Qߤ!^{Bˆ5€å ZèM)½ÙÀ"ñ<¥Ü™V2@føZÂ@Èz>Îx”ÒU„6„î v ØX›þ
+fåÈ°\úä2ß©Tt#tïç̸ó·òÓ"Þ°
+ (¥²ñó£_ÉìL>uþý̆é<ƒFFSj·èñÖºÖ>»çˆD ¶º0qaÒ"UQ:»užÿ¹’ÜÄ_oü¶'”FLZt÷+ XûõÙ¸ÐÍ?šÇ7ڍšu¥‡Â¡©!5ò¨äØŠqŸ¾´ ®âiuÇüV?gÜ9½xÍûVb¹Ã†N£¿_åÕnœ²(;vjëþŸ¼4pVΙ
+Ó½’Ã÷}à< ˆ¤¶g^Z·,ìðBǰË7ø3úüßÁ±ÕÙ‰“iKó™M³šü'‡O}Céó‡Äa (¥|:"žGÆ~¤0ÔaŒ¨gÞ¿ÚÖÊk†¯w<BÈ8˜)¥›!xµ¦ý9BH{ ‘”RÕã
+S„RÛÐòŸO¯Ý;)lÏ"–%±œ(ËdДױœ(B$³3 +§¨K²š¿s1êìÊ•7-Üväûb¶?
+ù ä" H¬œ" @jíjdX.íÊž/š©Š3;‰åŽ7þLñ­¨Ó¶+œòXNV~ŒYcçEl°õâ¶Ç^þç»Ð=³'qBé£A²ôûˆ¥  BH…‘‹ÜÎã 
+œ•sãàwN  )Éi+µq½  "™‰á„·êâuäá©	eA…¿ ð€·jâÍÃó0쇊ò ïß:³ñ{ÀÇ0…µt÷à ØãÞ|F¦B‰¤F†¼¬°k²qôœë{Žþ9ºUjäÑ7*5¥Õõ/W4!+ƵL‹
+ù@ Ð”ä´ pP[šÏP£ÁµÝÐ/cOü=éšF™Ó
+æÌÜ0´-šuz9ìnäÑÆ ¤Â4Yn硧@E6mi>S®L»¼¸ôîÝ[‡Néµ%>CT,+Œöë>mvÇ‘ßý'û-!ä?2‹åöaš’œ  
+z51tþµ{Åž!B ®
+-ÇsHöýJ+6¡,¨°E%{ ™ñçE¶Îþúòÿ3À|O-–;˜ô Y•}?öèÕqÔ‹b™½ñÌúi=†vî`¾'¿~à›Î
+{Ïô੪
+ÏUn‰]UŽÚ²çû.ý‡~t"„HªýÌ€—woÝÿ“kC,ºxŠøÀ Ü!sê3W¥,D›/G)=RŸÒÕ‰ÂñFInâë[æø4Ö©‹ÚúJ„ü9&0+áâd¡Äæ¶NSÔB Vœ/¯Ó©‹zmšÕDhЩü…RÛ}6Î~†Vý?9q~ÓÛolœÙø+£^Û„Ê.ùuŸ^t7òhãÊãÚ8ûXV´ñs÷b…Ó5 (ÍO/”X_0õ¶:uÑ@Ï ‘S ÀÊÑkeÔ™¿%\Ýv
+ c2¤&-ºŸÌÍ:¿ròúÁ¯ošÕD`Ы½AžÙŒ¶
+ënÜòÖqCò¼Pk0†è—HªZG
+ó}YEPa‹w_®íŸï~äûë"©íšIߧέT*’Úlšô}Ú¬šŽ•Ÿzsvf왉6Îþª¢ìØq N À±•ã÷I»Ä
+Ǽûõ=øsÿ–Ý ”
+VÖ¢×Œ™í‡}]ëLÆÅÙq:õ±)´¢¬˜aÙIWî<ŠBÛþUÀd¡Ä:cÄçžÙ|s”Òc„L˜ýÏÎPJ/Ö°« €«ÅîКÚN©‰ €gÛÑ;YNT9~ôìkûNü=éNQv¬wЀÏ×'†ín Í:MŠˆdJ³õˆÍ…£¦iÛ±ù¶¼·K]’åîÚ¬çšÞÓ6E—·±soµ˜šŒ¬ÂÁkGðkëî €O‡	%>&9ðs¿.ÖNÍÓ_˜ø{rÙø‰,+¸'ÓÄïïN8³~š/(Eïi›¢ÿ5!º03ÆO!³½ÚyÜOßÙ»·ÖÀ¨/®îÏI
+=z~Ë»Á„0Æ=g\€ÆviÞ³âŸÁ¹Y÷i ЪßÇy>'
+ùslo[×€-F½FÐ8ppzÝ¿Ò
+À‰x-[ÌQ?ù»Ò ×7$±æB™ë4M$ÍÙbë.‚zóýË\¯i"oÃåË9‹=°$ÌTJ
+q¯tÙëÏ úN)½l)yjaØ4½®´C^j¸ÀÞ½µ>öò†±¬@|+‹ª(=µnj»V}?ºéÞ¢ŝ_In"wzýë¬øÿwjÚQãâÛë7 Øû}×¾ å¬ù^Š­ÔáG;”ß¹Ç^ڠȈ=ãØcòª ˜²4( lšå17öÒ†‰í‡}½´|Ì#¿kÓ¸åàÄ=gV–ëäêɾ%ùÉ.­ú~ê4²Ô¥Y%"™)3þ¼(êÌÊ&
+Ï¢¬¸sÞ}ßØ~©|ççæ×çï&C+Þ1ÖX%^ßé3ðý;‘?Ç¿{ýÀ7í¼Ú»Ý¢çŒÂÔÈ£mi~;ƒ®4ãð²¡ù~/L‹ñYzâïI~ÅÙqM­ýâË?ïžF!® zT*JЄ"­‰_dYœÑƒSh•Mè;ùá?G½_ß
+  üºO¿
+ ^íÆ)½Ú«x³vÿKJùÏ÷ócÖ0äãSgª«+¿g+Ç3hd©gÐÈèÊeœ@BËd ô™¶9
+ at Tuã9zvЍœyéžn¯W×ÆVþ}л+þ9¥Ö®ÆŸ_©n¬g	“Ž
+ ÔI”‰š õã
+1yhjâP½P_
+íæÈ¢R_6;{«¦¥ÃQ”ë’„ú˜çaBZÃTø:ª*üAL"‰Íñ3ë§õõEè2w¨ÔªÑ½¦¤ ùcdPfìéob«óÇW½4Onç±fÌÜ°§×MõI¼±ûw¡Dq.ìÈâw)5: @ZÔqiêíÃèQZ˜Ú™R“õVU    IDAT¬03º«@$ϼ{ûpp럽
+ W÷Í›Á°‚B ++KÃ0‚bƒAã '×Li~÷息9‘<<+ñ²Ï­ã¿\|q~ôßa‡:†ýqˉX85tïWÏ ‘›R£BÖªŠÒ;Þ¹°Ö-)l÷–&²BiÔæ9ÞsýºNÞyÜ’Ô”›~ÉìÞqô쐲ù‹¦Ÿtªf¬P¿î#û/‚|þVëŸå¦F…¬ÏŒ;Ê
+D)WvÏšŸ¾w–»¿x£QçN©QZ˜]š“|5ýܦ·ç ‘<.=æDg _ZôOW·0 Ä Z   -€\ 5vô¦b9:z´[íÒ¼grCËñ¼Bi`‰!XìŽ {»Æ_Ñ–+HY¬i®×»ÕrÖDÕr»uˆ&É(¹ó^I0Ձ3S‰UGAÕƒÄÌ(îf( 2FÿZëSwÞ/élÝInÝMs睒>­öÛì'œùþ–êA”z«{Ö*$¦{va&@—m²Üc}¸äšÞ:é[Uç†Ph„÷`Î"ý¥tƒ¥ç·¼-áÚ¶o/šÁ	Ä1+,-¯ËM¾:Öº‘ï¯#g^:riûÇî1Ö¬ °3ýΩ¡2[·uã¾¼µ)üÈb‡kû¿þÿS“Ö#6Ä]ÞØá¥qËz5ùçS—woÿÅλý¸"miþÈ#¿RÞvÃ'–›L{j2Ùøtœ8 2îœoãâ¿jø§gO¨ŠÒÙm_ì7èÕ«ï\\7L$µ=QÙº*Ôdtî5m]°GàÕÖ¹ÍßLŽøwpçqK*”gµírº¨G¹ëö¯[¾saíÖ>[ NM;.ðö¿7v}Û.¢ ýöàÁïþê։߮
+%V‰eö¸}ò÷¶-½[ù„ÊÒäl×:foÐŒ7–ROj‚üöð¢w	É÷ßjU«´d”ÒT k	!+ Œ-·¾%„l¯Í8!¤;!DV›NO*ß=p­ª?e(»«IÐCèÂd[rnC•Pˆ¡Ä$y°AGmöR=åJoé+Õ~vý„±­Ûìc%æ8vëÔž¬‚èšýª8-tfK27¨=½ÉCÓVª;G½V<¤ÉLé…re ºl“èîÏ궕¿ÒÿTT–¡äºÞ†³"* P´iSŒ–5dGÙàe Ÿe /Lü=™R“4;ñòû¶®-·U®Ók•Ýüû†æS“Éà’sR¬×”´³ui ­|–KöÇ÷œ@BÅrÇm‘§~1äϱ½Y¡äZå°sC–ع¶ü ¢’¼DG Щ‹{fF¿¶þc§Õ;æ­b.7üÈŽeþVN>W4Ã
+bËïÉäöM"tê•ëoøµ£ÉdpZÿ±Óêõ;­Vg÷1uÖåõ½^] 2·£^[­Ïª“g‡¹w#~½öÛ£;¾œð yêVF’D.Ìš:ê€ù„^„PvjWS8 |džG†âào˜ïj >й¡ä‘·æ² @`Ï(U±F…:ÞhoÛ[˜
+ BW¶ ”×
+Îê£Câ—Ê Àˆ9gEb&Wkt±~A˜_Ûye\±¡„J@g”	œ˜Â‡õ©cz ¸…:*lIvMþ)ÉOž<àí}—ö,ìäQ^ΉdWÓ£O´Äd^Ùó…aØ,Wß`@$/ÌŠiàväéå6Ôd|¨e­÷é[oún«VUêФÝï•ëzNY îß%Ás².. 0P Vœ—Y»^9ëò¡Êmã®l¼X’“ÐÀ}•šÉhðN9)võ
+Ö(óï$Ö7*×ûv›zõâ¶K^Y’=µºþ¬ð¿†%êL&CElܲk—ñ!Kì¯ïŸ¿/òôòCUïùêÇq¢Çq¢ºŒ2³	æû³^ ®¢†Çe›²Ö¥ôB
+ÃóA™s6c1ÌGÑ N¡ZUl‚…‰é«Õ¬¹®¼¡oj×O˜à<E0·´‡Ç§²ë&5e‰¦ôUj/PÀa¤(ìÎÛÅ]}WXUXÎ
+mã$÷˜!¹ÇZ‘ÃÁ˜½]ãžD×Ôº³ÀÒGß{(¥Iž³Î=çú ÿñshÜf[füùï6Ïöj­Sö’Ûº¯€FÞ]÷§Ü<øËæ/š6Ñk•­	aîkÅXNëŸåF„,‰1´~ƒß;\­2öñɳë>²WîYÔy€K³›ïÞ:´pÓ¬&mX8G§.
+šüCæÛÞ^ÚwûÄomüÜݍÉR8$ÌÜ°•Ç!“lå‹+"ù-­º°w³N/¿Y¹Þ·ëkÅ×þýêäúV‹evç
+zu#‘ÔöΘ¹a;î'¿u£æ³.-ØüEÓF^í_ÜsaÍ7b©Ý“Q/'›kieVPJ)!ä"€»0gÙ¶GÍb9 ûLÝ¡ñXBˆÌ~M0§>ÌwfŸ Œ ª}µYê«\¢>ßÈH›±Ù[¨U1z‘,€Í`DTkÌå鳍ÂäE¥íÇŠ.±VPq6P9¿"
+M˜]Ò™°Ääòš(\¡·k2Kr‘cÚê–%×u2VF*ü XyÕlU×èó“ìPÚrMkis6Óa„0ÅR¯Iÿÿ¾“OžA#
+r“Cÿ“Ä»ý‹'•ùw¯ ÀÀwö_ÏK
+vnÓÿz´8ë/¿îÓ‹ ³YzÌÉWvÍöî8acaF”“gШ¡ÄŠº4ëù xwx)SU”9»òج@”.’ÙÞcEÙÈ»ëØÊ¿û÷xó]uq–´ç+ÇôêÑG–
+ë¬SÚ7m;f? ´öuVûa_;øË€NÚÒ<Gÿîož ŸîoH­] À°‚¤f^ž•p1 ÿÿö,-·Žvõëó…Wû³ `âÂäooŸ\fs~uO™­{d·	ËBËÆ™Vnú߬óä8Xñ= zïPh\èæ±w.¬maß8¨Äµy¯ŸŠ²îøÉí<nwyÅ=;ΧBÈ0 3`¾¾ €X K֏RZ
+à,¡ô¾.U'²rrkÓ´ÓË«øt'
+DÂ…UòÛW×—P•ênCÌOaa:€÷%ð`-òŒçlÀû¡Y¢‚^¥ßû$9LWF"±ñjÞë]AC¦I¹y at zaË{Ó4¥ùÆ|ptHyLÖúà̆é^‰7vý0姼1õ5GmÙõMÇÂì;±Š"už$ôô^nõX×SÆdÊÜ~Yi,ÓÜ×½€ò7€w5rU­vhª¢tã‰5ãle"ž:B]}ä”ú†ÒfSp7 Ò*ÕJ˜ïn(€B +,,Ïá„R“XîÛªÿ'ãêS™€{‹þÙÅ9ñ?ÕçÏ0' Ì+³n4P>(kzU8BÈ  (¥{zR*•Y1P>†¨<uE!DsòÇ0ß•‘jš©l±¤\<<µÁÕ7XSÕ¸£¾(óŸ=ÿð–<ÕP~´?®ì{"€š+4 Y j3MÀ¡V¢ñÔJ 1‹'„ô€92»;ÌwdE0;@Êñÿ1/KaΧU'™¼yxxž_(¥;ì|hÃ*B ºr”Òš&dc8D$·o"|xSžú@]œeЪ
+,RŠ sÀç¥ 
+ʾ
+Ì QYSÌfû<<<<!¤ÌÖÑÀÀJU·(¥ŸÔ`#€¼ZÝ¡F at D2;k ªô?×fF‹
+ê“–±É¡”ÞF•P:„_`~Ý 0æ]Û”R‹Åmäááyö(‹5ZoôçGè¯põ‘ÌöÛš_$ËÄ8áyåÄꉖŽ<qe^ûÁ0ç+š_©ê·†‘ˆ‡‡‡ç^x?´Çäàoýº4ïôÊ-ŸŽ“ŸÕt0 „Œð€®”ÒbBHÌÆ)<فoyžòϬŸÆÞðÔ+\Ù‡Õ1JéSïeÞ䥆½wWáôµOÇÉ
+ ´>!„¼ àw ýʈfã̉øxxˆFSTvûoÝð<±†[„ ~ÕTSJ#k:à&Ìf×
+Ê…íï6±skU˜¾§™ÂÁ+§ë¸ß’ îÊEVâ%;±ÜA“~çDÀ°Ïž €•#ƒœ}zÜ
+ìýQ [5¦Uëþ3£›tÐ姅®øª…_×i±	7v¸õœ¼¦"¥KÈÊQ­ƒ_ÛqaëÛޮ̓³î\^ßÒÙ§{|ÛAó²À W“Óë_m¡*JsöáÍ+Uw^W÷ÏuΈ9ÑÒ#pXxëþ3s*×Å_ݬH
+ßãÑçõ­·ëûõ²„_ ÛL¢”FTª*°ŠRjÑ Ä<Oe<ڐ§¾ÉyÂÿ_p¯1H9É ªÐ!Ö zs”ÒjÓ’[š¤»Þ‹ÝÔœJof']ñJ¹ùoøKó“Æ\\Ý&/5l>Ã
+’…bë«7OüvøÛ5œP–¾ùíS¿]i~ââüôˆî!+GMœømêÌ#ˇ~Åp¢l±Â)*9|÷º´öú¸ù÷WŸX3Á?3îÌN –|óßÉ7÷	8¡,"ïîõ¶	W7ï;7jõ±•£;dÜÁ
+$iw~8ã扥›Fͼ¾Ë W“-s=ÿ`J¬nDŸ_ÔºÿÌË忼ë÷;—ÖüîàÑî¾Y«Ÿ&Ê>ˆøœRZ5Cn€…–—Šç)¤ÑÐæ¢Wš90Oex®g,%nŠÐlF5ÍŸ ²®¦¼¦WZ 1OÔ™6'’]›ðMÊW½šlœår>'9t	 Pj’½¼({
+ ìü®Õ¡ÄæÔø¯ãÒªò™-ó¼.䧅/ýEÄ[æ6Y¿é·%&£ÎeôásER;“Pb}ðÒîOFŒñØ’n’ÌÖ½"­†XæpxܼèUÉ{d§7¼zÀêoºàJè¾/\²âÏEdF½`×ñ¿Æ¶#„&-Ì|£ªÜé·Zߍ<4Å#`ðG½¦üóÔ=–E®Þ`
+¥t}5MŽSJMÕ”óðü9Cæö–5´Ï+Ë/©íZ†ðX;´2KëÈ'J¡‰e€9wË	ãoú& ì÷Š`¢eng+¯}  ’Ú™XVwuÿ¼€þoî
+³s
+ü3;éò6×æÁÃDRsÊóƃÿI¸¾mYFì©=:MIŸ^S6,(Kaï MZ,ˆþú¡ùNÅ9q¶woü†åDI,'Ê1´- 03º»Pj[m„î’¼¤™r»ÆKžeÆØ
+ ŒRº º6¼2ãáá©K(¥w |õ¸ã<QÇ ÚÒ¼å?›:¯À>E ©ˆ½&–Ù…ªŠ3[æû.£QïݺßgQÉ{d¹w¯Ï—Ù6ž—•pa~~Z¸  º½´<	„)9µ~ÊçB±â˜K³^>SÊüä  H‹:*¥¢¶ƒæegÜ99ÙÊÁ{ÝÄoÓ>³qnqe¯‘•£ÏEª°Mur;zvüŸª(㎋;©®þ)ãw˜×<£¡áááy²1™ØìMšFTO«‰Wk!~„u„(BH!dymú3„W!¶u!Ìã¢×–tÙ2·Éœf:­H¬B*+Ÿr¼ÛM8ªUåÜ2×sö–9D냍¼ºiÏm™ñÔÊy㸹Q%6Ǐ,6§¼•ƒ×miÞ.̓ÿ©<–º$gè–yM?;±vâ:±¢Ñ?  ’9„çÄ¿¾í+Ÿ÷r’CßFYÔÞS7_¡&ƒÍÆY.Ëv,hñ궯›W¤½(œ
+º¾¸lRq^Âk»µ]o/P=C™ €ùPV<<<â֐¢#ú]NûY½=ì…“7ͪÅö€O еŒàÁ8	<!‡­ùÿÌ°ÔÚegï×6G€w‡‰áÙ	+Ò«
+œÝ²ÏGƒ,ÒÍÑ£ýÚŽ#§å§…ìÝZoøöáË 0òóÐ_N¬žÐQ«ÊgDR;“ÔÚ%½8'þr¯WÖßc ãìÓýkuI¶“ƒGÛ­åV•£gÝØqbÍ„Û%¹	MƒÎ^›xcGsÀ|¼ùò÷9“N¯ŸÒ<?="УåÐ póë;ߧýÄ”Æ-‡¨Ä2ûÉ7OüÔÊ W“ò|FO„I Þ Ð…RúD¼xxxž\ŽL´Ëqû¡¢ü¬õ—ôßÕ›ã?,=ï³L~æ1†µ³"Ó°ªI§²MÙ ŽRÚ ¹µªƒÆ8ôƒS§+—ùu^ä×uú=Êœ@B‡¼wâ\ùïvn­õåÊ0+ŸAï¹ {¾o?¢8/áÍFM»Ì«:Ÿ@$Óö{ã|HÕò2e Í;¿vO2Àž¯¬»àN•¶  7ÿþj7ÿþ—ñ”A	†9‰^0¥´¦Ùayxxžc|×*”ÿÜèqFö?Ú3ê;ƾ G¡­``€U VÖ°_)€OŒQˆC“ö<Ú¥?¼eíH¬òšŽx¿²/ Ø»ýâî?à‰LˆhI!-aÎsö"¥4êaíyxžtŠµ”Û¡ñÈ)5I‚\¸ÜÍEYÌÂTzÊJ¤"yåÆ0G©žröRF;ÜO”.`&áÓ„2Ü 1™ºIý¸ZÇa¬B<€RJé1BÈq Î5éD)ÕHzbZÿ7÷Ö4ê­¨¼“«ÌàwC.ÖÇ|O„W˜Íóߧ”>ÎSÏÁÍLƒbäÆÂÉÝ=…·í¥Lé⳪Z9sÜ­ÙûÐnû{þÔ£¯Úüãaê`î1åÐ A¼	 ³*‡Ìì);új[q’Åñ”aTQ&áCåFBb|×)þ}Ìá ø (¥”² Àë5íüÄ(4ËR–?è €ß)¥[ZžgE¦Òd{"^'ìí-Ì­ïÉ~½¨jÝ«©ðæߣ­Î–U\˜(°þ†Æóò]½ë›%·‚\¸âí75î¥:*ýúDi{	£^2H~ æË.µuåŠ~<§ò[s]Ý~TQêOçU-Ø¼=QÚf‹*.Š9—žWp1½ßUe+aôJe.
+ôuäòÇëšNi#¾ìe^÷•T½Í¦pMóŒ“U;WAÚg=¤Oý‰ÕSr{DÑ“.ÍVȧÖÁÅ d Ôe.D‚Útæ!oØA)Í«I½¦X~ëäRG–åøm¸…`ãÃ[ÕBˆ æ$zç(¥|<FžZCp-ûr+ûÞ€WÙwW ö ØóɺìoúÊ6[B®vn‚Œ%çTý¾<^Z<±µ8Îׁ--¯ëýwÁG.£ScAú´ÝÅÿé+ñw⊄,Ñuñ¤6’3ÿ	˜Yb’[‹ˆ*_m¬¼¢îÛÉCp{L€(’RŠ.N}©•ø’Ú@¹N˦F~`¿²HC]U÷íà.ˆâ+Šùè rð[%çßì(‰Ÿ±·dØëí%ûù0)±yÆ;<ÉP=%·†mRÁÛûgÙTY Wi¤6ØL¹ 5€µéÌØs°Ù¡3d·Î±^Û’s¼Y· #£‘$KÑòÀÃ[ט•0ç2{¯Çäy!„p ¦ èÀfEå @
+@@sŽ<QÙWeŒ öj!Nõ¶cU–÷­Ž’x[	Ñ®½®i³æšº§Ÿ#—¼k’õþœR“0»Ôdûná% èÔX÷O˜ºÅÆ­O
+Xúû3ˏàõ]Å#LŒD í‚~òc `¤”Y7Æ꘵˜V…ª½š;°©óûÊÂàJªÞsû-{OaŽÞnåH«ã.
+Fk¢ b´¾ov”Ä«õT”­4I‡ú
+Ó†øŠžzã«[Ëg
+Mýäm¸99[´9[´à˜"YÒG§H) „ÐÀJiâBìŒâjº3«@HÇQÎ.Xf‘€Æú£ mM—çG}‘â¿Éné=×éV}É¢Ë1sþ-qub“LXb‘ª*^'JüÜ(„¾nÆ#„|À@o>âÏà”!ka~èms a
+³ó½ô~Ý`¶:{@"CðŸpqõÉø@qêø@qªRGÙÞ¼´âŠº™›£4™À×UJrÜW©,(?ÔÅC/šEŒ)S`-& ˆÉ5Ú9+˜Š€«‚)ˆÊ6ÚõðDŽT@Ô.
+F ÍØ¢5×L¶ °m‚õÖΪÚ\W8©—°ñEëõõXª§ÖDDâJ#¯–—q
+r³°ø±Æ5ûÀ^ªe·" »Ÿø;4FLL²æ¢í N—zc.êE¡_W[ß™™ÕÃqüεAÉCÛõ|ÜËO‹C™
+`ÌyÍ,òÄÌóôC)5Â|’³ƒÒÀg Fãÿwf•QÈ 0€RGieIY¯¥é­[9Š,¨\HŒ,£\Hôc[ŠÓ¾:^Šù}d×dŒ ÔzjŽ$"ªìR“¨òÍ^ÊèÊ•YuŒk)Šûß’!ÎM”„gšÎî%€R•Õ9õo&Ì>£óìà.H0˜@ü9庱V§M§½~Ì}G­§§$òÔ>T¶:f3³¡e(§L	æ=ñ
+ÍP`â²v5sªÈ¼>4y0gŨõ…F‰ÛÛçñÖ©©«ò½rö—4ceŒÎd0‡©Ê;ªtÊØTègÒSÖ¾Ÿ<Ñ¡¿"#òíô^­77IX˜ÓRäÊ•6~Ó.¾|mš^¬Ë3
++Ï+vhlEÈ­Ü#J7§áŠhwìc‹Ã4Š¯«­­ÚJžš€«„ ¾ЃRšó°ö<<÷!À-˜ ݪÔ)aŽ˜>¥¡˜6„i|Ä·m$gòK´TêjÅäMï ‰gð¿Î’“Ã6ŽqD¯ÒSqáíýäaÃýDá3ö–‘
+‰öô4Û5™§ScAA3—ÜiyþË&
+Ò£©0ª…§L+6‰­Å¤øËãÊÞsŽsDûçÅáÔb£xàšÂÉ®VL®Ö®¯0ìiVfO*!D
+@ó¤?QeE&	 hRôöN5ÝB”Üžžì<Þ:5s{q@û£žÿ*#µò[SR‡@Êïymü–ºœe¤Œñöëi}Ü^µMr®ˆ	›2€ˆÉçk#•çÈ9¬t)º¢r©\æ8D‘è4Ü*£ü÷Ò(­£ë+6‘  i"(*¼ rzZ!$Àz #)¥±kÏÃSBÐÀ› zØà˜/ìåeÍJÌ¢”.k!ËøyˆâÊÂþôê<£¼…#WRÙ‡ì½.ÒØ÷ºHc£rr7+Vc%2Î	–Ýš,«8ÙIøÄᏪã6µeÕ‘ØÿU¹ì¯ÑVg‹µô"Ç€Vöc²Dñ-»-I…F‰g¥]ßÍ÷ìWEæÍíY%¯ÌêÀd˜jw—Ö Øb« £Ò$6–š*â|Éš	KIفæ®Þ!iin  H¼y&eìûÉ3ç7~Ëîü£Ì-i"(T'ëå r´¹]°ü©pÊ&„x øÀ[”ÒçÞ÷Ž§æBœ`Ž­7æ;Š?¼F)UBvÀ|‡¦ƒÙÔz(¥ô‰ˆ’#Skgî¾y´ü¹:íV®«£²2 ú ¹xB@ÌXԕɁeaeŒ‘cþ	¥cÑ55˜ÏÄå-Å©Vm%YN#­ÒŠ¯ªmŽ˜"ßJn±Üõß„Ù]íûÉÓå-Dojǁòë’{ºØUp	ªmYzò¯yíe¾¢¢Òm#ÛÒ–Yå£S–Öü€Å”ÒÝ
+-Ï“OÙn,æÝX?˜Ý;^¢”^­Ô¦€0'U0œRZï>fO.
+FsøU›
+oÉSÇØË•…©†Êjs
+¹3(µé.MÔæ8Û`Ylù¼å?û|ßèôÝßó%‚"ÇኛÚ\ç½ÀéRÖÖ"ÏÈÿ¥¿ g‚…Éa˜"ZÖRTèõ¥ÓÙ¼“ÊF§J‘DÄ t½×
+ÁŠÊk”·¸½a{=cSa3ß_]BtÆZE~TÅô‘Rü”ù	íp˜Rú[ÝJÅó¬Aq ð*̪U0'N£”–TÓüm˜Ow~†9£9|VCÌÇ“
+-ÇsH€
+µVJT
+MîSvEEñÔ $7âg”¿W*~.%PœÖ”=þ½8B q„öuƒ¤+™ÛÂÌøSòž#¥€"%í[ ˹á™òdµñ—/{Ê^ æT<<ÕBéónl €= &?èè°Ì)Ì»²§ÎÒ—çÙ¤ì¡JUk…&·nÚ¼ÉÔS„y¢rƒ>Û4’ÂvU5~4ЗRÚ ]!‰7C`[a4ÀSÏP=%†”Òúl–9¡Ny7¦‡y7ö¥´&FN~0+3Þ¸ˆç‰ƒ+;Ï«MBÇœk+Æ:Ë´.oÉSd«¸#v£,Ùèƒ „Ì€ù~£¥T[ïÂ=@acÆÙw…åôYÑy½ƒ´9[,pdxŒ®Š2*@ ©[ÝqÚccRS¶4Êh%oÍFjÏX¥––Dî{Néónl0€} ¦RJkuL)½ùxRòðÔ€a0ßµÔØÊQ!0I¦·	½ì…
+ùù\­4ÑÊ‹jpÓI`ÌÊ,¿¾e«	"'Öbg³Úd­•¬Wú°93Vh܉ FÛ‚úãZ·‚1R6+ù«R—¦_ɏÛ
+f×Ç<Ua„ÿ^C±ð
+P­c€w(¥õ²vž† ,D›5G)ýë¡­«AÊ1T!bøËàzF©­ÙkLé à/ ƒ)¥Iõ*Ô
+Õƒ¥ÈÙ©uSÞ4Ø—\Ó»Ëü¹,ïÅòk0Iß•¶,¾¢÷àD#ä2 k³¦qî­¯ÔŸËöœY²9    IDAT-»y÷g•Ÿ<Ë³ë/ÌŽy«¸›÷ŠËœÕýM³«£ÝyÛ­ µQ㑱Nh7Px¼>Öû !/À¬Ä†ÁœUáMJéÙ÷ªJõT°ö†Æ¡!ææRKLµ¹®xZ±0ö‰Âóp!^0_èO¥”^khyÊ°øÝ™2Üà,oÍå©îl
+OéšîµÙ9¹¨ñ½:Á(WE[üc}4bháHY 2K#
+ò¬šV-wZJ˜]Ú6c­ºi£‰âÄ[cGfïàR…ÎŒ²²23i)1´pxå9	KŒ­ÛTk‘½CÛÂa¸0º¾×]…愐m0§ÝX	àÃZÇk­[
+÷Eiví»SØy	óEEVKQ¯”½ÇWð
+í)§ì‚ÿ€¯)¥u‘ÿ‘!„¼ h¸L¿6½„±œ51Èü¹ÌâPƒcé-ƒ£Ý QgEVI ½Uëm(¢Ò¨WŠ{›´à“ȍI°
+ÆdïÔvècOúwÂê4NqOWýcf”t•4eó\^“$Õ×ïC:€w)¥'-<ïý¸«5 Õ‚FÁ<Õó\¤ûâÚS!DóåþJéʇµ·€<. öè  3€1
+&‡{Žj­:pÅ¡zçWÄÉ¥‘›ž‚xûÁ”ÒÛ†F[­ÍéA””UÝ1Ê
+Oë›ÙöÜN˜£òZ ¿'“º6ÃtÏΓ°øÏ‘pìû%@@}~’‡ÖÇÚ‚’Rz¥æ½örÛÆΔ4´ Ï3¥©Y ,r—ېp„O éâ`ÍÓp”…zù@¥tvËB`¾¯ù	æpH¡ nÂÂ
+MìÁr6D'taK©Áü*rcJ„NDí0T”^t¡Ä=¬OÁ(¡3S$tfUVò6\zÄÐÂ!  &‹Ã
+Oé=¼³î,È¿=¡¨¯6Õ(¹›ð	ÚôKYăd0©)StQïÍYUX¿‚‘òV‚TŸ%ò«êó¬cãÀ´~“ùÔ@Ü:¿VQZÚÐbX@W˜¬žH…Vª3±Gb”n…jƒØÏIœßÕSúÀ;ZeDÜÿþ<Uâª1PÎVÌj{øȲØgç9q	Ìá^&6¤„ ›aαVÛo Lª˜ÿ)eçVÆZ-`”‹˜ÿ)ø?öî;>Š¢ÿøgv÷zÏ¥ÒHPEQAAl(*öîóØËcï"Š€*ˆté5
+é=—ëmïvç÷GH~‚ˆ’B˜÷ëåË8·»óK¼¹™ýPäÍ“a_扒ûC“Ùðü¤kK®-€|U¢ Žua€#ÕU󂨚TVþ·¢™~ශ7P.lüYò7ÅÑêBuRÇœ¨Rr4¾çèùùr:8°qn§n<üÀ¬@)]ÐÞÁKnuÀxï¢ÊË%jóL>ðáÆúA½bUËŒêc/Ëÿiñ5__×õ+“¦!‰ñ«kk/ì¯)Ë”emí÷³®¹¨»¡¢íZqòBîp€sÚëÎúð2هѐu]†
+`;¥t;!„óì	¿ïÙÃ&OÚ»bNGz #;ôÚüάa©ºì'GE7Ùìn|RàÇ}®®ÙÕÁè)ýLyÝ"•ÞeùîxHV½±®®ŸQÍî¹ înÝ–lQú>Ù\ŸùíngŸ³“´µ_ír¦%G(œkxS>/j |±Ý‘¡ˆtÍ™æ:%'¹ƒ’0o»3#Á¤pm)ñu™ÔÇ´¿_µ öVL¿äºSk=a}ßxMÅuÌG5 u\à4<kÖ.Û×Búø
+@<þ¼k±Àã@S*šN½²ŠaNgnuŸïÍ‘n "çÔä2–[›þ‘þ+ÁÄ7ÄÉvø¹Ê¹:UÏUÍÆ"_懛ê{”ØCšæ¯]· ô’Üš`TïXUõC‹«.ÚVâ·¤YUNGx at WmÅY‰šÊ#¯góJZ£š÷Ù|’rÞvÇ°_ó<éûé
+E‰òWÍ+¢ä‰ì	ÊÊ+>/™B)àôËŠùÛÖïw§÷í¢®š±¬zÔÏÙî xúךQÝ"•õã{ó„´†€ß~€™hت£´-êlŽ¢!„¼`€4 G'w Õuô"ÞDœÆ³„·ãnÑLÕöà¿I7Ü罨=cêÐwhWõ7²hùÀ{]=¿Úé8;#JUúÎÄø•å®Æ´ƒµ Ð/^U¼(Û•ùü˜˜?'“¢­ir€U¥”r	<82j= P
+òÒűëU‘¿ÙåLɈV•Þ6$" vVø×ôƤG)]aYæ_³Þ¨æÃÁVôt—e(ó‡e•Ý'i†§êª†¥êZ}h½¤KXô½††%Ù¹0¡5BF˜À@ÓÂ!4?2sH}ùÿ;ÅÞ¤.ß7Ö9 X, Ý!YhX)×!'”/ên¨¸¨»¡Â+ÊüõÊ&ü°×•¬Up¢LÁm*öu Žãhw«â˜ÊS££WeF«œ»Ä²‰:«–³7.)¬Í1z¡)¯_Œ^pÔÍéQJ—VÉùçì’#®%9.!À[—ÅÿøÙf{ï¿*;£_¼¦èù±1­ºy¦FUë­/~$ò¯kÍzŽtxOµ7ѐ>)Œ†Ž+@@	 q™
+
+0sšðf‡Õöebï>)3T/Ÿ¯?Cx©=ã d(Ðá:´Üê€1#Zíâ	 SrÏAÖ(¸Ð…Ýõïn´q÷
+·îÒ)Ækƒ‡—i딜Ïæ“”ÍïÐÌZ.xä–çÍ;^¡/zeuí‰b{X¢$¯&˜pÿˆÈm”ž ¬ÛY°œÑEm_È×µ_‚¦$,©V¥ç…‹c6…elºðÃC7H›Zs%¯Ðˆjmď³í6Ê>üœÛÕhØÄq
+ö²£aEãKhXÑh àðd{eög:—pÈOêJv(,çy%Jxʬ–,ËY®©Ø¿ÖÜwÔªUºˆ“2-ñÓ+ÃÎzÕ;ë­	};Ħ̵‚™Ž5¡çd‘¦
+f²$nº¦]v-'„¨ $y'ãö¹ÓÖTõŒÔñOPÖ$˜u—ô4”À5ýÍÜüuÙ8µÀ…¼¢¬:?CŸwëÙ¹£2ô9,®mPqþÙS~ý;õœ™ ±§Eªª&^2I¦ ç¤èò»˜þ2GHcÖ®Y«jFÈD«ä‚Ï^³¦ÂÒÜömùÄXƒP/†©bdš~_'z Éá»ö÷š—BÎ ð,€{ ¼s¸8€†¥ûó¯­ýì†å9+^ Y
+%Â9	ÇÛ	Ç9¦¾Vwm{Çw¤u_LO-Íþuê5/•> Žª<á§W†Í¦TÖs_Ÿ³öÝÌÃo›2h⬽ºº¾|ïUÖO²&ôíÉ¥“_Ðíp©ë¾ðïˇò<Õg¥ù‘vE w‡žC{ìü¨ŽˆÜYâéR­JOóNãÚ3Íמi.(²‹Ú½"ÐxvېˆÜƹ0 X}{êœ#¯›jUzÝ”üMó²çÇÆüáe^àˆ¬þ?k¹Š‡øÕÔÄEÕî°:Æ 4ÝÅþxcÒ‚Âú.É¢ð6?¾3#„$¢aXñV ; ðh‚|öD¶b˜¿rÁô¯s Œ€/þû¶Ö·fÒ;¿ß°àΤ|a(ÜõC
+Ç+ÂC®|=ý¼[û}ó€KŸÝŸ92  {W½áu”i¤P at pÕD¹û—¦¹ž²œåšK_@å°"cðÔí݇Mw®ž}M÷Ä>ãÊóÖÜ'匉9=GÞÕÔY„C~²òƒËûw8eúàëÜ ½æ‹»®P µ%;RBA·9ôöÿõqýÍ1™5åy«qœ`¿ö•ÊëÀç¬à¥P°éÓ«dïí¾5o÷:ÿ¦ÛïÜVϾ¦{ÚYW—ì]õFßøŒgŒ}¢)«‡£*OX?ÿö³“úŒËiÕ7þ_0Vx4iü"ïÞð£íQ?¥ÔàÛÝ¡€J 4=Ré9ÖëÉ¥ïdÕÕ8|Ù’æ (xB3¢ŽWgsx.m)€—)¥‹!4|+r˜Ý®Á1§…ß?P°í«.¼B}Б´jÙ»ãSüîêþ¯t®ø`Ò‘‰ýg^|ÿÊMû7Îé¶ßÂÊ"ÂñιDþgêÿê¦Ú¾P¿î‹é?©õ‘‹@)Éþí=s÷aÓ¿/Ù÷Ë¥ÙËœ
+•vﶟžz,wÃÇŸ]þäî…æßž\°íëw*ýæêÂ?ßñËóK'?›ÿqþÆ9Ã]µ‡îâE‰J±I–D¥’ÅQ•7$,úvr‚Ò/…ƒ©¿Í½©Ûˆ©³´¦ø¦Ï•ožê~SÀk¦P鳿z2ý¡”3&>4üº•ìû卲œåÕ‚BSP[¼í©âÝ?¿5áÑÍK×|z]fñžÅo)5†õ»–¾x'•¥ˆöü4Wü¬7+á?Ú<^Kdû2Ñì? ]ÁiH['ãþ“ß¡µ§³ÂÿóÍÉ_µwííðøô" ¿PJß J©›B¼J)õ·k€ÌiC¡6l½zfѬfEK~ÿêî¤Êý¿UÛ+s.°	 Çy®{µúV øì~ËÒm??c+ÙÏñBÅ€ñÏÍIxÕŸ6wÕYº|{ù“»nûùé˜}«ßš`aYÎòKµ¦¸/¯x&{^Ñ®Eºµs®_àãçЩ¯ÖÜ +>¼¢Wåþµý¦<ð áŽjÙ»—&nÿö‹ÂßJZSÜœq¬þœÔÔ箾bÒã;Æ"SÂ?Î2ª<wÅ f€12õ«	n^úË›²•îš`iÕÁ
+—è#ºÎ¾ü©=ßl_ülôîe³v¶âÛ{B«CwØ~v"<ì4„®œ–l‹›®~¨=c! äPJOڝÓyÎÓø€* Gþ±x»CbNc:s—¦áß_9Ì^¾÷N^¡>BÂᐿwãk
+¥®)	Ï+Jk·$ŽºýûmßÎè½yÃüÛoüúÞƒ	=F½rÞMóó ÀÚ¥Ï pÉŒê½+_©È_£ÎA±	}^€ä~¼ œç…& €B¥;f~Nsl÷ðäçö àƒÕŸ\ݽdßÒ·W|py‰Î’PI¥pì/jL$Nx…º¨ñ¼.Y£v€µk¿ÒÚ¢-] pŸÓmÈb 8sÜS5{V¼Úa’ô]k¾ËõGHïݶèûõ†
+o{ÇÄ°¢a.„aZ2
+A®oaãóí•­„9=q¼¢iuŸ½bßô¸Œ/\3«ì1µ>êÏw.äèíR…†NyþàÛ7¼á¡·tý±<wō¯ÕWìë	 »—½I_Ÿ92 P·9kôæ½@eÀ	Ï7,3&¤iµ¥JköQúÿ›h½õM	+λyAžB¥ÛðÚRMœ•O8Þyñý+núZ͍S_«™vÍK%3šBæø£cVëwÙ+s²c£²}bïXë2VxânÕ”¶wgv8éC?Rº¬=a:.Bȝh˜œJ)
+¶pÈÜ6‰aš(Ô†•Ößÿåã©Ù¡€«ÿñŽ_ôÒà‹¼ŽòÁ
+•¡0à­¦ÖE6íàí©/üåã©)¢ÏqŽÎÒe. ÄgŽü©pç÷ï~ùXr‚pT£ç	
+ÍQÎ)oÚ¾0rÁ#‰Oé#“×yíeg„ƒž,…Æ´3,úCψãŸ{ə֢,yýüÏT:ëZ9,šyAUå³yÇœƒŽI=û§Ò}¿¾ñåã©)¡€»!\‡XÝØ	 bØÓ"BÈx ¢¡3kñ¢Ãù¦ÕtíyÑ[–¸,; $öóvLêÙM	®záп¾}ñ™AŸÝÒýâ'?.Þós2 t8y×QÑ4$˜uák]{­PªÒîe/ûE¿3²Û€ÉÏ
+òvqã1©ý'=b+۝Ñmà”gM˜Y	 #¦Î.8þ¹‹W~4yxÞc?íwÑ£µ ÐmÀäßݶâ¦}ò…†^9#gÔ†/ïê©5Æ9/˜þÕúõóníã©/íf‰í±ñÜ>{¬q5ãäçöxhûÂù»–Í©PéóNxa3 ÄgŽ|(匉õ
+±\^çª9ø œó—¹ùkÆoþþáóÒκz~}ù¾ØÄÞÿiþi˜Ó°ŒüÝga	!f…Ê‘ÐK›¨	N|l˜•­ìpcw6•®°â©Uþ`‰ý…³2;èq–Û(¥­º[ !d06êC)ÝÑšu1!$2¡÷ظѷ,´µw,ÇòÙý–_{wÏõ.™Ñaæ§N¦ß>¾6¢`Ï5”Ò´Á'!D{2¹ÛûÆ•tX*¦\öµɵ+°ÿß\ç¯üã;´:Ÿ$(íâQOó3'W½_ ´4Ü×*ïoö=æÌXgÆtzÖ.}^ŒÏ8—Íw!d€”Ò¿=©Wâ¼³w†
+©ý˜Öfðn´Á¾„(4<kö$¥ôoeYa˜SÝ%ÿùí·öŽ99 '|ÙwÒœ/ª£'G™Ö‘`ÓÂû[õJBˆÀÏ PJÙƒÒÃü?+é¿Jð´ÿ»óÿ
+!D ¿@)Ýx"'ÊaQa¯Ü§%ëÐÚˆ ÒµêâB‡†\Œ¹”Ò§[³.†aN=ö¢è½Æóoï’BUÁVMª|Âsh^_ÉÀ}¥÷õ 9=òvr…ºDGz/mÅ*ÞBÃÎÓW´bÃœ‚'Ý8ØÞqü•ÃSfëO¸CãÔ”›¦PGŒÔµÉÒQÉ/óŽõ>«u´þ¸+tjvÇF]b¨j­X¼ûƒ:^ËIêE›­îôˆªÂ‡%5\­s}BÈœ`¥´ClIÁt2¢LªŠþP´w§« •;á^ -ëðÏ¡ÉʹvúÿV‡VüfÝ ¨K?¶F3jzûŠV*Q©H¸×œ„õÇ?«c#„Lp'€!‡Ÿã`˜“Î^³þöéͦöŽãô:mFÓBÈX (¥­tð/Q€†( û©êV†
+I÷[wûkœ®í~SÉÛ¶¾ª8EÓr ,¤.yÇ–vHê„["²U±Š@ñ›u=3fÅî¨þÎÕEòÊBüTsñ±+=Z·§£÷6þ¼yè¡Ë%¯Ìóºcgçïè!# ¼àüÖ~®9­Õ{íeŽö‚Ái‘A P Ã5IYpíÄØWû“»Owãs"½Z׿ς®k<^=,ë½øÕŽ-~«m¥' òÿ[5$å¿‘ÛUñŠ@ÎíçžñCâ2¢ÜG«Ïplñ%öÿ1iqó:
+_©ëáØàMj^3É”ÛR§gßà‹Œœÿï̲ |
+`
+¥4»½ãa:¯ÃÙdN‹S¦ýÞÎjˆ@)ÝuÜ£;e¬àˆ©«€ƒOT$¯ÌSD“ªôi’•¾’·m xó‚q%oÙú€”Y¤\úÌØ¿÷>pcÊÃQ«xýŸ;#Ë0m•*FøÓnÆ3ÔõGÖïÞ0<[3´÷œ.+Z¯•­‹`	€(¥kÛ9†a˜“A`ëðshÍîO´	¯ã$B É+ó®~3†&µ)ÊÚ´gc¶ª~É+óœ’È9·•érƒeSåG߸)¦’æZØ.)ƒU!móºÂnåŸæ”<ÙCþƒ•#{~Ôe…ªKÛ-
+9™‹YàJé‚öŽ‡aæd8¼s[‡ïÐ8‘4ÉŠz Ф(ëËîzgĶ=×”^ 0ó~}u ¤>µùàŒš3Ã.I­´
+Þ.7Yr9-J}<*[›¦t–¼gËHy(*·ñZ‘cÕ‘c™Ç­êW
+ˆ”wåp èñnüÚ¶\íøoB üA)u¼ã†aN5'œœXaT_ ëIº·r\L3r®XÇõúµ¾t»üO“B>	à2Jé);ÿÇ0s,!är +)¥k%’N—¼y@ï—~R(U§ÍRÐöÆ	*ºcɳ–z>!äi =ŒdÃ0• `/ ÿß=!,zME+©Uö dñ…!üØ
+ ö¸2
+Àu Î><ÎÌ0Ó©BL Î(¥ù'r"¥2Ÿ¬÷¥_ÕOÝJ¡1Gš¿+Hë|êÞÊ…r!€™ †SJO¸3d†9Eäÿ£E!„íßEý·ïê˜gþ® æDÏ!„ô0ÀJ道Ã0LÇ@)
+ Èiƒ]¶˜¶FIDÃV0·QJ7µw<Ã0muh!ÄŒ†M:_¦”þÐÞñ0ôŽ2•òWÐ1!D	`€¥”Ò·Û;†a˜¶$ XÀÓށ0ÿ!„ ø@5€ÿ¶s8Ã0mæðMفRZÚÞÁ0'ÅK º EÿîÓòÃ0ƒÿdƒÏ¶´©Øg]™ïN©rK¦8£à¼ipľ8ƒpÌtS¿z#3¢Ôî(=€÷7Ög•ÚCf¥€ÐÐ]ÙyéúJ¾nuG¹À% †RJƒíÃ0L[:¼9qi‡]RîižZZ=.=Je›6в#R'xë½aÕ_óÉö³öTšæ×ò¤i•D̈RÙ¾ØæèÿØ⪡­yÛ"„Œð(€±”R{{ÇÃ0Ó^:ìÚ¯yî®ÉÊÊ)g˜`@¢¦éúÒVÏÝjï±·"ÐõÌ®šÂ›[rÿ(öG;Ę6Ú†ÌÝf¾5!n9 ôŠUWOèm,í¯¶Ý³¨â2 ¿Oÿ¦|ôÙÉš¢eyžž·œmÝdRqÁy;}ÜI36ː;©© ¦S>z at WMéªýžî}âÕ¥wµî‰ÐòâoÞèyÛý~IoRs¾O&'üÚï!d€ Œ¡”µGÃ0G¹•bmï@Ž4.ËXRT/ÆÝðeÙØ6Ö÷p¥¦Î÷É¥U#bô‚gö”„Å®€¤þh“=kT†¾2ɬ¬¾mˆuãçW%,1iø¦MK½¢Ì¿×•žbQV@~m0ñP](âÓ)	?“¢­yrYõØ	½Œy\½áó­öÁ;ËîòÔ»ª#>¾²Ëâ`˜ò¯¬©  ïÿnr÷9Ö-¯Oüþáó£7´õ{ „4 ? ¸RzÂYD†a:
+;w¸-ÒcB`ñÍÉsÏK×çï(÷'Œÿ´øºÍÅ>«;(	‡lb|¹+l|umÝÁ0›Š|éǺÎûëG^7¿ì2¿H•÷ˆü£±ü¶!»uJNÚ\ì‹´jy×¹iºêôH¥ghŠnÿÒ<wJãq7œeÞkÒð¡[ώس§ÂŸ 	f…í•5µçÌÙbO7
+mž1…	à OQJ—¶uýÃ0	!ÄJ¹Yø»YöÛƒJ tê sÁÔæ‚g–Uüa¯«{ZdÔVŽ@>;I[Þxܸž†ýǺÆíC"ÖLèmüÓJNž@N0+ü –Áñ„4mÏsÅmJ¼,ðœ 
+žP  ðê¥që×ôÆ,Íu§Mú¬dðÓ’æk¤­¶™WøÀW”ÒOÚ¨N†a˜ŽÌ	à‡»(dÍoÌoÞh‰6Ì™¬ãzÅ©«¬:^L¶(«ÕMÃRµÕÃRµÕ*H gT8òk‚'RÏÈ4]U7lÞTì³–ØCš
+‡|™c2
+¯±ÍÞ3¦Ü'›í=ûĪ‹€†Õ—ç¦éªgŽ‹ý]-`…3t¹ÿ…· äSJŸjÃ:†a:,Ji˜Rjë°‹Bfo¶|eM­Ñ â|}â5¥Wõ7 ÀS£c~›»ÍÞóª/J':*CŸsf‚Æ>¥¿)gÎ{ßÉsK.ûàò.‹ÍJ[„–?j{²EYÕ¼ž'.ˆZþùV{O@Ö\Þ×´½q
+h„–÷N™[ryVŒºôÁ‘‘Û à³-öþ³VÖXt*>0:S¿¯[¤ÒÛVÑ0ÜÈ0Ã4C  x)¥9dÖ¸cµ.¢KҐ®Â¤—ǘ;}¶ý‘ïºqÍ©Ÿ¶w.qjvÔª¿ö;Ê«þéŽÕÃ0àj ,—c¬ZÁÙÞ10Ã0ÂB´€9 BÇ;átôí
+‰ßµwÃ0ÌqY \.PJÅöŽ„a†aþ;€/:좆a†ù;¯ñuØeûÃ0s"8BH!„Ý©1Ã0§4
+ÛŽ˜Ú;†a†ù'!!Ä*ü“ôIŽ ç{|™Kہ1Gs‹ÛQœaæØL .?á¡F…Rë,	Z,	¶+r⯯½c`†éˆ(¥6 žP‡Fe‰Já°ßç®îôYB:"IÙ—†a˜c ”þ½ÏHBˆ@Lë†Ãü
+.Jie{Á0ÓÑ É *ØÖÃ0Ì©Œ0€®½a†a˜‚¢ „týÛCŽÃ0ÓB, .aÃ0Ó)°ÔWÃ0L§À:4†a¦Sà!Y„u{Â0Ã0ÿ €ª±€48êÎíðŽ 'ZNZ(çÿ¢ü¨ 	!|eÇ*'Q~²ÚÄÚÚ9ÛÚR쬭¬­-¶õ/ÚÄÚzì6µZ[	!*BH&G)ýRêlöZ_ £Ž¼€¡‡ÿ9Ò( ý[( Gå“$´P~3 ëAjÜ|øßÍY¤ ×´Pžq8ž#õÇÉkkFå× uÛ:¹…ò8µÛ:­…k$¡õÛÚ·…ò‰8ymUqlZ¿­ƒ[(¿§v[Ïk¡|Z¿­æ#Ê8ym×Bù@´~[ãšîœNV[¯h¡¼5Û* JéŸþAÃÝš®…r
+ Må: êÊ
+ ”-”-”›ðG”‘Ãåäˆr€¹…k L-”+Z(W·r[M­ÜVc'lkK¿?E´UÅÚzÊØ’˜ï    IDAT¶UÛmåŽ(ãNb[õ¡­‡¬¶¶ôûkõ¶²eûÃ0L§ÀV92Ã0ëІa˜NuhÃ0L§À:4†a¦S`Ã0Ó)°a†éX‡Æ0Ãt
+¬Cc†a:Ö¡1Ã0‚ÐÞ0!D at CJ$¦¢”†Ú;†iÄ:4¦uizÆ+µLBÌt¢gkÀÁöŽãï „hUª³ ”Ù—«N‡£A÷–JJ©[ „hš3ºR^φ;áÀ¶*
+8Ú+5Õñº¸	á’äöŠiîÂ1Gmҁ…e‚ Ž¾Kjï@˜“+àøJtopøMa<×Å>Á>p:ѵTá,½­½Ã`†i쮌a†éX‡Æ0Ç rTþÚwbåpu›­QÙÃùëÞ‹¡Tdó= À_÷^Œè^¥oëzƒö/#õŸ[dÇpÊ/
+ñ×ÍŽâ•ñA¥qŒ«½ca:OùƒAÇ×RÙÛàÝÞÊ',¼ªÛ–Ìí³Ã¾íjgáe¯Y{–ÜÙuÛózß#‰¥×poå2'D®´dîxpz6%pªÏëu¿ªPõ¼Ãœ¾îR^tì2…ð&›©ÛÒ'»^I,TØóÏ\
+P ç­øo5¯îó±9må’“]×ÉtÊvhõyn‘ÅÒË(¨Õ ç5t}ëJµeJ½ýÀ—”³¤¯ZÔuÛrz=DÃuçRLáÕ™³"2ÿø¬5êaÚGÐñí]„ÓZ2þ¸“S$„E×/FÑõk %›‚JŽó[«nNˆ=¨‰þÏEêˆëmþº÷b¼•OÎwMÙhJ]¼ªµêd:&wé­½åPù]ìŒ	š¨{*À]|CÂ% Ãµ=
+”µFÝœ%i£¾Jóp¥"qŒöo<ìß½JÐô
+´F'Ã)Ù¡y+ŸM’‚…·k£ïš¨‹›Q î’Û{óÊÄ  ÐpMmµá^ŸÍiÏ\-ºWþ§µê`Ú¥"¡’k°B7è>N‘ ¥q¬Kië wÉ´×À¶/z ¨,×=¤ïòÚ~gÁ…†ý»¦S*ÆN›«Ž¸ùy]ÜŒ"9T&ØóûË«û|,öÜL©dæ]¿1gnù€åQÛÅ›ÒVüÒø³&òŽjí¿Iœ °í4öm=›mNcg †¤Ïv €³àÂe©îBH¶m_ôÅ„ø#¢GÞKúÏ­¾ªÉ’ó,äT©_Z2¶| öü3odAÛ»SÙ5ÍAMämOkcŸ,9²nÂéemÌÃe @ˆ’ª#®ûÃS¶Å,ºWFš¾mõœ¨SrMt¯L8Uacg †Ä÷÷*tC|ÎÂ+‡J¡ŠIr¨rbÝÞ¸E¶ìŒç è\l´eg>[»'zu힘åõygÞFe öýï¬Ïí{¯-;cf힨uu{æ{Êÿ›q¬úÍéË—“?ßpÁÖo-Ó–QRNˆ\*ºW½PŸ×ë~wñÔ3›¿®‹›õ0 ˜ÓÖN6§­¬‹ñ€«èªA!ß–§úÿ3¥,Íñ‘;uï½'‡«yJC„ʁîR ÷ruä÷)
+£‘B¥W:Ž¼XÂþÝj®?‡S$lk­ö2—ÊtÙ¯Tö´e'¾ã8xî„ s‘©ñ5còW+9Þº‚W$Îoø[\ù*¥"ñV<üˆÂ­ïòæå*ó•JÁ‚뜍 *{c¤à¡;yUò:C»ã	§)õ×¾õ^ãç`KœcGÙóϸÅ[ñÈÛœ2ñ#môƒ¶3NÑM9}%•iuû’>´ï?wR ~nÓ¤¥1éÓMœû#'ÄþdN_5Ùœ¾l ¸Kïø +ôqÏ^¥±^§,–_ì8xñ$  ’'RKoá„è½ÆÄ/%¼yßöù‡’X¨h¯62íÇÒ}ç…îìç¨äÌ:úض7úGWÑ”Á À)¢E àÕYA^$DICލS8>r™ Xòm1+M–PŠóU¿’ÚxMAÛo¾.öébcò—›9!f‰$÷W1P*WáeÏ€S—˜ÒV~ߺ-f:"mì“%ÚاFÞpHòï»Í]|Ãoõ¹ORÙÃÞ"Dá$^ä	aoùý=¨ÈP™.ûJWª9UŠƒ"×JÁü¯I8Mž9mí"•åªz]ü¯Sìæ­|â˜_Þe©.ž†í™”ŠqB‡ÿJ9ª#¦Ú¨:ß_ûöd)7Í]zßÓÞÊç2u[ôœ Î
+Â…)(ÔYA ðU¿Ú…Jž³U—^IeÀ	Ñ>N³R‹. ° Q”Z27|	 ¼*íMûþs¯öV<y†1yÞ–vl*Ó§—M©‹WXòþ®ußðPȳæ! [<ã©ìOõ×¾1£é¼n;h°é‘B7<¯ñg^Ñ%'¨;çXõS*{nÏg¨ìK5¦|wCKC“ÌéAý`…6úÁÿøŸ»ä¦¾AÇwŸ¹‹§­2¦,Üxä±R°° °ñHór›sš~æM‡*ód»»ôŽJY,‰‡4Wí_F¸Ko[í.½m½¡ëûNRóNºS²C MäMµšÈ›ÞðŽ»ì¾úyŸzÊøÝœöëÒ#
+ûwǐ‚Οîo^N8]qÓpº¦_¨ é œêª‰jÅ&0§ …n¨O¡¶(èøvJÈû»–ð¦0 *‡«yNˆiÈ:ATU„<Yy~ã]~ȳ&‡ç$¤PYoeõ±ê´çõz‚Ê®^†Ä9Óº¡¾Öisª1$ÎÞ-º~É–‚yláB rÓ#%œ2±ÞßUºØgU[§×¶t
+*»²Ôϳ‚†â8ejÕñêVš'ÙQvw­ÌKÀ:´ÖdHx#7èX´C‹ X
+p!ÐPSþ@^ݳ
+ÎÅJuÚÍçÝš£²·éöíPS9˜Æ)bkÚ |¦¡²‡³çõ™)hÏZ¤4Ž;ò¬IÝËî"œ&§±s!œ:ÏU8i’B?b›ÚrM¹B?lžè\ü¡ãÀ°š¨»VÉ¡ZUÐñÕpSêÏß5^7ìßs­§ü?…²X'‡«Ç*´^j©þúܞʡÚKº³ÔÏ먟NˆtëÞÊm«÷€é†^	*ó
+ÃèMœ:¾Neo^uÎ{ À)ºî”9“=ew®ãÕ=mú„·²E珻¼UÏ?òmûXm¹úPÀ6'“"Ì“æm *Ò†^©2_µÎ_û¿û§ÉÕÅÏ<*§§ü¾îR 'EaµGKL¢{ÕXаUe¿¹­ß‡qJvhŽ£.‘ew„Òpþ^™äÚ¢’k„ îñ àÕ;Bž
+÷»KnïÍ«»×éb)õ×½¿Öoûì1I,}_ys^À67M–ìzSÊ×
+·î4WŸ?øõÆ_|5¯ßJˆ¢RŸðÊŽ–ê÷T<ÞM‹­@Ø@%G¢«èÚ³”†ó©­ÓêÚðm`ZQRpÚªç·{D÷ŠXÎKxÓNMÌMw_Jã¸!ï†K¶9ã@¥gI󶺊&ßòl˜î.½ã6Bx7á-ÛAMC…‚¦ßAûü§@Ã^™ú™©Ûò£F  4h&œ&?ìß5µ)$Þ˜€uh§N™\òl¸Fª{ïZ
+YMˆª\¡;ûÆáF]ÜŒ5ž²{£ƒÎŸîá<ër5‘w¼iHœ}»§üþ»EÇ/ß©	§.TêÏû¨éšŠ¸oäPMO_ÕŒiàÔEÚ˜ÇïliH›e8È™òí¸ §9¤2Oš¦‰º¿òÈc;@£y0ùTÊåè.¹­è^1•JÞî²–e%¯JÿÖ’±æ ‚”΢©SäPå ÂiË­Y93CÞ-WÉMwÐpÝ9”Jz©KºÁŸšR¾ù½>·ÿTö$€(Ü4lNY¡±Þüœ.î©â–ê¯Ï뻪ҼL¡ô±)õ»umÑþ¿ëp.Ç2r¶[rbfPŠ.m¶útMN,‰…
+{^߽Ƥùg)M—tª‡ÿÝ…cpmÈoï8þBˆN;3étNN\ŸÛýQ€#zd¿ÖÞ±œLÇW‚§ä–J©û”¼C3$~°À1ŸãUébD榹 æ6–)tgù­=ö¾à¿L¶fe¿àÅãÕÑ}Çû Þ?Á°†a˜VtJvhsªà]ÂJ㸩‚î,o{ÇÂœÞÔ×͸N½b–uh ÔÖkQÉ¥lï8˜Î‡%5&/`~0íNóøQA:Ö¡ÐF?СŸ~g†aŽï”ÌÂ0Ã0GbwhL«
+¯$W>C%ÛÛ«“EG¸½c8¢˜OPóN›îmÇ´`IÓg Q™Æ'Ú^짓‘Cuœß1¯Œ†<í¶lŸ£áïŒé„(¥§D§F ¨Ú;¦Õˆ”ÒÀƒý¢;³¥4ÔÞA0ô6Bi§^ÅÉ0Ãœ&Ø¢†a¦S`Ã0Ó)°UŽL«âUi	¼"FÓÞq0'_(¸»¶=Bˆl­@gE)¥^ ! ¶3sç%Òvœ(åÑjcòg<Ç™Ž0sÊÝËO郧ҏVuwWNwZ&Éî¼dˆŽïD †;4•Òxa’ :æ.ÜÌ)*äßICž
+ Úyiµ pl×åN…œzs	ºþP›&œ¶Ùö;%Y$¢sqÓ+ M/r*mÃü=®’;Øó_Ãœ6N¥!†a†9&Ö¡1Ã0ëІa˜NuhÃ0L§À:4†a¦S`Ã0Ì	
+y·t¸daÿ5¥b«¬l¦²‡r:üƒé¬Cc†ùêóMküÙYxÅë²dïPã9]þTÀöEäɺž»ôŽ^®¢©À[5+ÙU4íê“uíÖÂR_1ǯúåY,žhß?Ò¡4ŽÚ ¾ªSCÞ­½µ1®T™Æ¹ ÀSþHZØ¿3CŸðú*Al<?èøÞ,º‹7t}3Ç_7;J
+0©#®.óÕ¼‘%‡k¬„¨Æ”@Eâ*¾å,È>58•hJùz# 8¯:[‹»)tgoÕ'¼– ’X¨p—Üu.•=&CÂë‹ë’%;ï*ºî<cò«9Þ"5ÆâC¾Ígèãgþòí4?ÔÅ<¼Fiåö”?”.¨{ØÕÖiuîÒ»³”†ÊCž
+£©ˆt¼Ø¬‰º}3•ì[b™< „Ê>­1iöjNˆ‘¨ìá\EןC8ß˜<w+ ¸J¦÷•üûúpÊ®‡L)ßüÞ¿'v‡Æ0s‚¦·„÷Ú¾y‚¦ Dׯ—p‚µÖ]zÏs `Ï?ç*ѽê\Nˆªs\2³ùù¢kEאgí( ÝËÓE÷ša!ïVCÐùóë ¡á@îP硉PÉÁ‰®eïRÐHÁ¢Ìú¼Ó® q
+ý9›ƒÎŸ¯s—ÜÖ ìûG|@ˆ"Ä+“‹$±T r¨\kÏø"ÇG8;³†:×8þ—W¥Ô/èæ«yý	Nˆ®qOû0ìߣÝkÎÝ«R äùí"ѳ&žpúÂi+m¿C¢{U¼èùí¢†¶¬|ƒ†í9T•â,˜8 êsû½ ’X”RŸwÖM¾šÿŇÜk®UÎÛH8£·57ͱaæ8”Æ1.ÞkHx#·ñnLßeÖ'¦Ôo×’ $±èb*{£C¾PÉÛ=P?×z¼ëΰËÜíç•*ÓØï¥`q߆2Õ!sÚ¯K-™ë?“Ã5g 
+Û-AçÏS Iòmê){0“p†¦n‹Ö“?ߦ2w€¿ö½w”¦K>m¼KjNP÷øÞ˜ôÙöwóp¥~øg¦”pŠø•žŠ'†¶o©!¼©JÿBÁŸcÖ4§¯X¬yx¡®î¨Ÿo¥’§W8{Ž®K“Cç	êÞnJE‹èüy¼ Î¨;Ñ÷ûŸbCŽÃ0ùSHA7øð% @8M™¾ËËï4vxÍqÊ$õ¬5€*Olº"®A”  @i8 ¾mBoÀ¾Ð"‰…#¬=þ×~à¼	4\—*èם‹¢Ž¬‡WwÿLtþ|£óàcœ"áO9\	ov4üÛX%‡k­ @e_$¯LúƒJ«,9L  KžÄ†Ø"…tô<!á| Àñæ0(º³Üà´¬Y9º+ìUr³»ôÞ,_Í›¯h¢ï»šÖÏçÊîИvå*¾¹_{Çp¤ÖŒÉ[õ|bÀ¾ÐÒZ×gZ§ˆÛdËîþŒ«dzß–^WGÍó”=ð°-§×ö쌚¿¦‹}¤”ʁ([væ³’X6ì¯ê! [vÚ+ÎÂkf)tg­2qR2Ù²»?#/  µå
+;áMmÙ/Ørz<é¯}7 Ô×­Sèkß?bÖ±V%j£ï])÷²eg>„5†®oç¨Ì“Ö‡ý{&Û²3ž
+6\Ë:u—$Vœ]ŸÛïž¿Š—W¥‹¼2áw[v泶œ^×ç¾Þ]rK_[vÆs¢{Õ8›w·Eg €Fó`2KNÜù¸Jî Aû—)¥í–m_©’fLž/p‚…@Ðñ£ÉSñØíÖ¬ì—  n_â'‘½Jnn¯øZr²cªÏís¿&òŽš¨Ûª…“‡ê¸…'ëúǬ7oÐ4¥þœ‹N&ѵTá)¹¯"®®?Ù×n
+„“!yNWµiB¨µë
+:¾7+£]„Óõ™ò¬Ó)ôÏ9§$‡Ê„úüsÞŽÈÜp7¥!Â+Sšâ]+Jã(wóãÃþ=j 4}'gØ¿GÝü<Y²ór°P!hûŸðµÏ¹×é‡?Á
+×	ÕÞM‰ãÐxYôlÚ°!G¦ùjÞ8Ÿ†mÃm9Yœ!áÍ·A)_ŸÛï.JE£6ú¾O4‘·Ôøjþ°Íp²6ö¡¯Ô–)MšÎ‚	ç
+Ú~Eº¸gŠ/£2]²3äÛ/“åPù™œ"z¯%cÃWž²3C¾-ýäPMON»×ÔmÑ÷aßN»ôÎûÊñªÌõæn?® GÁø‘R08!*gDÝo4Öå*¾±¿ªˆ1§ýº´±¬>oÐ4Âëìr¨&]ß好•3®¤4`R›¯øV÷Tq}Þ iÝ7Ïi<VûØ÷r¨v¤¯æ‘Açë	§õQæ<古…¼›ÎCU½	o,±d¬ù”pzÙUtý€oëhNˆÎ7uûaQó‰ýú¼AÓ§vSÉžhHüàOÙ'È’£«Ò8úGCÂëyÎC—ö úøYoÈ¡Ò1Aç¢^!ߎߍɟþì*ºa¼®é®Ð
+]lLúd—£`Ü(*y
+r¨ì,SÊ×Ïx*ž&‰‡êëL©ßÿæ)$-èüi2¨¤T™/¯ïòÊþ¶ø9թ̏¹ééq?Ü9å„èmGÀ‘ðÏ:²cËñ‰ÓZþñö:o‘;3 8¼Ê3ø§œtlÈ‘iSš¨[×^¿×š•3Si妲¯§:âêE
+íÀåþÚ÷¦ €¯æíGtñÏÏUY&.öV>{{óó¥Pi¦,Œ I,ë%‰EFI,N”Äâ¦ÔoŸ“CÕý|5oÆIba¬,¼Ô”òåL*{¬îâ‡ñª” 1éóW-™›ž—ÙcBލZwé]=¥@ÞHsÚÒ™ú.¯În¬Çqð¢1!ïÆqÆäÏ—7¯_W¥\D¯zʹ•W¥æh£îþÂoûäɦכ«2wÞ¸Suۻ津¿Jbiº,Œ’ÄÂh)Xp©1yÎK”Lž²zûëfG…¼'Y2ÖÌÕîâéCþTw¨bˆB´tßöº»äö鼺{®)åË7ƒŽo€oëÔˆ{ž5§-©ÐöpBô¥aôg–Œ5ß»‹oMeŸÙ˜øáë¢kÙ½aÿµ,–fÉáª,Kæ†Ç½U3ÊáÚ®–̍3Ãþìóýu³£‚ŽïnÒÅü÷CkÏü§Õ–«JNößs4Ž·HÝ·Ì>þ‘LKÚ¤C“ÄB…}ÿÈËÚ¢®“Åq`Ô%!ïFm{Ôí<4q„¯öí¸ö¨»­N·OóP™6æÁ}²äLÔÏ·Böwó”?tW ~Áµ á¿ú4eEàU©«MŸ 'Df‡<ëÓ €¢6	Úþ¥áüUáÀÁa¶ÆUtíöü!QÙŸè¯ý gÈ»q¸ °„W¦„š¾Ӑ5ìß=Ý’¹éNˆ9ê«1é£Å„()•œ=M)_oÔDÞRp¡ ãÇ#·åþˬ
+œ"î7…nˆW$d‡ûÓõó†Q*FØ÷|Xקˡʮ¾‘MÉŸýBˆ’ÊaÛ wÓgá” Jüu³£xeê/¶ìô—Ývd]’X<He¾l¹B?ÜË	ÖíÞªÏ  …nÐRNˆ‘ìs©dO·ç}•¢{yºB?ô[Oå³Ïز3g„ý»õÕ¦ã’ÃÕ¼< lï8ÚB›th„7˼*¥¸-ê:YxUJ	'DµËܯêVÉ+SÚìٍ¶$¨³| TÑT@ð§yuÄ56pêbsÚ’W¬Y93ÍiKf4ã­eR¨<žR‘PÉÑïÿ/Ã5ëxVÉR}oJEònîÇ+»îõÕ¼q.§ìº5¢ûÖ ÎÈDP÷Ú&ù÷
+4¤÷i¸˜Â¦Ðý¦=ï¬äPÙQÃò¼*] Âë<wkø°U*óx'!êJÝGÑAçb#•©
+A+]r¸¶…Ž™ûSg©4^¸•pšrkVÎLkϼgŒÉŸ}{Ä	rãPáM»UæñßX³rfZÒ—ÿGyS­1é£%‘½Šo¡4¬õ”?ÚœÚEe· 8E자{M_JE"KŽëû €pÚ  ðÊÔÍœ"~‡5+gfDVö£†„׶èbßÙ«ð.^•¶ÁWûÞ„£ãg::ç¡Ëεçé©xº{Ô/(íùC¯i«úŽ;‡fÛ—ú:ˆÂM©?žW¥ÿ,‹%ƒ)
+´Q·¿¤y¨Ì–1 a.Ñ}뾚wºøë>|ˆÞ€j¢î~C©fy7^`GݾÔ7	Q8°NÐôÿÁ”ºpƒ-;í@ðNmSèÎ^+ºW^ ‚¦ßb•yB®·òé‡#zìzľ䍼29O
+è§2OX¬‹{¦È¾ø•œSaJ]¸ (‰-;ícBN™¼ã#ê}ç‚RAi<ï[C×÷ö9Œ'‰EC@m½þ}ÂiÃþºO¯
+k8EÌ>KÆoߊžß/R/*v;ÃÔíÇguV°>·Ï*óåßÉR½Vt-¿TVòêÌuæn?®®Ïí{•ƒf at RY{xôOïavúK '‚p¡ˆ»Ÿ÷UÍL
+ØæÞÂ…)•Túø3ÔSmÇ‹îuCü°ÍéöïÈJ€È–î[i>§r*4}D½Ë–ÝýC×·_#œ1 §‘9Þt  TÆ1ï;ŽyTÒpBT¶%sã¼Æóµ1÷¯w—ÞûH}NÖ9„7ï&¼ÕÏ	ÖZ€—€ðUœ`uÊá:3!‚Û–ÝýuŽ×—º¾ý^8¯ñV<úX}nßaD0ï%B¤[ßåå<ûþá=mÙi/ƒ¨lÖ¬ìY„3æ›R¿ÿÍYxuÐQ0éºÆ9±†8M,4‘Ógûë>¾1h_¨Q.x ”Æ¿ôUÏzDéàëj P™.]t|uØ»}'X*9Áê(¡’³
+ 8!ÒFe¯_ûH©è^¹«áÿ)Jº!ß“?ßÖRݺ˜ÿÌöÕ¼~Íþm4À…¬=óŸró<À…@TvC×·vùëfWúë>¸É¾x²>þù%îÒ»§×çd½$¨»/VG¹I•¥Œ¢¼ `Lúpµ£`âT[vú‹ ˆ&úž7uŸN¤²'Dði£ïÿ°Uþ N!ÎÂÉCoôÊbE´9mÉ
+wé½$±$®1[†³pòŽp‡9ÝõñÏýâ«}§•ƒ*SÊüµ„ÓË!âñó†{t±O”¸Kïè¥4\P¦2Otì-!÷ª®†ÄöøëfGì†h£îüMežè:}5oœ9 ÓDݾ\q­yLœ퐂û“ÍiË~q—Ýß]
+ä%ß[%:±†¼Û®çqë•ú¡E²dçÝÅ7#¼ÅeLút‡®æ=ež)Kn'X\†®ïìlžíƒR‘¸Š®(
+ªŒÉs×p¼Ej¼Ž®‹ÑÅ>¶TiãòVÍL¹×ôÕÅÏX¥Ð
+ñ5Æç­|¶¯$^fß?Ò§Ÿ±œSÄ…Ü¥wŸ/hz´ÆœìqW9Öí‰]lHüð9\§ôT<úUTŸšó‡&
+—IJnÝ7Ï‘%;ï­x*St­¸R¡ü3¯Lª÷×}ürdïŠ+Ü¥÷f…<¿oHüègáäY‘½
+ï©Û³LŸðÊÕ*Ë”z[vÆ»‘½Šî¨ÛÛåkMäô‡uqÏÕíK}ØøîS‚n°·>§ïÇ‘½Knt¼hŒØ?DðZ{îÂ]zo–è^5Κµï庽]çX2×ÝÒ¸ˆR‘ÔíÿÝÚóÀ0Ž·Huû’ß5&¾ÿ¨ªRz«^xÈœ¶ô	ûQoEö*j–±åôzXiõ£Ê8ºÂ]z×S¦”…O8¯œ¡‹~–¿öÝQ„ÓzŒI³—ÕçýIdïÒlÙi¯hc}™WÆ]%w¼`ÍÚ{¯-»Ç]Ü“ÿm~ú39\Í{+Ÿë.ºVLV†ÇñVo ~Ác
+m»x4•}zKƚÏí{ŸB?l…<” ‰…­Y¹Ï×çy› 9ãcÒ'»þî/·#®rl+ÎCGÇÛ
+-    IDATÈ¡ª®Í;Cæä9W9Öí[Ä)â—ªLã
+:¾¿„ð¦jNSöící¹ÿ‰º½ñ9E—å„ÓÛ¤`ÞTAÝë9\Á	1ûMiK–Øö¥ÎU臾öm¿LÐü4¨”ÄÒôˆî[?©Ïx3§ˆ/àq6ѽúJ…aÄBѵüvsÚÒ{´ýå1^•êÔFÝ]ùÿ1uù’¢6)M—,]ËG€p¯LÙöm™hHüèYWñM/*´¾ÖDݾË]2}† éÿƒªHdNŸðæ·Ž‚±kš3žS™'mõÕ¼ú€ é»D×ÆRÙo4§/ŸcËNߤО9C×&NWoÉXÿuݾ”·uÅ¼2¡JШ:ê+‰Å}ځkD÷ê›#{ÝÑŸ·ò™dݧO©,_ÑFß{оÿÜwÚþ¼a¼"a—9}ÅÏÿê{Ä*Çã9rÊ*•y¼S1ÙF8ÍA àñuTöD‹îÕúúÜ~„ý{{€@–‚…© @8m ¨#&QÉ•ú§ëÞ¥²L©ox.r”Š„÷èâž) АYiãj¸¡œ$*Tæ+¶É²ë,^Ýc5 º¾™Cew7WÑõˆ`Þ×|iëáús8Þ"‹IžòG§újÞœBxkn ~^©+›O%g÷{ÍhOù£S	g(
+ù¶_ÓÅ>¶4Èë*¹c§LX
+ Töføkßžì)t*Ç›òåP¥ 4^øº¯úÕ{mÙÝ^k>L%º–ëóÎz?ìÏÎ@¥ÀÁ†÷ˆoø¶Í)bê¨ìŒ9æÛ/Dç5´Io“C•ÑÇý}1  …~Ä~…þœÍíÓ™pAsúÊOtqOËáêäpmzØ¿o•œ†¹€%cÍlsú² ÎoN_±Xi¼èg)TÖÏSv_O"Xv™R¾Þ¨²\ñaØ·cŒ!iö9T5 äPÕPcÒGëDϺq€¬
+y~¿TÖzÊÂ	‘ù!ïS¤@NªÚrå_˜‰dLYð¡>þ¹Cr¨ì"*9Âþ]çQÉÝ4È¢´+äÀ~•¼ÝÁìá²dO’IJQ @ˆ&ßœ¾b1Ì!*yzÿ¶Ê‘
+¯«óÍiË–h£ïûFUõó×}Mï7§ý²ÌøÑnMä-5aö¥C†÷‹@ÅXOÙƒ™Ñ)£k@·!áÜ sq$!J›)õ‡µúø—Þ
+\t²CÿjÙ~Ðñc"á4ejË¿{«f]¹  Kγ<¦‰®UÃ9e׍:‰JzçÁqcyuZ1!‚÷ðwMßÞ	oØï(¸ô|^[¢pÞ,{«ž{F9ýú@ýüÇõsw«#¦ÚxeÊò kéKÚè¦á(D •iœËÍi*tg­W[oÞ°™¤‹›Qè·ÍIr—Ý×C¡\Íñ¦0¯L\A!†.³¾Ø¿IVG\]ç«~@CÊBø@Ø·sª>á÷5ı‰SvÍÓÅ>ù{ þ‹JC„ãM~cò¼ç]EW=°¥¾·²á=ú)‰pÚR•eâ&_ÕËãüí;,æŸk|ÿæ¤!¼»iÈŸ¨KÌiK^9üeº!Cá‚MÏžþp•JAÓ¯Ft­´€$–X	¯«äx‹DxS®}ÿð+	oÊㄉp†JA¾Ò˜<oKóªCžu?¹Kï™æ,˜t¥%s×ÿhL‚L8u™1é“7šù÷ ú!NÂéò›góy·h@ (tƒŽÊö!Kv¾±„Óÿ_{çUÑõñ3·mï餓FŠA)""‚(ŠÊ«Šˆ
+”¦B¤‹¢"D,ˆ
+Š"ˆR¥J¯I …ôžlï·ÍûaYܐª÷÷%wwçÎœ™›Ý¹wæœÿ 0E+o·âÚYª&ÃBÈ«¥úß("&Vœ=dZ   Œ¢«Ù…ßU p®}!ˆÕ^ôØ_$|B#%)¿ø,c0%IY @ÉÚ5P²Œª˜ùyžëjøä1ZÑñ+JÖ& € õÛXëú¾©©×&­û‰d¢8Jšê‹å!$UšsîíªŠY˜Ý¤
+ Ð$,6-ç>ÞVûé뮺¹	´²ë×ʨÙE2ÃÓ¼Öµi  Rݐ]ˆ–5D`' €&þ«×xO~Š­ìñWD¶" @5ûUα«««vÖHQpÚäß—“LÌ)[ù3/s®1˜”¦m¢$).  FÝÿsRÒò©nˆ @›´v`´•=þ
+ïÉK `ô°•KÉÚ­ü1UÅ~rœ BóÝ
+ŸŽ YŸSò¶')y;%Kß	 @Éo©¡¤™û@J3öP²[ê)yÛS”¬]žoÌÛäRòvM4ÕþkœO¡á|8ªÆ'_Ž§ª³&;ÞkY­ñ˜—띵3b/|Æ¥c¯x1ýbòKÙ+_jåž½Ü
+EœÏcVäëH{ÅèÌË­û¿­è¼ÌRØ'Û˜—9Þ˜—1éBåe!O×’˜Œ¹©Óx瞇¤úá« $š{æÝ9“%šþ? ÈÃ_^Í9÷
+0æeL2æ¦ÌpÕ¿eÌË|ÕV>z4l-)EÇÃçµIÙã[éÈ׌y™ã¹iفŸQ²6‚‰ÜgÌM}Ó˜—1Áœß¥‰£É$p$³3@ícä¹Ú ¤é^’ŽÚeÌMžcÌKŸì¨ž”$Õ=üÇøÅ3ƼŒ	ÆÜäÙ¼ë4°<"$
+ÆÜ´lÞ{JFP†ãÆÜ”é^Ó²1Mÿï/4n—ÊUW
+qÖLMð˜W<Ò\×ËÏÕPapTOJò˜–cÔ½ªc?;z%uÝÌÜl{h9q‹…Ï\¬ŒŽ1/c¢D;hEsqÕáÛ¯l½‹^Fðžj¥OÛ÷Å¥œo)ì= Qz£?õÇ{r“ç2
+'úŽSfÊÃ_™®=×æuÉÂ^Üv.}À‹Á^þlk PÅ.:ë{Â{ò$öògïÓ¥l[q©õþ÷Ð΅ǼB'Ñ´\ìÿdsuŽóÁÚ6ª(Y+·ß«õRÚù»²ÍÕ<.õs?[B‹\
+ø4赬ÖЪnŽ9®]ì\ÿ´RˆÔ0²’”¤œ×#J>áõ+mƒQÞYGË;Nú»ˆü ×'^Ëj³nö ,Ø#!5«b,¥]\¦mÆbÑ«õy™nÿÀ§©È9ÿì 0šÄ•süu8kçÄx­«{êR¶-µ?ÐKðÝFJRvj[®ÞÊ»Imeÿ†E{Àœºyû®úù‘ãW`Ñ.ÑøFðšWŽ DyUÏ_T1æ6?c™ó;Â‚+œ …ºÔ]ßž©¯îîÆÅOB<­è´^÷ÕAÞ[мH4åwNÖ§îYâ³yF¬(X³Œyé“)Y»-  ÓÒž®ºwÚRòök5	Ëwû&˜ÑýE¾>•Vv]§Žýì(Æ<X@Ö’aE®º…ÈU·œYÛzµ£zêƒXt$ÚûRFM/6çwHâùºV´²ë:À" `)º·à-ºƒ #ŽTh­"rê>ÀàO^‰mÑRÝ°%ŠÈ)7T˜ÍµÂ¿js±\ìysUKiçïÊ6Wó¸ÔÏýøžèšú.\Ìy W¦nr!®zÉ$pn¥Í‘…>wÅ릌º·=8™Ý˜\¹\ðžzRùÆ"‚Ž.´W¼0 @9ýsCFþ,ØÂíϧ³ö-JÖ¾q´*fÁuÜ×s	:’ °—nëi\4V9íg[éãE®&QŸ¶¦àÍïæjXi/õ "ՍªèwçcÁ~Örš«þ½7¤úGVé[š*Ѭd”wÖéÒöLSÇ}ù>kýõœ+öòÑmcҐq2[ýÞÊÀÏhE–E—²i†&ñ§·Yû¶Ç H&f+%kó£2 PD¼^Ži±!=o–&á»=  Xdåš„åÓ8çŸ# ìeO>„HµE›´îmÖ¶ùÿD¾Ž¹ê[¶T.²å	"[ÑU›´îM©adƒ¿^GÕÄ'H¦E±"|Ü—Ó’×}c\Ó	0+Ó·:2[ô–Æli¬³vF¬à-¸S›´nšÈÕe
+lE²ÈÕÑ"WÓ @`K†ÑŠ¬½Rýc_yLß<uE9HkÄŸÐÌw<¬KÙqÕ×:ýXKíDI’ëÎx9^ŽªñɼûhŠÿµ<쥌ºo“¥Q0“¶’¡÷ AGÕÉÃÇåf’mŽ¥¨Ï½ ÓÊ9çÚä¼Þ¹JŠs‘_î’Ôµ Ê#RÝP£ê¹Ít²ÓŒY䨞ø‚£z"`ÑÝ‚w2	lY$AGídTw:Ïe­kg*cÞÁ¨{Ûí•/uÌjM'³&dœ}[’ÀÕf©b>xƒQ÷µ!RÓd¿áôÚ>!_	àÓÕ³—?ÛÚ^1f ‚EG-¡¡òÐÑ'­%Ã5æÄLËo]®Iüi»ÿ3¯mc¸×üÃH@¢;ÉÝøùY)=·T?ì7Ÿ,áå]‡¤WÝ
+	ÖKQ¿Nèªÿ0.°<)MÙàêö#ò¦¶º´ýób°£fšÃcü2 @1imà’kßÒž`âv“’d–”$íù†&*$I+üO§îÆOÏëuÄçÜ'£YîkmÇ• xDª…s©á\,þq¸ã1‹wŽärÅ‘.Æ)„‰/¾ÜÊ/J’TOJÏݼXÛ†>"W“úweD¶‚æ]GG"çü³¯¥ð®ïì•/§¯<ï:ò< Š÷?Δßùñ˱ëßÄUÿA‚£jâYRG×3Xt¶ØÚYýF&AjO8«&¥ ^Cú‰éˆUˆ„T?ì°ÈյǢƒÀ˜E³ @ªt¬£jâL¯eµ†”$í#¨ð£~ueôÛ{ÊpÜcZš)òu$íM®³ï‹‚çØ®ðÙá Xǃ¤úG?WÇ-y@TbÑ}Öw‘*ѐq2[—²õEι·ÉÓk]ӏVuûI›ôë"˜#¡°è–U¢­成5ù!!¨Ðý´¼ÃFCzÞ,]ê¶ñŠˆ	¥M+`šLf>ÛÔùŽª	©¾‰XPJ
+ÿ× @2±MÊ2ª;‰lE'Q0“{ªóY¥‰bþ[É®ÿ*¾eYÖ’!ùì\a7Ö’a;*ÇÝzeu<¸ ðï•àµ¬ÔYKzóÂ%ÏÏŸÐ8çž `¿1/c"  Ýaˆ;¢OݳķðÙÓ ˜$¨°\]êÎe>ÅW8 Ú¡IX>ÏUÿ~:çØ6 Æ¢„db·‰\egD(ªô­Ž½ËÚ·v$ÙŠ"ÖþGçØ> “€iWL&$	œ9¿Ë¤Ó{!˜ cö  ’Ô}~•  wã¢0Wý»£ ‹4"uÅê¸Ï–¢MÚ¤u `ƒ¥¨ï=^ËÏ/¨¢ßm.è9Xä*³ /yúyø+U€(›¶åڍΚ©Enã’ñ °ÄœÛ‘7¦ˆ4"ä5úVÇÞcmëÕöÊqÏæeˆ×ê[ùÐoƒ¹àö¡"Wß@ÈÃ'¿ånXðÆBŒMßêØ{îÆEa®º·Ç`cA*՝ϻ¥ BéÐ$þ´Ý\Ðí!R’T¤Šùàˆ9ÿŽg1v (.eó<GÕk­9Ƕ¡ „—’enز4,˜:óÒ'ë[™ýoåº!-³öž@º‘¯} Ñ
+5y­ëäÆÜ–ó¡¨D¤¾Vªjò¿ÜàKíNpš„åÓ©ÎW´˜]€HÕ[Žêמֶüy¾µdø£gÔ-BžY ˆ˜ô££úµçÍ'»<ˆHÝ‚
+s¶-ÑÜ7ßVö¿‰ €hU÷Œª×JqÉ‹ÓR/A†¬G„LD¤®š BíXôPX0Õ:kçdpŽm nJ–±,°>F3`×ôÝ‹}+GP![e`e¡ÏïtTMxÎt²c„>mÿbYZÙãké°	”¬Í&Dj‹©ã  RS „+"³—;«_̘›< amÒºlDjK*„E”¾ž BÎÚ‘‡ŽþÊÕðѬu’Qöøät}…ˆù”S¨#PD¼^Î9vì4ŸÌšˆr!RÕˆH
+Hõ)ß5ùK…$ð8ˆWÝÜh‘-l.èiaÔ½ ¸jg'rÎý­åáã6ùWHU“x÷áeô{›W‚XÛzµ×òs‚à-‰%¥©Åª˜sy÷1©«þÝ‘k0LL­,ì…|Gå˽(yûeÔì"{ŘRšj’‡>_c+ÑQ¢}°Àcþ6S“ðÃ.  [éð,yøøcÎÚ™í¡ðˆ\]ˆ&ñûMˆPŠöŠ1œëà­”´UŽ*váa„ŒEa+û_g‘­ˆ—…=ÿ[`ÿ¬§õGLÞø”嵬Ժêç÷F¤Ö¨m¹z‹­ôñ‚· %ïpP³ ïBcf-~ð‘«Ž¥UÝ÷*£fùnb§¶«!«ã—n÷)¨ì–;ª^ëCJâ®X û‚ÆÞ߁WGÉ;¬Ö$,ßݘ· –¸_L+á¨z5c^bÈ(œdÎïú¨£jR7Dªí H4d7h÷]ZCÆ©q9	Xû%=J,º%§ï
+±!ãÔ8s~×Gµ3³¡t!BÞ O;8ÃtòÖQ{ÎHåœ>cÌi9 @ÓòçÉî†O¢]Öªã¾8ðW¾ ?ò°±»l¥#Æl	-°Åw‡d–²—jã6-*eÆÞhcnò,:Z1ê>Ó  °èQ#RW¤OÛû¥ñDëqŽêIIœ}GGR’¸OÛríƳÆLôª©)Õ§íÿÌRÔïnDªk•³¿rT¿þˆ­ìíx÷‘,ZÑåGuü’Çc¾Ä¢›Æ¢G@
+§ÏW`Ñ%µ•ý¯3 Æ¥j1k©³fú {ùs]oAR’²Y“øýfD(EGÕø¯õW­!=gî%^ûkB²jCFþ”À÷'³›—Ó&ýþ+ üz¦L«ãó  ‘Ù¥ŠÈì· e©üH´ƒ§Ÿ¯íÓ_Ä7š¼c_ê’7ýðÒÿÅ=§»´2jz±2júØæïK4ýg7O÷ùá€zvùß×·:² Àçâ,Ñôÿ0ðÿ¤úG7Ÿ«}Yèsµ²Ðçšxë[ùÀ¬IXöç™ÃRòök8Çî§e‘£>¤Yn}«Ã ÒsÞö<⃒µ¶"”¼íIJÖÆ ÀÚ~@JRöÛ+^˜.ÑôÑœû#{”4õ˜õÔ€Y†ŒSãüç³ö-˪÷e·)¬}óý–S"%šAG½Öuóiy‡”¼c¥èžOhyǯ¼æ•ñ®c;$šÇœu³§ñîcsÎÝCÕñKÇÙ+_ÊÚÖ'¥inÖ¾í9uü7söm¯L܏¥«5¸5ûô^´œQvßÍÚ~ïc)ê£KÞ¼Út¢Ý[$“°’ßrTd+e  ó”1/cIGåNf®úù‘®úy3uŸ°`÷­h`–¦•ÝÿôZWµ–Õj–ïn>NÍ¡•]÷{Í+žŒ?eTÝ뽶õïÓò¬7¶"Ózê~¥6yãZkÉд¢ëbι§ß•^§Kr
+‘hô!,r•-e!O—ú?çÝÇ’	*¤ €`b‹E®*  ‘úÓj
+#I·( @ˆ¶pÎÝúÀúið•#5"ß&pшÔÕøÞÓž3P–VÜö©!óÔXC橱”¬G,©RÝ#…çëƒÛ¸¸5 ¦Þcú>!i= €D÷P1l>[S¥ŽÿöM‚Ž^ûŽu:3PtD)  AJy×±D‘ohE˳ΫEFJ’ ˆ\E†ÈÕ¶qTMz°@#D`,Xie×rߘÈ+ücú×RÏ  ÞSéX0¦;ª&=†E—2"rú"_oÌËXh-Úå\m_ÏÐòNZÑéÊän‚\ˆP¸°`Ñ©ã½p©Þyÿuu_ Ò©Š~ÿ„ÿiLÙâ­ÅšÄw r  -í‡Egç:tœiÓ׆À:R½_“øãEäԏÏÉ»  ¡8¦MZÿ›ÈUÉ’—kÚ.÷¡à9ÙW:ªŽ’¶Z嵬Z ŠùðM  JÖz•³fú}öòѽH&Ö—Ú^]Êæ%Ú¤ßÖcì	ó-Ñ{i¯õ—‡±èÙ²®¬}‹cA¦MÞ¸Fóa®<ü•*  ξu
+)I8Ð\‚Êcú¶/-ï¸DûÙQÿÄ…›Òk]=0¯äÝ9]ሼ1Äk]û0Æ"Ã:þ¸ýtk“ÖmhüIà*Û9ª'%!BY¬IXö§D3è»+¼LWæåHÒ-¶YK†=Î9wË]uﴐ…<³K`Kú¸êߍâ]û崙·o½’úe†‘;oÁ}öòQmoQßs•ùúHGõ‰Žê7y÷1))IÜì¨zå	α]᪛}º”ÔQ51É\Ðí!αóyZuǧŠˆ‰»£Õo$:ª&%™˜Ó¶"L+²Üú´ý‹E¾¾«Çô­/ºß“ÓßUÿn”À–ô‘…>»‡’µÙà1÷¸×ºVí¬ÓÜ.„ €VõZ „<bâwRý°U´²{%ÉÄïr7,|ÐY“K'  JÖö„à-é쪟)r5½  ¤º!¿)yØ‹Ë¥!OþD+º–sŽíªèyßÑŠ._òîÜ.ŒªgÑîÆE7„,­Èr«ã¿Þ­íø/¢IX¾[›ôûºæŽSA.ÔdÏ“Rt>Ãw#ŠY¥²ÅÜ
+éy³BÚÔö À" À»† BV €sZ©ã6`V À»sC€ÕbÌ"ÁSØ› Õû]
+g ¨ã—ü!pUÝyÏÉ~Š¨é«}rιﴀ€ïž˜sþù„!=o&£êö3Æ‚ŒVd¹ „³ô	Iâw¼;g0k[ß$Ä… Õ"ßáÍ9÷ÉxOÞ}†ô3HiêæsÕˆ»á£‘«ºÕ~b:IGíÌI}ýõ+ÈyÀ˜¢åýý¸
+ÃßÕy1\´RH r%IY‹H­¨IZ·œ¤[ÚÊž˹öÅK´ƒ-RÝз<Æ%ÑÊîËT1æÒò[*(Yëà  ”¬Í1JÞ®ÔW_«-”´µ•’µ>ì+Óî¯r§2¤úÇŒò°—¦ðîc­	R—G21Md)Yæ>,XÃYëš{Yëš{Yû&½6iýjRšzÀVþÌˬcW2A‡sºƒµm¸€“_ÖÄ» @ñúDÖ¶®AG”jZ®YáëoÒ™”ͽs9ÇÎ(  ‚ŽÚçnüb¸D;ø]‰¦¿M“¸b'-ïô«£jüξ¹mS»Z¤díª  TÑïd4÷.uÖÌ|ÂcZ6#j’Ö­%è°¯eåýˆÒí PF¿}‚`Zö?„Vtú˜’µ«‡¯”èþÈUÿÞOã⇠X`ËCmåϼ,x‹Ó”-f/bÔ}m´¢ÓrwÃÂýŽ7"^ËJ­µøþXt®úw£¬%ÃÎv\ø‡±•ý¯Ý…Ký{\ª2ʵuŽ¾;k¦&x­kÏŠåû¯BБsÓ²Ïw]uïo•c'ó2'sSfž]‚Ws“çxÌ?>/ÑÞ¿ªÙ¹vDjNsS¦³Öµÿ“hïÿÑœû»S—²mï>ö«aA$Aê‚ÔEˆ¶œñ F”Õ^þÔ›Æܖ¤_b0BÒzcnZ6kßò(  "”"É$®7æ&Í5æeLôÜP’–'¥úoÛÊŸë1¯ÐùíQ¶xë‘«ioÌkõ†1/süéåHdÌMËæÝyý/4VíÀFŒ=QÆÜÔ7®²ÛùË
+¶ B^cÌMžÍ;þz¡z/ÄUW
+¹Úó2Ç#Dð¢`×¥l×<˜ïßÀtâ–ç(ù­».Eéþâën3–Vݹ^ýþ‰«]÷¤Ò˜û9-k¿T¢|ÜQýÆ,FÙã³ÀÔ)çÜۈ‹Ý¤¾WCÅæJ	TỉûԐžûì}Às~—áºÔÝߘN´+}q©,äÉÓ‰[ÆPŠ;Î¥ÆT
+9?^ËJ-£¾ÛxÝU¯¦x­ëiâ¿þ€”¦°ç»¦£¢aÌMË–hú-SFÏËðýßÒóž<L Ë;kÛ¨j -òu$ïΕ5‡9¬m£ŠRtpùÕ?ÎUçßžoߢ¼˜¶8çnyS
+Ê‹äŸV
+¹Ú¨ã}(xòå~wäk"òoIiÚ?s"˜ü-¿õ¢þ¹n¬%Ã:óîCw“tÌauâ¿Z
+û<¢7Jà*Sœ5Óú”WÙÂVö¤À9w÷ŒIyØó%úa
+¶’¡}¶üVJÖf³*vá^-ï/ruíÍîc»t)ÛÎ<]›îxXäê3©®PEÏûŽVvsšNf=	 PXt…ÉO~!¥ê´TÛ0‚Ôœåa嬝ÃÚÖv¹†tDHŒê®ß¼Ö5‘LÜmòÆ5"_GÚJ»G`ËÛS²¶›5	Ëw[ŠúÞƒE\ä*³ÔñK¦9*Ç= ò¦$‚
+)`ÔwíVD¾Yb-~ ïÉëN2q´I¿­÷·g¯x>ݯ&Â(»¯ °œxŸÈVt UÝW¨c?;Ê9¶+U“‰‚5Z¢éû³²ÅÛ¦“þr«ÈUf1ê>K9çž®Xt…ÊÃ^ú,PZËœße¸&ñ‡åŽêìLÁ{2M—²s¹9ÿ¶š–«¾ÃX ½–•Z‘«ïéª{KﵬÜ À»ŽÞjÌMJJ’¶i“ÖÿÖ|Œ‚œÍ¹D&ÖNÒ‘'.cu¡ÉÌœßåQ‚ËóOf  ¶J±yÝçšx*\`Táý{Ó¼ŽK™Ì  .v⼬Éìü+«¯ZÑÅu-'3 ß?èßc_	RÝPSó­ƒ°  óIDAT`Ù›¯e¥–sÿn®ÀÕ¦Ú˞ꢈœò#"•yú´‹(E§	:r«.yójÖ¾ù)mÒ¯stiNgÔw›l%Ã{aÁ©Ñ¥îžÅ»ÝÇ9v)*l;­ºsIàd  {å7CFþ‚Ž,vT¿Þ @`KF2ê»7KÔ÷þà6~1 Àm\2A9å‚Ž,,4QÙb½à-~@÷Ù[ó2¯uÍMËUÓxoAιOf+Ù‹.¥Ïžƒ÷±¶õj«Ìùúd]êÎלÕÙ=1`R¿tŽÀ–Þ'x‹Cìϧóž‚,}Úþ™"WÝÊQõêa UÌ‚<¿šˆ*ö“ã ¾Lܪ؅sXÛÆQ  öŠ1ÏP²ŒMü×ó=æŸF ˆ|͈¸QÓçzL˾dTwn¥ä·lr7|Üd	cÊQ=¥
+çÜÝO`«nǘEWݍ Â‘¯é*Ѷ R}Dö⇧Ã\ ‹Î0MËÕÙ¼'o/EJËAú|Íçþ ]êîoýÒp~ôi]i½7—=¡9k¦&ØJGtĘEóò3ÞŠæ‚;¾:¦]{<æåzË©þ½¯µ7nã—H:j%oïa”·mä='Îë©IÉÚþh.è±Àœû+"WCÞÂ"ßÐÊœßu &¼æ)ç;×Y;m¨1/ý5Ás²—ÈÕ¶ @HV¨Œš]¤Œž—Eg¼O‰ñRÝP“*îóÍ7ý *t'­ìæ$¨°|’‰ÛëSW”yÌËâoQ‘«ÏðÛã1¯H `”w¬'¨pAàÊo•¨ûl£YnDê÷ pŽ]=@t¶0ÌšˆEwç$6o3uü—ë}w¹˜ ycëØÙÏZ:|, &N;-‰šÄ—ꆚ¡ÈQ¶˜[(Õ>tR¬ÉMÇó–=¼ûH'À¬– uyÖâÁw](æŒVtÚpºÏåÓ7-þ®ì_¸ÏÙj2ÿ"WIý][‚·ùºKî¼…L`ÎÆ«ÅåÚ#
+fòjÝ,]ö„F2ñvRÒ²³oS:«^;#8,°e7Í xNªoqÖµ¶ãfB¢îw\äëÛ pîãmI&þÐùʪ¢ßÙ’Y6
+‘ªZgí̳dâöÒófé[™¨l1ó"dV,:š¤ˆù:RäÛÒófLô>>¦æj¾e‘>­Z’€Ïñe<=É!„á´çª?Ä‚ £÷’’ø=Ù3Û·×DÈX  ’Ž=ÈÚ6uá=y,˜Û P²Öû¥;iHÏ›eÈ(xMóÁ–¦íMžÖ©ýöú^kŽIuC–Òófé’7¼â×Mý+œw¿Mõæq‘«í…y
+%¿åOÞyà%J–Þ4–16‘¯ÿKå‘‚¿Ï‹7¬ÓÑÕÀ\Øk ¥°ÏWíìô£=[ù¨ž¶ÒÇï|ÏRØ{€?ÀZ2ì1{åØ—R§)¿óHË©û&¸ê?Œ¿¨òê(anª	—ìXå¨|¹µdè—zÞ¹øÛYÚݸ(ÌÝðáp}«cï6ùR¢ø"U^Ö¶©%muT`Ëc9Ç.‹Žtc^údeÔì ójcnÊLŒ9
+£¾ë³À
+eGõ‰^ó÷O QºSâ­  9‰ó¢l ‚œ’µÿY“¸b§17ém ʉ©‘VÜökßô(  %k·V¢tÂY3u¼¾Õ‘Iæ‚žO’„‚§ ½D;h"2»Ô\Ðí!‚
+¯ØâL,8¢ )"5Åú´ƒm¥Ã³8ç¾  ¤$a6é÷uM•OBóuïÝ ¾4ÖSƒ'I´¾ó‘ø÷ijo@œ<ìŏæuT½:Ë×LJõ#>”‡¿RnÌËXˆcĘSKµ| Œž—ïßüØÚRxφŒü)9‰ï#DÛ0vG‘’ä5"[Þc^%}n¶?näFG:ªÎc^¾×˜›4êRUüûÛD®†F¤Æ—
+±cª± Àrjà«€y Ê©ˆþàD*E[é㏝VEäïHõnr5|ô¤9ÿö8âC‚
+*ì€OyDU†HM1À¹Õ0e÷Å–Â»æ ’Ö#R×drET¨‘º*Ÿ]†F at 4ï;Ö–TˆS3½­ì‰ {²ß!H]A…º  T±m´–ÔzjЀ˜R’بˆ|³Äœß5Õ˜›2 í‹•-æùÛ¤å–óÒ¦ÒÊ;V!R] §•_üöÊÃÆ}æn˜?Âcú.€ô2NfŸ«_¥ã	RÓ$“ £yDêRŠN›•Q3rLöµŠˆ×ž'ÑøÙcþa8çÜsQºJ‚
+qôù†Ö.¼œµ3bωᤤ叴ªw9çÜ'sV¿Ö‹VÞq\9¥ŒslW¸MK“D¶¼A…7 RéVÅ|œc-Ü]òÔaD8wã¢TYÈÓùŽê‰} c$ý‡T7Ä쬝+òF9ï:ØF:z“È7H¼æoonï>&å=ù÷»êD°ö? `Þ¤3t¨ûìUDL. ð˜¾6¸K<µ]ªzÆiÇQ5>YdËî'%i_I4÷Öøö{íZ‰fÐÿïkߢtÖθÅI´úÕQhåíG•QÓ‹m¥wÀ¢]¡Žÿz"”¢µäá.iÜy‰´"+‡dlöŠ1¼;××Kȝڤu¶„¶—éIJ’*U1óó|v~kp7.º²«æCpA/ÇÆœ¸Ï”‘Ù“5Ó¦”>í&éèb@„(°åÉÊÈé?ÙËG½iÈ<5  áXØVC«C½½Ö_õ®ºycš+BpÎ}2wã§i¬mÃÚäßGîM5ÿ]ýö0‰n¨É˜›òQHféèÆã-¾—…<5A™]Ú˜“ø¾:ö£)”¢³Ó”×ö³ÖåOXŠîé+x
+îD9
+¯û”Ú·ö7¤çÌm<ó¥.uûÓ–¢þc	*¤X—²m…1/mª<ôùOe¡ÏÕz­kÕ^ó©¬ãgC2ËŸ0æeN¨û¬òo¸:k²ã=¦¥Ïc,2íÀ=y×!©¥xð¼ÌÒçl¥#:òîœNòð——9*_ý.¤M]WÝÜh·ñË‘ºÔݳ¹©›BZWÞ鬙ÚÒkY;Ȑ~ü¿Gà-dÌ…½ßÉ,}®ñXÄZUÜâa"W-uT¿þ]h›ú»¬Åƒ»\u‚>uÏW—zqo$/Ǜֶ^ín\Ô‹,Ã{Ž?’Yþ䵶éjñ_órôZVkìcH4ýÞ‘ž(´^D+»~»¢äVQ²ÌJWýKhEÖ,FÝ'ÇU7ïu}«Ã/˜rÓÖR²6!Báùú²§~gí[ Ñ<kß4*$³ìsAÏÁ‚·p0£ê9Ÿ”$6º_Md”ݳö?Ɛ’„uþ=3‘¯#Íù]æ’ÒÌuŒú®ã×ýD¾áZÑe)çØþœ>ýøHgÍ´dÖºv$­ê±Œµm|V“ðÃË~é[ƒ£jü‡ݐi2Ã%Κ©	:¶Þk]õ’:î˱QØZ2l!£ê5‹N™,tôa[éˆÏ$º!ÓhE×ZWíÌá€$‚T7lé톌‰Ç£—”þ£é·†µoíJÒ1§õ=ù¼çxïÜß^äkÛû”¡â?b”·/áÝ9YY¤ˆ˜´ÃZòèGŒªÇG¬cÇH‚2ק\xɦ™—ã—’Ô»>DË;|[œÈÕuPDL>o`,"¤§:š—è†1ö4	öµ•>ÖÑV:ìM‘­ˆÀ”ײ²©ª7"íÝP“O³é8£Ä9-£îkó¹bB`Kh‰vÈQ´e‘ÒV›|ëX´·´•>ÞQÚ¿›?ÉÄ•úšÐ–±Ž‰æ‚žƒUãLj|}ˆÞ(  ,Ú[ÊBG•š„EWB„W9µ‰*ˆÇüC4"äÕ  ŒúžbQ°øösi) €4ä©,º[øÆD–ƒ}A„î&}ØŠ¿ÖŽ	¦V¢éo“è†!ó=±ÐQXpÕÏo at HišcŽDqºäÍÏ^k{‚\>í@+ Ò.wÒcúª%¢tG4	ßï–èþ”w¾ € Uµ-×n”‡>_ „£âÅöÿƒÀUÜÊ{ºÐª^’’–nÞ}¼“Ï{—
+sÕ½Ó €dâשã—îgí[;RÒŒ•êø¥ûIIü¯6T¸ ˆ1Óò[On(YÛŸ4	ßíA¤ö˜«vv"kÛÔ@¤9Ç®~€‰³&ûL˜Tÿ¨Ñ¯vBÉÚx¶:µox 0¦\õó³5Óz‘’äŸÕñKhÜÁ¨îtøËKuCÌ"ol¯OÛû¥6yãZ,zÂ}û{«b/TFÍ>³Ê y² ÂœWÙC“°â5{ŘÀlç:t=!‚'¿³ö­.$÷»:~é~Jš±új]§Nh»W`KSD¾q éé@÷PZy›¯p5,ˆ¼ú4ïÉÏôi‰µ-ÄØV,(­Eýïµ—?Û!ÊyZh÷̝="U–Sï´—?ÝmE¤VtÖNÏ–…<õ8ï><¯êA2	¼¶õs¤ºGÏxqÎ=÷¹êÞi!²ÕÝ“‰\u[FÙ}
+A…1æ" H:z›µä‘‘~å_›º}”¬íóɬ™©ÊsŠ°`OvÖL‹sÕ½3””$l À¢³½òå4멁TØßÄQœ«þÝ(GÕ¤!¸AnPH&Ó¶\»QÛrõÖÿ’'ëÍ%kW¢×   ²eD(|9s&Á%AŽ²Ž?ž‘hún,H±èh©Œš^쨚4`bóé'¦¢Í¢`”  Ri  H}=¬  ,8Ï¡œA²»Ï8Š RéSÞ@„€E/MêJÖþgCzÞ¬Öÿ§Múõ÷sõÁV6òV NjH?1‘ê|ÀI·¨Æ‚5¢iIô×ꢜڸˆd8@ˆmž6Æ·2±0[1e2%oï¡d·Ô#B•ëÛ7>™mÈ,~™dZÔcÑ×?,Z›H ^	œÐd!ÿÛIIÓ>¢dm<Œ²çJZžõ
+ €_ÙJ‘Qßý±ÇøÕ}¼sÂ¯,‚…HIRÖÖ¥Œšñ£(˜¢Yû–;iE§i”´uÓ§„¤ƒ@s®}]T1³þR* Ð$,Vç>ÞVûé뮺¹	´²ë×ʨÙE2ÃÓ¼Ö_R ¤º!»!-
+ÌgF0ÑÝƯ†I
+#fR²6yØŸpÎ]w	ÞâdJ~Ë  MÒÚå$]`+{r,çÜ›@ÉÚX(iúvMâÊm´²ë
+Gõ”6æ*"&NôZ~îO0±yÚ–¿ü @šœc{ BÐ&­ù*pHI’‡”¤n  ê™çnürÉÄRÒÔ_ûx%»¥ž’¥ï„›”ëMàÒmºÜ>Ø+FgŠ|鬝ë¿rý#yº‰Ñ˜›:sü9Tj¾ªyJvË,zZ*"³K©.EHÒ  @J[åñî#s“ÞÌ«šŸ§ˆš¶Gäko5æ¦Ìù†ŽÍ?§åíþðšW<m.ì5ð\¶É#&­áÝÇî6æeL2æ¦LwÖΈ=W9FÕ»Tä:sSf`Áš  Šûì áƼ´©ÆÜÔ7 H&v«17uš­tx­è¸ÌZ|ÿLcnòRšrVŸýØ+Ǿ ØU?ï)Ó‰ö£e!O6 RUiÌK›jÌKŸl.¼ë>ėǰèhaÌM™%°wž¯®KåºR
+¹J
+ŽêIIÓ²qŒº÷B¿CŠ1/c‚D{ßOÅÿÓ×gÍôWýJךëqÍkY­qTO~֐ž;àúPçhÎ¥Út¹}0æ$¾§Š[ü†£zòƒ$[èOr#ð_ÛCrr=+…(Â'¼~áR£¼³Ž–wœ­¯ˆ˜¼˜VvùÇYÍ ¹yÿt;72®ú÷{aÞØ͘—N¨¢ç/ ŒIÓ‰vc0fÕò°—ËBž®wÕ¿å1~=€åã—zjYO
+êAÉÛ•*"³K-E÷ô•hæ\£oI¼ÈUÝJÐaÇu);—;*Ç¥r®}íD®>ƒ #ŽkZ®ZÉ»ËìϽ€	R’ºCÛrõ  Ë©=o~7„$V}«£ïûÛ²•=Ñ^äªÃ•Ñïn±—?;@äRåíëT±‹ŽzÌËõ®ÚY# ÆgÅ
+Ù+_Ncm æTŠ¨7ß÷ZV¥ñ®Ã÷ Bb‘ê‡ÿàÏšk[¯¶W
+DVMJSvh[®ÙôÏ\… AnN®+¥YèsµWZ£îmo.=#Õ?jü74 	R'ÈBžlø§Û¹‘‘…>ó"•Ç
+éy³uo;]Rý°U´¼ã¿²…«~ÁDEÔŒ¯%ºÁk5Óš8S\Eªà-	 ØÊL-UlY¬À–u×$þ8]äêÚ¹êçG
+lI„à-¹O“°l{Ùw’¯:nÉ;ºÔ?gžÜ¾œs·Ü^1&Cðœì©MZ?KÙâÏýíXŠîéË9w÷WÇ/Ù`+{â‚Ô5j“Ö½íµmú?‘¯#ÕS_¢U½~•ž\ŽEWë@EÁLzÍ?WFMûL›´v%kã”êÉ5däO‘ž\æ6~qNoGgíì{H&î˜!#ª"âæi-Hë…ëê	-ÈD(räáã+y÷±FË©{Lß@t·tT  ˜—ÿÝéþR’¸™’µñTH.çØ‘ @P¡RòöFÕk³×º~ ïÎ=ä¨;éÁ¢;ÖÝ°0ƒ÷ät Ö‘Lwæ¦sÞ}ô)}zÞ‚Ô	"W}lQ–¢~] ÑÝðI]1ªè÷N ¸êæ6‰÷rVMNG”&7ðÆÊQ9®§£zbG  ,ØšìÅú‘hØánX0Ö˜Ó²/£é¿˜Vd]±àr ÿ%®«'´ 7?”4ÝÕd‰®™²…Tÿ¨i™6iÝÛ†ô¼YÚ¤uo~N†J«ŠÂ˜EX°´û«"@¶Ê§ª!
+¦Ö³ˆsîmG21Ç]õï÷ ˜˜ýú´ý37€ˆ(iæÁs  §Eh#­¸m¾ß³• BЊοÒóféR·—GL.C„´Îݸ(Œsî–cÑ“h£<|l>l©~¯X,:Þ“7X—òÇ,©î᥀…³2¯ H4÷
+E¯Ê#&ÏöZ}9ãäæÀRԧߍ’ãðz"ø„ä_…’µñ :ìˆ17-[³`ž_¡2ѯl!Q÷ýÄRÔw`AFP¡¹ºÔÝßøÏ—‡¿¼Ã^ñâDS^úíˆÔE¤ÁMP† R @¤¾– V‘oÔ"Dٍ¹i爐\³àcÞ“/sVOšl:ÑöDi#*Ä®l1÷¤¹ [†17i. ‰Ñžû"ÔùšÄ•Û¬%ü–SŒPDNûÖYýúcÆÜä! k“Ÿ*ՏøÄU÷öX $THzR’ÌÒòߘzÎ @‚<ü•ù”¬Íæü.sILˆ
+ùÃg«¦J õ5i°ÙËŸë-°%w ^FÕó‹í¢¹(¬%wA¤Ú)²ÕaÚ¤uí£3¶<R÷ùŸÀsi+}¬ÁÄVaÁ¦Ð$|¿ÛZòpMÂ÷»ýçû•ãRyO^‚*öãÍ$“Àù3; b<ʨ9¿óž÷‹ŸFsÎÝÔq_¼¶=¿q¸®¼ƒ\]®G/Çkñàî"W8¹zü½G®"è¨õÍÀß¼–•©©#èðjÞu¤¯!£àucnÒ\RÚjƒÈÕ$Š\õ]!­«
+ô€õ›ò; L2‰ù¼kß`CFÑøÆœø…Ríï‰|ƒZöÒqkÉCÓHIêFF}wŽ<ìÅš«57׳—c WZÙ½@䪪¯µAn&¯6yÓb‚Ô	îÆOîB˜Ý'ò
+ÉX°v`í[”sjmË5›¶„6çßÞë|µˆlE_DjŽòî#-°`oÍÚÖ«’Ôy­k†ÓÊ.«(y{ ‰‘’·)	Nf—FpBrSü!rÕA¤ÝŸ¹´\›´îíÓŽD³N—   8ç^€xzŸ˜tóž<	"d"ˆl  "¤ê¸Åï&µ4dôênø(ÂY÷öGõ$+B$"{É©Xþë'´ A‚¹DhEçe–Â>Ù>¹+LÒsg“LÜ&cnÒ\_"Ò	 @I’³
+˜
+ˆô "Ü  ´²ç7¶Ò‘¯b¬€9…6iíLKÑ=³ÉjNª{¤Rd«·{­«ÿǹíÖ¥lýùÚööÆ!8¡	$ÈE¨£IXö' üé1¯ÐI´-  º”í?pÎ}k(y;17é3  mò†u¼ëÐfRšÂúsÖ©ã€#^ËJ-£éoEˆÁº´ã9ûv¥D;Ð
+  Ž_r  þF6ȹNhA‚	r™HuĆ¯ýB½¶Ïÿ^ ˜{ qŠ©ü“YË'‡$H W}ځE×Ú†ÿ"Á	-H A‚Ü'´ A‚	rSœÐ‚	$ÈMApB$H 7Á	-H A‚Ü'´ A‚	rSœÐ‚	$ÈMApB$H 7Á	-H A‚Ü¥¯‚ü³`è1}NÿÕn.D¾ n°Š"‡DÞŒ®µA®&MS=" Ñ²[b¥^è›kOnɵLð‰’Bp%àf…Ã_vÂÌ„ŠVÜ~­írõ¸¯à-©  ø{]LîOô    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/documentation/pictures/mpm_stack.png
===================================================================
--- trunk/openchange/mapiproxy/documentation/pictures/mpm_stack.png	                        (rev 0)
+++ trunk/openchange/mapiproxy/documentation/pictures/mpm_stack.png	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,109 @@
+‰PNG
+
+   
+IHDR  ~   Ì   íM®7   sBIT|dˆ   	pHYs  
+×  
+×B(›x   tEXtSoftware www.inkscape.org›î<    IDATxœìÝwxSeûðû9Ù³ištïIKK¡-Z6²—™NÔWý9DEEÅ-(‚Š¯ˆÈÞ{hY-´´¥{Ùy~@ú(Pš’ÜŸëâj’ç9ç܉µýöŒûJ) d
+„vN•]+†¼´µþæ±µøøÊœ;W|mgíÍcë>ðó‘:×ÜnLâèW;êý5·ŒÍ÷÷;xՏžu¨ú–±¼D׆1o«º—±õwòˆê±oŸ¬luLè ûN\ŽŒmXÐٍÍé'ÌM(¿yl㧡nK`˜ðÞÙ²›Ç6}ÖÕ…0ÓíÆ€:ñý‹¥·Œ-ìæ”’‰$–Ü<¶ùóîN&£šýÄüä¢{û*ÚÑ iäLþ(å–±m_Ç*ÕMUü)§ÜÓØ7½êÆJAkcÛ¿íçШ*O]‘wóØŽïÉjò%·«Ê“Ný43÷汝K†Ø«Ê³dS?Ëʹyl×ÒQ²ÚÒùôÏr²ïelÿòÇ¥‰ÊéŸåfÝ<và·É’ò¼xDZsŽe‹å^´­c‡VN—æœrú̺E@/S˱#«_gtî1þû<ÿˆÇ
+-ÇŽ­EX˜¼ÇåNc#?Ìî5ㆱ3›f
+²·¹†
+šSÐeÀº–c	[æñ3ίséõBa·‘hÛ:vq×g¼+§W¸DN-Š÷…¦åØ¥#K¸wî¦×ÖPJnþܲv¬?þØÒ5 ô@ìˆ7É|£¦¾Ä™g2QAËl6ñëúعÝ2ÆâX~]'Þ~¬ÛäÖǸÆ;|<É<oãò$,Ï°1D$÷æÞÛ˜˜í:šˆä>·Œñ2–{ç¡Dìàwoc";¶[Ðp"Qøß2ÆÉÙ.AƒˆTØʘ’í4à¶cÎ}‰Ô±Ó­c%ÛÙ¯/HnH9N>½ÀΩ3ç^Æ„R7Ž£O$ÈœÃnÉ\9JÏ(¹ÜÛ˜ØÞƒãàÖ…È\Ão]ÎÞ“ëàÚì[˽9r—ÐÛŽÙ9w¹[·[Æìü¹Ç »G°o“ûp¥J?»GÞÓ˜DÀ•È܉ƒg÷[Ǿ<‰Ì8ôcQÊ´yLªä‰í\ˆ[È6%¬ÆdN~<¡Ä™x…e†{ã˜"';ÞqÌ»ë6ÃðoøÌøB±’øu›Ìb8ÂÇýy¡ã×}:ÃpDm³sàóøvŒO÷i‡gwØTîÃ7µÚŠÜøº?þØt÷Ÿ,Y‚{üµxnq£«¥k@u|&06­ž-½e?B¶€±t!„B¨}`ðC!„²üU „p+.°-]B!Ô‘aðCÖB™zâ'©¥‹@u|zM
+!„Xº„,÷ kQþØ\üC!tGªÊ<æÀŠq   lç‚lþ¢DVRj:-]B¨cã‰í©GçáU  ½ëd„¬?„B6ƒË—ÒÈÑŸ4RJõ–®!KÀà‡B!d#0ø!„BÙ~È*`;„Bèî0ø!kí\B¡»Àà‡¬EyX¿Yõ–.!Ô±©*ó˜­_v÷$„ˆ-]B–€ÁYJ©^æj°t¡Ž
+Û¹ [‡Á!„ÍÀv.ÈÖaðC!„²üB!„l?d!œÚ¢dlç‚BÝ?d-/ûÛ¹ „Bw€ÁY‹Šà>ÿ‡í\Bw„í\­Ãà‡¬¥T§ðˆÀv.¡;â‰í©{ð jÀv.ÈFaðC!d3¸|)ûe¶sA¶
+ƒB!„À« º®ºø2'å菖®!t+Ô©)jÔ§¥–®¡G?d!ìñï^dIŒ÷»Ž¢ÔýRUÑ•—ŠàÆYBèß1è›xe%Ç2`ünéZzÔaðCÖÂ)éàWv}¦­¨þ7+áó쌣Ǭ¼ü ŠBý{Y™{Ožú’eé:²xŽ²•z¾ ²t¡ŽMU“Çlÿº'¶sA6ƒ²
+”R­Ò·'^¥‡º#žÀž:úöª ¥kAÈ0ø!„²\¾”öœ¸XE)Åà‡l?„B!Á!„BÈF`ðCV®/ÏÀ«þB¡;Àà‡¬…SÒÁ¯ì,]B!Ô‘aðCÖÛ¹ „îJU“Çìø&ÆÛ¹ […ÁYlç‚jߎ*<"ê Û¹ …Á!dutZ«¨ðŒÌÒu Ž‡+Ñ^S–Öc;d«0ø!„¬NzÚV·¿×yËÒu „PGƒÁ!du¼|”xì‹•–®!„:¶¥@èA „°&ÌOa$ö^&KׂnïïucF‡w›qîâù_{jµuâа'Ou˜‘³{ÇKýªª®ºw
+žp¶gÌ›i  åÜCûßî]U•æI)e\\"®ñcÃp( À?'
+
+—’|鯈¦Ær/ŸIûò @}]¾ 3cwp×nÏç  l\?ndç°©‰—WwW«+e~þÃ/ôíÿñ% €Œ«;®$¯u÷ˆÍMI^×ÓÉ)<{èˆO;òQxNöp  þÃ{÷Ù W3ÿlž224lú…Î“Š  œi0hÙ]»=åðÁ¹Mœ´y›#0 TW]îÛóÆ°	OlÜÆåIŒøÈBè¸ÇYçÄ=Ÿâ9]\AþÉ>‡ö¿5M*u¯”J=ËŽš÷ÊŸ«NW««Ånn=®ž:ùÅÓçÏþì P[“-Ôëy¡aÓOyûHÊÊÜÛ{˦©ÃÌëÊÏ?Ñëàþ·žãñ$jG§°¬Ä+žØ»ûµ^  5ÕY’‚¼1ÿÛî‰ØƒûÞ|N(TÔ;8tÊ?¿dúáƒïF  T”§8ddìz6aÉHW·è«n½
+÷ïÕã\ÂÒ©ry at QüéÅOÜÿVw6G`’Ûû—Ø;땪˜—xq¥ÏÅó¿M
+•åè¦*/¿r*î«PóvãN|ÞC¥*vÂЇê(p²Uþ=žÅïçG€·ï ø£–Ÿ øq±W¤Ñ¨çLšº} @EE²GVÖސÈî¯d¹¹÷¬0iÓ €¢Â32½^ÍIOÛ2 ö˜×åäžüø„¿  ˜LVFúöÃF,=ÝÚv]Ý£/Œ·ú0 À?'qÓ®l`ÞCh4h…ÿsµ³Kd ÀáƒsŸövpôã¿ زi
+;5åïÁ
+ùöìcC¿;[\|6ðïucžTÕzED½´ÁÇ÷±J  ?¿¡'Ò®lîmÞ›˜“}(¶kÄÛʉ&9¼b’™“b ”6Xº„ÚîñCVRªqñëí\¾¾C²ÍB‡JGÇ°,ós‰Ô£²¡¾Ø À W3ÿ]Ñó™{¾·mËÓ3²3÷öÒinØ«ëêÖ£yY?ÿajuµÓí¶ëáÙ»y®·ÏÀæòùöåæÐG©‰hÔ5Ž¾~C2š×0<]£©UšŸ›¸~SuUFg‘عhÀ /.˜_ïÓïÄúú|ßü¼cÎ/÷5µüØ>ï&ßÛ'„&lç‚l?„P»bXìæó0	J†¶|n~|ìȇ:JòúìüÏÿïõ«‹‚;?q€Þ°®úº|{ó㊊T6›×t»íÖVgË͏«ª®:°Xÿ›ËbqšC !e³yMU•éÍó+ÊS”-çïÝõƒByi]]ž_ꕍnæ×¥vž'çnçÏœú.ærÒ±ž½O³X<<ï´Áv.ÈÖaðCuHª†b›-P ÔÕæ
+®¦m‹¹yNAÁÉnµ5Ù‚ÆÆrnÆÕÑr‡ +·[_^úúB~}}!?'ë@”BrÛ¹Šà”ÌŒÝÑõõ…üšêLafÆ®ž
+eð €øÓ‹‚
+òOÆNxbãòΡS·Ø;{FCC)×¼ldÔË'
+âbÊË’»öŒyëÔ¿ûBèÁÂs¢BRLì»ñ›6Œÿa‘Û|£QÇ÷ôêW__èÝrŽLæ“ÿß=ߧÔÈâò¤5'mZ~»õIí<‹W.|ßdÒsB‡²a#–î¾ÝÜá#Þ¶yã3~ý)ìS 
+b‰kþˆQË·•–^”Ɲøâéž1o¯qqªsqŠ+->¸iÃøÉÏ>j
+ @Hè”Â#‡ß¯ârÅ
+î15ìA¡€ @¤¥‹@í®žRšq÷iB3åãLW¾Ôù¾«]>ôCEÊá7§NßsöAÖ†þŠò±ƒ"°ÑÜÆÅìûï\>îÛÿã?»>›[QqEììÜ­þvëXôµâóa#–þ4¶¸²*íŽs[ª®º*$„{¹ÿm!ßÌ W3Ë–øÍïÞcæƘÞso»Wµ]VæÇ“§¾4›}äôf4±iõliíƒX×£Œ" ÜdsØ‘®Šg&…úVZºÔ>Œ&JþHÌh€o,]ËærzË›ŠÆšÂGïя]dé‚Ѓ¡tì|Ç+/Y,ž©­AŽÍ´y. €Ü!°Í àÌ©o‚S¯lŽæä•úPG'ò°Ѿ³‹±t!¨ÝÔ^-³…vã«Ñ!™–.µFõGb†³¥ëxª‚z>ÏI9¶¤6õÄ/»¯œøYÀbq2Ø<ñY¾X™èàžÜcü·Ù<¡O´·~þÏ::†µéPª_ÀðCrEP›ßýR««Î.™={͹ø°·…¶Ù¿r¢;™“¬§”6ZºKâˆx¼þ«ŸNc‹xØgÒFì¾,wñ"«@)Õ<·¸Qç40ñìö÷†¥ÿi£Ñ 3ª»èšjë˯’ì¹‹Ãæ
+ÏóDì“#†ÏO“»…c˜GÐ豫Ž¶uîØqk=ÄRšµlí‚:&OLå.U5EÉøÿ=²IüÕé>æógßØ!ÇÖ<û›Á ‰¦Ô$1™Œú º.H§©ÛP•k*¼²W@V9Ãâf³ØÜ|©Äݾ¡¡”+;c«„:MSµËŸs•k	‹]É°¸Õ,6·’ÅTqy’JžÈ¡J¢ð©rï4¤Ò#täÏs2;í׺̳ëñÿqd“0ø!«¢mªfÒO­”W%)ì]C©)I1tê~ ”sÃDJEôzO8j2ºMjW“AÓ åÔ¥ª›ª0ø!ÔÁp¸¢Z;çN+õ•ƒA§v04
+ƒ¶Ñ_]_ª e©ò’ÌcŠôÓ«  „0•„aU1»ŠaØ•‹SÅ°ù•l® ŠÃ—TQj*"s’²  ‚Rª¶ð[ûW!a B)ÅÓXP›`ðC!„ N àØÊ×æÇ„0.”šd„0õ„aU†UI€èh«ç.B( ÃåIv*½£W;ûõ)¨H9üæÝ.&@µ?›§9ûÈá»Í+HÞ%,LÛ¯PUåʵ
+•
+V¥0êÕFƒÆI¯­nª-Rz{ p  %!D å PqÓ×Ö^«è€ŸY FÙ
+ ¿Y[ÇôàaðCA±‡Öƒ\k_¹ð¿Äå Pvýk œ¿þ¼2tÀLì5£Jâàc  8¿ë#§äËÁ
+ßçDL,'M,÷^3éÇÝN¾±Z€kí\úG=T¡#›<BGæ@þíæ´lçB‘µŸ5Ê›¾z@ÔM¯)!MÐö XI)5<„·ÙŒRšHy ¶À›„d ø 6RJUsÛèÑ„Á=„6Ü´î_•  †CœùkÒͯSJëÚ°}·¦ú{sè+JÝ/H9ºäïëç÷QBH# ÑñDút°¶ÇøoàÛGÈæZÆnGG)­€z ¸kwB ´  æ¦×䄐z¸ÍÞC¸50VÝÏ![JévBÈ{ ð tkÁo!d ü Ç(¥ôNë@¶ƒº-BˆZ9¤z›¯R ¨„ÖÃ\êͯQJµ¸Ü*¿Èi  ƒ^MŽ¬~òW“Qï@´l®ð½kçUC_ÙÇæð‡Bÿ’N«b>4/z؈¥§-]˽R×2WMv#s’ËõðTsý_úÝæB CëA1 úÝôš!¤ÚḱŽRúåõóý ñõ&À0 PB–ÀJJiÞ½¼gd}0øÙ ½ÉÄ'„„»‡9
+­¹ ˆ»éõjKž\lnç °éӐ·MF½³Xî5¯ëw·øG?ÕæÃMM•dú1íz7½®ATV–4ÐÝ#vG{n¡ûUW—磪+èRW—ß.ç»™Lz¶Á { 
+±Y<1•86V&=ôv.×&V^ÿwW„ ( õ ÿû#ÜüšˆR--@ ðàÚ¹ $×ÿÍ€·	!—áÚÁd¬±¥+º~6H­7( `>Üæâá¦sè(¥ÜEYçÖI}zîøܺ¯ïuYßÈ)µ ðíC(ëŽÊ²O¹‹u½‚û,nïm#t?
+÷Ç-14ö·€Ÿ…RgM{lS qz !“+Ñ¾ÓWÔæœû»£]¤”R#\ûù[Ö–ù„\æ  £n3{ýkw ø LªœÊ+©ËOþ6gÐ]÷^"ëÁÏIyÜ¢úÆ™–®ãað‹šªò‹ššz?ËŠdnÆ°AoV=èšî¦±¶P &Kl¡ûqa÷‚0 €òìSÁ£ßŒ;hézl¥T Å PL	 íékÉ  MpmO  ²  -ä‚,عMw¿)Ü—ª¬J,PÜüz—·K#,涧ÐT_.ìNñ  àÉEÇžÞò0·{Ú©ùg‚GcQ­˜N}üJœzùÚü}–ÿû
+~/n;ѯXÕtÃ7€‹DX¹blŸcwZî“£Ââ+	*ãsU>2IÅ“áWƒvm¾æØ¿ö?n0Q‹!Æ(WEÖ+Ñ!iJ!ß&;°ŸÈ+µw“5¾ré#݇
+!ôèHØúŽ¥&;  Uuî0 Ààga„9 ð5\;¼«‡kÏñáÚE+I p ÎÀJi©y9û`—·]úú·éÎäï÷¯HÈÄ“‹n¸0.tæ€ÏYw~ÙëϤ,=6Säj—j2˜8º:µa1zïñ]7Ç.›×–m'~¾wª®VíȵT\úî ‹Çiì6ø¯^ŒÍiËòÖäøsk¨rªÜGµæ~×q_ÁïHNq?.‹¥ñ±—dÝËrGsKºdUׇD¸(âË4‰%Õ]–%¤¾2<À}óÚ‰ö·i9%wq–•xµë.gXt*yöž§†Îéåádsüßθçb<œÎ.Óû„¥k±4B3ma!á
+dxñBQAÊî „P¢×¨[º[v½›Â ð ”À 8výëEJiõƒÜžÈÃ>u|â{?Ün\¯Ò°
+÷¥:B¨×ã]JÍ{Y<¶jbê‡_™ç{{·”¥ÇÞ`¹Úߌ;g~½>£\Xž'wX.t±»áP¼²‡ÏñÁ[þ³ `[ô×/§ývrh§c ÐV7rŒZ8JôyÛ/;+"=jÄžòNA0鍤è@šR[ÓÄõV‘ðo¹?±®VÍÖ7hY"w™¶`wŠ£ÐÍNíî® (9–!׫´á!å7ïá,:¦àÉ…:E¤g}}F¹Pâ«PCò«ù|±ž-âo^ËϬ`wŠ³¼‹[­,عñæzò¶_r•ø8¨œûø×u,mm“D§ÒHëÒË„m’x;Üó©÷}¨·›‹Câíš‘R²ðØÅÐÔŠZW{¯ñÕèÄÎŽö
+  Ž"Aá–©ƒ·›ç~u2)ø³c‰ó¾»”ÿVl—4 €ôÊ:áÒø”®õZ½`X€{úÔ0¿þ˜ê{òµ3 ü¿ßðáW'.õÛ:mð6 €¥ñ)þÁJûšäòj‡óÅ•žùº]}ºkÀ
+ýœ–ƧøÇVøpXŒá©pÿK|\où‹gù¹4_7‰°±¼Q-8’SðVlØ™pgÕ†äl·=ARWýVlØEO;qó‡¾3=ßiSJN¨¯\R>!Ä'gkZž×û}»¦è&òþ¡s‘Eç\ÿ†Yq>Ý[)âkÆvò* ÐŒÌçÇòkê#\ùsbšϹȯkà/?›œ]Sïä-“”Ïêš|"¯TÑ ÓËÒ+k}ÞÙŸ îìh_þÌMïÓƸÄoy˾ϴôBèFMõ¥cÌw¡@…Çÿœáß÷ÉUwm…‚ŠP X o[úœìsìè–úóñ—»‘-àÔ_øtwííBbÔÂ1+ÎçïÉùûü8sðÛ?æçq%G2Æqí…Eº:µ³ßÔ¨U½™ÚêN
+i€2»ähÆóó/þ5´æJI¨¾^#',bÔÕª]}'G®êóÛôc  Wÿ{ÚëìûÛß0é|ž½°äì¼­¢©ùçݼÞÓ³6õ-‹ËŠ1Œ\“ÞÄó²Ûwrdʉ—þzÝ Ò:£eØ,mÿ5Ï|ëÒ/ Z[ÝÈÙÙoñ5!,!·Vꧼ\TØÄÁ™3•Ñ^u;û?/ð™›#>y	  þ-1e'3{N¼òá×  §^Û“ù×Ùç¸RA©®Níªˆô<8âàë  öúy|åùüÞ\;A¹¾AkïÔËç¸ûА”²S9ƒ¨ÁÈÝ3|Ù\žLP9î¼ïõ¿Õ?ǯQo`Eþ¼åí*µÖ£›³Ã‰"U“óW'“øŒïßê္½ÃS×&e]Ü’šóVl—´¸ü2ûñë,qØ5Ž"AÑÖ´Ü'ãòË~[:2æTk˳Æ ÒéÍ—®ÃO	©ãµF£ÀD)ÛY,Ìß––7=¾°|ŲQ±q  }Wí|æriuŸ0'ùI›Ñ~q"Éq€ë†›×ûë¹Ôáu½ƒÆ`:Ø].mPó?Ûp¨ÏÑÜ’‘!JY|e“ÆqSJöÄ#ύš¤°kúêdRðÇ“Þòµ—$Æ•wÿ#1ƒ«6%ï÷íúv­VÇþ)áÊìwû„?+ðô×ÖŸ6ÌÝNT4¶“׎U7fÅö  üåÒÔoâ.
+ß“QpöÀ3#ÖU4i8‘¿lý.ÐÁî¼RȯڟUØËW.©)kP‹´£¨¢Iã˜XReþËÈ–ƒ_µo·‰œ»OCݯê¢$ŽQ¯íÞâ%¦,;n ´¡^GñoÚ¹t4”ÒÄöÜ^Sqÿ–ˆ/^7?çÉEU#¾ñWy|Žìʲc¯ùNŠø=ö§)'	‹¡M%uÜ;­Kå•Qq&g( @êÏÇýJŽfŒ‹ýeê{þÓ»žû`G·”ÎôyÅu@` €®N-ÉÙtѵìT¶{ÉÑŒ!òp·3-××XPÚëû'>z!&÷úòo¿Ü碬“sãÙ÷·¿!sKxlÓ›8¾ñNµ5•ÔG|<òÓ.o=– °)ø“¹oyÆð}¯L»ýðTü››§<~îÝŸNÏÜØ_W«VŽ<6{–}ˆKÃÞá˦RmÓï¡üÉNk^ìõýďŸë•WŸQ.Üóí7I_îOò2:«,.kä¨ã³gšÏ‡ÔT4pøJ±¾è`êUN•×Øøw–·e;­¹ïà·ûjÁdÅ—k7?tUÛ÷ôð
+ÿ·#®•Zë‘=kòç–]©­q“
+³kT  :7J.৾þÄ—  /ï8™ºîrÖÓ_
+‰ŽqØF €miyÝÏ–û\)¯íT«Ñ:}20rõÍëÌ™=e> ÀKÛO¦ý’3u٨ظE§.],®¼÷éá¯Çz:Ýõ„V½ÉÄ+|kÚ\ €c¹%ò}™…“V=Þ÷½‰}Š –mžóöþø!Û§
+Ùúë¹´Iý½]¶›÷<F/ßúr‘ªIÒ–÷ÿÊŽ¸á,B™³& p¾¸r×€ÿîZz,·dßáœb‡]÷ÂèU7/·!9»õ^C)U›Û¹ „Ž3›çD:J¯_!J)_ÓP9 ~µlemמí\¬
+[Ä­qîí×|h–k/j ÈZw¾aˆ>féä“æà7ª½e]ŽŽš(Û¤7’‚½WÂŽ’LÿéÝ ¢>}1íדª¼-‰®O Ô\.Š93{S˜®NíÌWŠsmx~KËõñ䢂 brÍ˧.?Ñ”½á| "Ò³D_¯qŠøpø~óáÝ;ÕƵ›CŸºLÅm(¨	³s½|zÖ¦0™‹ËÖÖ”F T%…ÊB\.šwz1öXù™œ‘mù,³7œëÂóª*/¸UœËw“‰p¤üŠÒ¸¬Náï¹Âó*Ž>µúy÷¡!'»}0,‘¯?°ï×û~ý}\¶½Û'ü¸ù¹“X  H­¨
+K/¶5ô è&›!: €üºß(WE‚yì•îÁ‰k“2_:‘[*à^ PÕ¤U4鍂҆&o©8ÝÄÌ:)dÉæÇÏG]Z{)óåÓe²ÓåþŽ"Af[B @Âî’ùñ®«¾,†è¾<ü»S—	¥”QiõöuFJIe“Æ{¨¿ûŸæù==œ’6_ÉñkËv2ªëL”²b~Ûþ &J	‹ÝñÜR·—£‚SWžOçz-Z·0ÂEÿnŸðã=Ümî|F„åÕ•_F)¶|ÍhÐu.JÝ/pòH\dÖ‘Û¹tt\;AU¯%“niÚ­¯SØ"^5Ãaµùëš”wŽ„_ÁpXÔШp¤üNÓáˆyÕz•–o~îÔÛßà-ÿÙސ_ÍßûÝ‚ÃSÿ;vèÎWþùß|î
+¿×9"^®^#P—©„„Åèå]ÜêÛRO.l¾ø>A4    IDATE•[) ¢WiEÔ`b]¯«É¥à  “Ö à+DÍÛUDxÜ1[P½‘e~¬«×ˆ ÀÔTTÛ|«P‡p÷óŠî^Ù  £ãÞü8aîÖþ9/Œ¹ºêÔŒN/÷ù-êÓÑdï}?!‡­i-€0LFJ™{YWN­*ÀK&Î  @¨ÑD›?­ÑÄP `1¤ùjFDàž×ztÎÌ®®ĬØñÅ[Oôÿ︾GÌã¦Û×M  ‹a(CÀd‚ÿ­ûnìùܾQX„觅ù»vמkœÅÂF¹V›ÞdjÞ®ÁdjÞ‡a( Нže>Ô«1æqœÄ‚éáþG[lîð@׉P—÷æÔ¹Ÿ½Ðe_Faakö~óÙ ¨¯^yd­ „¬ƒNS? nøùNh/ì^ë<¯îµQÝ<
+³7^ð,;-kK«•ÊóùÒ¢Ci#{ø ú)
+s’
+{›ÇkSKEêŠ_Y°óú›—{Ê5üùÌ››?*‹Ë:âëW ÐTR`ÔèŸcªK/jª½äa®%.ýKáýí¬”%G;u}Xʽ¼/Ç>µ,>§NèbWÙwÕ“Gnç;JŠk¯”À~ €´§‚[Ž”ââš”w ¸ P•TØÙ<&uÍ+=–1ºÇ¢	Z»@Cì)×\7c/ ì=2í¿Cs7_õéèDŽ„¯6j
+ü›çß‹~Ž_¨“<}kj&
+çnmVõÖ“›ŽŒ¬nÒzþ2º÷2  {qÆåòš.FJw±¡?Å_‰pØu}¼œo9ißW.U?Ó-`ÍÊóéÏ—¨šâ\$B @ze]¨‘ÒM,Bèªéá".»*ÚMY××Û%c÷Ղ鲊ƒýÜÚÔIÝl\°Wæò³©BÁÈ6_„  7š €£Hµ?«0썞3  âËÃÍsd|®ÁAÈÏ[“”é÷~ß®)e
+jn~]c¨¿ƒ]& @°R–—_6à?‘Vš/þ0RJÌëç°º`@dÒ‚‘IQ¿leÎ.îôjtH¦½€WUÕ¤±»—÷B÷#aë;nÔd2ï0ߥ‡¡”ŠUU¹ÃÛºX=MEƒÛ¾‘?MhùZ¯'íîüFÿŒ´ßN^<<iå».òDªÆâ:ù 
+Ï_Û3¦7òŒûuŒIgà¨ËUŽõY•ÝìÏ
+\7c @ÔgcÎäm¿<nsègo9Æø&H,t‘¦uygp«=Yƒ^ˆÉM^räÒÙyÛÆŽ:>çw  †ÍÒnújŽË€ÀS»S]¤é!¯öË pŒõÝ™¼äÈKgóÙ9V_*ò¶çՍmyÏ>º®Ëù'qÊž!?:*»{]UåT9êê5¢¡;_ù'lÖÀ}Ç_\»`׀x;–Ïè„4ßÁJí}9gã…IÇžýC«Ê©rS—©<¹vüJ €ÈOF%fo¼³{Ð’¹.}ýóD
+U‰…þÃ;_°rª½ôõþáN±~—  *ÎæuWF{%  øM‰JÎý'qځqËLj=åå½~xâLë•ßÞ}¿Ã9ÅÃ~ø;Úü\ÊãÔœyܲ¥#cNœ)(
+úaãÒ¥,^k4òüäÒœõOÜ [ÛÐ9øÇMsµƒ°V£w¶p‹?ù…9ˆ}=¤Ç®Qk÷Í÷^´þK¹€W’[«
+)*xŸÍjõv`_
+Ž>¿þrÖø×w²iÊc; ØÑû,Zÿ¹£HPQ]×ýÅÈN? ¼’¹%5w×Ä
+¿	t°Kà°‡aôÇfŒúãnï·—‡SíøŸÕ%¾µ:1#U)ä—Ö7zwwS&¬8`ÿÌž×Ï?tþÝ°e›½5£ˆEˆ¡åòÑnÊSߟNþ¿m©¹—KÔÞön‘ylù˜Þûc~Ûæöí_?)ìÎL”[£ê|ú?cæÍ?t¾OBQEwo™8«^«—æÕ5„,ÓûO €¡þîç–œI~©Ë²ÍÝÝ”W>Þ÷è½þw´„òô—•„áò±BAAÊî@ÀL„& L¥&1P*Ôk±­‹µséBrÛÛr>~vîâ¸ÿÛЯ6­ÔO•]it| @åUêã»×¤3pXŽÖ©—Ob·†oñÛ¥ù*_)֏<<s~ÂÜ-Cj.)£½OõþyJó.‚â¤~ŠvÖD~4r}ÆŸñÝMz# ûÈ“ÝÇ—Ëèjê’Ôû—©»Ís‡ï}íï„w¶d—ŸÉ	-=ž©tèê–­pŠõÍáJy7œ²Ð{ù´ò.n%¹[“ºL‹æ+Ä•¾“"Î xOèZ¢«W/¼úû™~%uʘ'ÿtxÊÊæ»Fõú~âi‘›¬¶`wrw©Ÿ2?à™Ç+ϸ CÇ_|ï‹S¯ÿÝ·.½Ì€ÔO‘ç9*´€-âEîö%%Ç2"X|¶ÆwJäήï½ à:(¨ª÷òir·$†jªÛtÁÍH/ç/ö<5ìò½,ôß‹W½ÊÕ7œç!ærô-?.9“R^ã¬ñ^Iq‘u;ÓóR*jä8‹=Ü+[kÞ\¢jâþ|65¸V£ŽòÌh¹wî»S—ƒÆuòÊoÙ´ø@V‘¢ ®A<#"(7äÇMïÄz:Å÷÷qÉ:]Pî9È×5g\°wIËõ¯½”é—_æ-`³u3"¯˜[Í´ôwr¶›“X îçírÞÆ#9Å;Óü4§›‹¢è…È Ü–cÿ\É
+QÚ—©‰|q"饢·¦½m?”]ì°ëj¾ß”0¿ôüÚ‘ƒ§mÙJfi|Šry‹„ËQ?ê›í¦¬Siõ¬ßΧù§WÖ9*ìÊÿÙ)³åù“µ{í¥Low©¨ÁÜæNuV¿U;S+j¾¹ÛÜG	!ÄÍ/jÊ#ÙÎåÌæÙé§WmzæÛº–®¡ÛY3Wñ·Q¯‰!„©˽ªëKG2l^¾NS7(åúFLô¨´u1±iõl©ÍŸ+mìòö¨c³JÙ"^›ÏÉïˆNømTCAµûã	s±t-«¥s~7·s±t-­Ù;|YØ}íñ{®[`ÞÝæ\?ä™ÑòµQAže£‚<ïzB‰P÷ÉÀȤÖÆÞlÑßÎìz0¼á¯é]ü§wñ/¼yîÝÆÌ&…úµöú תÖúþµ;p-ÄÝ<>È×µjïµe£Ý”·|S\ïMxÃN	c¼ÞÓ¯Õ{)Êø\žï  5ž¡cîØ> !tÌm\aê}#§Œ®+KóRח´……óþzßtêÚ§•¶.êÚBæàïÓ\Éœ:Ji›ï…µ¸§‹0îRQ¾‹Dhñ¿ä”"ÚM"¼§;› ûG)mòê2F{÷™¡{u­Sëß}úˆ>Ó~Ín96maá<®@ö‡¦±jÈí–ïH® Äö^j x¤÷r¡ÿyló‹;;ÂÞ> €gê=ÛQ÷ö™Y]ðÛÿÌðõ·Û[Øž&‡ú%¼ôx‡øFD¡£±®8Ø¿û´q±S~Îmm|ÚÂÂyžøBAò.akã	Oè`ê÷Ìï5”RüCÙ¤~U/B!ëÒwúŠ5N¾±wJS>Éý¼,;Ž×^5!„îÕíñC!ô`Ý-ôÝë<„å`ðC!„²üU „¸øë¹¥ë@!„:2~ÈZÔx†Ži´t¡ŽMS_Êìþa!¤Ã_ˆ‚ÐÀÁYlç‚jÂæ€ÈÎYØÎÙ(v±ªI8}Ó‘à»OEÖ€R MzC…¥ë@!Kà	Lýž][½z¶ÿP€Œ?¼	›¹í­Øu1¨uBvVuýYÕõ–®µ/Ãݧ „²fµi¥[ãßþGjé:PûbSJU–.!„Bí‹Ršq÷YÈÚà9~!„B6ƒ²
+ØÎ!„º;~ÈZÔzÀv.¡;ÒÔ—2{âŒí\­Âà‡¬¥´Ñ»Ûx¼J!tG„́D©lç‚l?„B6ÃÜÎ…RŠ("›„Á!„BÈF`ðC!„²üB!„l?d!®'Ö¿„í\B¡;Àà‡¬E½kàÀ&KêØ°²uüU ”6øELÖXº„PÇF8{= ˜,]B–€Á!„ÍàI”¦A/l¨¢”âŠÈ&aðC!„²üB!„l?„B!ÁYBˆË©
+ÿgoé:B¡Žƒ²*GïÄÉÚ½š<Èy¡¶ÓÔ—2û–Žp"„,]B–€ÁYJiƒgÔ–®£-v.î;*aë;nwš³cQïAqë^h¯š²„°€Í€Zº„,ƒBíLâà›zrù–3›g{´6¾ý»ØÁÕÅ—¿ŒúKF{׆µãI”¦A/n®Äv.ÈVaðC¨
+z~C
+P*N?µrçÍáoÇ¢Þƒª‹’V²9‚ólŽ ÷H „z 0ø!dl®è0¥&‡ôS+wÖ–¦¹  ìXÔg`UQÒr  "{.!„Âà‡ˆí=öÂ4Pj²/ËŽ[”ŠªŠJ „†ôý¿ã–®!„õÁà‡¬Â£ÖÎ¥sÿ׏SJù À¢Ô$¥Ô$»ú ;+°çsõ.!„Âà‡¬Å#ÓÎ À?ú)Ãâ\½þ” ×[·=O$ßa©º²všúRfÿÏc±²UüUx”Ú¹˜ñEò D{Ët
+ˆƒ*	!«GB(`;d£0ø!d!
+Ϩƒ@ÀÐò5ÄÔïé?R,UBÖŽ'Qš{y[¶sA¶
+ƒB2pÆú+È
+ÁÍÅ6.!„~Y›+:×9B°B¡‡	ƒBt­­i  ¸ØÆ!„ÐÄÁYBˆó©¯?2í\ÌZ´u†ÅÎÆ6.!„&~ÈZ4Éݹ“µ¯·uÉ À6.=|ØÎÙ:¶¥@èA ”Ö?·¸Qlé:î—/=¬i¬
+´ö6.ªªv܆W»YºŽ‡IdçZÝgúŠ,KׁnÛ¹ [‡Á¡VìýiD÷öÚ›'*€Æj^Û l¯í
+Äʺ~O¯¾z÷™NS]1KνøØ`¯êöÜn{©ªhǝ½” íüJ2Žò“|ÖÛº™ZUH©Éîa¿Ú9”õšøCþƒ\§¹ËêÙÒGîB?„Z!ÒfMÙÝ·²}¶æ{Ô—‡uí±¢¶Q-ŒK¿œ íü  ØÆøÆÌØvßn{Ø¿7ÝùäÙ4Ò^Û«,¸ É
+&„ôu¯i¯mšõÞ,Æ-A ¡Ö6ªKT²Ì³çŽÀ
+~Ù:~µ‚!@Þ˜Ø~eò .yNöíÝgþ{§.ç(Ne\l·€‚¾ˆ«1Ç:ƒtÜŸIÞÙg‹-]BV/î@¨h¯Ð‡BȶaðCVâ|fÓ,™¥ë@!„:2~ÈZ4É\:ë,]ê˜Î+´×hwýyg2QrætžƒÉDñPø\=•ç@ÛðtF&ãt¾¼=jj+­ª‚9øËX%!„oéZ²~È*PJë;žØdé:þŒÂJqIU}›~]É-“TÔ6pvMÖâééëÞK¼Xt×ßõõö“ÓÖ-(*ªÃPpš-kñ¤ukÕw=G<ç|‘ìû)ë>lºÚŠR#˜(% €áÙ$~uoþ´cÂwŽ÷hËÜW¿ßòì/Û΄?ìš²6|©³iÈ+ÛË)¥jKׂ%àU½!‹Û±ýŠÛÑ#YþAAÊÒ]»Ò¢årAíG†ÊË­-ÿ%¾/›ÍgÍîs4"Ò­Ö¼ÌÂOEÅŸÉïÌ°ˆqøðNç^z¥gšylË?ÉkVŸïËb3Ægž:Ñr[o¿¹³ï€~™#F lÝ’â~òDŽß·‹Fk­¶%?œ=z8+Üh4±ò¿8kvŸËësxPŽ¬:ïWšQ©ÊøM)‡³»Ù»JÊŸúnÄÁ+ÇrœŽ¯¾#”ñƾÛï¸['e  5Q²vîÞ˜ÜÄ’@.Ÿ­é5¹Ë™>OvÍi^ßÊsþg6%÷â
+8šA/v¿áó\þÂ?C>u. —gµynYvµÃ”…Câ[«mó'‡#®žÎïLB£Æ'<öŸh«¼*¡Ž
+÷ø!ÔF™öéÚ‰‡/d:MýdíÄ	óÿ˜¶õdŠ{mƒšóÊ¢†Žÿ`õô¿^ôi¹Ìö¸÷'>Z3eäÜ•3Þúig?ƒÑÔ|x)·´Føôçë=oÕ³_¬=Ñr¹•»?ÿó¯5¨µ¬iŸ®Ø Ö²Z«íÈÅ,ÇéŸý5~ÄÜ•Ï¿±dÛ &¾ÕyÕ•+eŽûö¦ß²%¹OL¬Wrnn÷Œg7<÷é'‡&*
+u:#ç?/nzÍ<άý7¬O×)Ä1ÛÍMZþÃ÷'žÿáû“¡  Gg9¾÷îž™B·)<Ü%óËÏO1L͇Å⺥¦–+ZnûlBA×Öêš=sû€Õ¿Ÿ×)Ø17"Ò=íßϏÿ쓃Qó³xò’JÜã7'N9’Ý-¸¯÷¥üË¥MøëÙ]‹âF{uuÉ®-U)~~nÓóüŸú{ô…]iƒý»»_Hy
+æxõÄŸ‰>  'Ö\ôùgá‘—¤Ž¢*—@‡Âõìªå¶2âz”fUÛ™Ÿç\,vÏL(èÜZ]K¦m“°%eˆo¤[º[°2gçw'Ÿ>ðs|ÐÃúB·Â=~µ‘F§g%¤ô/©R¹ôéâs6·´ÚùÕ{_ñr¶ÏpWÊJ=”yŸþqðU/'û/cü+œ»ê<wùîYn§ºú{gn9‘<lê'k]6.xj½Áh"“?^3S"ä×ï·ïlz¯’*•w »2  )«Ä£°¢Ö .  ¨µ×¶Ý¨ÑíxÆ–uí>“êúÎ/»Þèâu¢G´güö¸”¾“>^ã±óË¿·û‡ô/èõ&ÞšµSÿP(D:/OûÚÞßûæ¼÷.yþ…諍ál×.‹¾9w®Ð>*ʽæÐÁŒÇFÙýù—Ãã  žyj½`ÓßICfÎêüÛ¯ñ}<=eWÿükê  'g‰ê«/Ž¼~¯õ&²ooúˆ™³ú¬4ïM4MÌž=éý>øð±söÝ?x€ÌÛýì„!”a3ƽ?žþÏË+Ç>4°´,«úÊ'W,¬+oà
+¤|CúɼÃ^ëµjôÛ×öf~1üwÙ‘Uçõy²ëŠãk.öóu>ÿêê'v °¹
+GV{æ^ë©È«¤Ì4c阯£Æ 4ÕiD§6\ê7ø•éöÝ#„nƒ²
+„çN1/ÈzNü¾öî³ÿ±½;5±Ïe“‰’.3¾ëi'â×ÿ<gü> €¤¬âNÛâR‚cüOüº#¾¿‡£]ÆÚ¦ý àé$«ùdõYÙ%Õ۝Ïð¨kÔ(-~ék±€g|elLJä¾ÿê~êùiëé!a¾.çV¼óÄ. €Ç"òƾÿûÂŒÂÊM÷Î.¥RT¨Pˆt  Ý"Ý*  &O	Ï àóÙ&‰˜W“x±Héå)kllÔɆl>Dëvá|Q €Šòepˆc†ylò”𬯿<jº×z.^(’étFÁª•	ãV®H ”RÆ`4±©‰>{SÜìrC( €Gg§J6Õ>4° ÀÉOÞÄb3ºìsE|	Oo2š8±S»4f¾Qniçw¤
+ ¨¯ltŒÙéˆy¬ûã!GVÝ{î½z*ß(¿çxzÃPÊ&.OÈQýë7‹j3~ÈZ4É\:‹ÛcCcb;g 0¡v"~e¸¿k¶yÌÑ^\QXQç PQÛàîïšl›< kÎÂ5‡ô‰EŠÌ¢J¥“½$ϼ÷NÈç]Òì›·Õåµ
+®…u¼è——RJ	¥@X1\Î.‘?JÁÒÎríˆ8—Ëny;J)…HÏb1úÔ+åŠ~ýý*  ²²ª”<[
+  pÔååÍ-D/ÛSJ›OkáòXÚ•®ùªÝ’âúVۍxzÉš €.øtèïÆ•< ·ÙnCn»-?ß–žv  ÙŠäîvE  •ùµJ.ÿÚçÉåsÔ5->£¼K%-—gsXÚ¦:
+Ïü¼®¼¡ÕÏSîn×èkNZææ\¿ïëßÒª*˜ãë_T95”R¼_/²9xŽ²
+íÙÎ…Ãbn¸¡.‹aZý…*àqšÊjšI&ç”J
+F×Q&n²ñÕõMš~AÖ6¨›ç
+y­Vghþeš˜Y|Û^hB§¡w˜÷‰„_Þøüìò™Ïý:ó³´5ïÌß7Ì*ïqÊ0„úøÊSvîLíQYÙÈMO¯ÇÅåFwê¤L ˆŒrO½š^’x±X¦Ó™¿%Ķ\>8Ø)ãlBAgƒÁD2®VŠÏ&´zΞ““DëåeŸöÓ²SCJJ®µÙ1LäØÑ,å×íGée¯¶w‘dûý|Œ¦AËÊ>W$˽Páî’ àÕÅùJîÅ’ð’«•bMƒ–ufcrÏ–Ë;8d$Î
+¥&Jr.Ëò/—µz¾d§X¯*‰ƒ°dӂê›8  Ú&=+õD®¢µù¥F0hÕ,Àv.ÈFaðCè!‰
+òHNÏ/OÍ—ktæûM'úËÄ‚Òè`ÏêÑ1!™M½ô·×Nl_µûl@]ƒÆɼìîùåµE•uüµ–µj÷ÙÞwØNR\rnï3Wòšƒãá™N·›o
+>û|Øæêê&eÿ>?2vôœ¦¯¾¹ àýùƒÎzzɲ&?ñçG=»ÿ8ß`0²¹\VsëŽéOu»ØР•D„/þì‰	Ìõ÷w¸íU¥ß-½¶¡A+îßç—/zõXúNDøâÏþøý|›Zî<J¦,²¶4£*hnÄÒO¿›°ö#{WiÁôo† ˜òùã)¯váÐUÞ‹þi¾ØApÃé}žì_™Wë5;xñ§KŸú{¦k"¥µm†Ð§¿±²2¯ÆëÝÈ¥_΍øñ¹]—|rzÃ¥Ðvx‹ÍøRgÓÐ×v—a;d«ðP/BÉü§KHÍ+óyzáºy\N›a>;x—Ã2…ùºÔM{¬Ûºo×{ù—í§«\N“·³ýó²#üË=”—†¾õÛÇÃb:{¼Ýv>qø‰¾QÙ?óùúùvbA¹Þ`ä	xœ†S¯}Ó>ïôß›ûsßpÑü< Pѐ™óîk-眽0s¡ùqT”{Í©3¯}“qµRÌ°²æ_âl6C·nöÏÜÜšDBŽAé(ÖÀ&óxžÕGO¼²$ãj¥ØÏß¡‘¹~ €L&зÜn×n®µ‡¾¼¬¢¼›S-v¬—Jù†‡ð<PÏþ0ê 4·§‰Õ©8bT§w[ÎY’õÖ\óã.Cʾ¹<ó³‚ä2‰D!ÔÉœÿwïh±\¨ÿèè‹¿–\­KEZ‘L €]æñÈÑÁÅ‘£ƒ¿+¹Z)v	¼ñÔ‚€^žÕËòæÎ2?ï<Яâó³¯.ª.¬ãWÕ<ÂœëyBÎ
++!„.~µ‘L,Ðgþuc‰[öÚ·-Ÿ¯ž7e›ù1—Ã2múäéu °®µõ}ôìà„žœp»ím¾uÙ½æG¾ùÇ–Ûù㽩[`k[ß‹µ¼ý9ŒÞÞöw<ô§eo¦t딎âê{©íQäêtÛ-nu÷:Þ’ÜÝN#w·Ãóë² ~Ù J))JÝ/ÐiêYz­Š1hY½šeЫ£^Ã2t,£QË2ôŒÉ¨c™L–ɨg¨ÉÀ2
+,j22”YÔdd™š›X”Y`21”šX×ÿ1 at ióco7K¿ó‡K£n’ÿóE·‰„#!Œ‘Æc2?&„1†eBL„°ŒÃ2†e$„e$ËÄ°ØF°‹cb¶‘aq›cb±xF†Í5²8|#›#0±9£ª*WÌÁ›ö!„î?d!NÁ}^²ë1î»:K×ò(¨«¯ó=°bÂe` & 0€H‹Ç@ŒÀ„\& bFÒ¼1¹ö:¹¶|ëó®!5€}‡?Lúot:©ZUX ” ¬kW_{”2šÇ Ð<F2-–c®ÏgQøßó: €EvQpoŸ3{³¡G?d-4R¹U‡ŠIf'Ëõ~¶{n³,;ŽWtò¥Ús›íMl'Ë=7ãËöØÖåË4ªµo´Ç¶¬	¶sA¶¯êEVRZÜïµFKׁêØ°²u¸Ç!dU|t úø±ìî55j…»‡]þfϹv+2tïþ˜³«wêñœžÚF½ÄÞUšß©·WÒ:þ-ënÇÜÎeõl)¶sA6	ƒB^P!~ý‡-ÓKªT^j­^ºzÞ”cü+-]—5HO/÷>²ÓÉîÝÝ‹Êòýå§Ó3:wvújÈõÛ•¡{ãànW;bVïÍ
+/™*åp–×ÑÿžŸîæ\Ösbh¥kCÝ;~Y ‡Í2õñJ
+÷sÝ3wù®w,]5ùkýôæž}ýúûU$$ä‡ýñû¹˜!Cÿ±d]ª‘sz7ßv0¸weÊ‘ìÈsÛ¯tÁà‡Ð£	ÏñCÈ|]äMŸÌzfxNE–®Åš&R]Õ¤tr–TYº–GYE^àÂÎ4×uóöõ¬-UyDëœdéšB÷÷øˆÈÊ  ®IDAT!«@qé÷ª]ôد°jöÊKÿ7™(룃ã,]Ë£ìøê‹Á§7^ÑX«vêÜßw_øÐÀKׄº?¸ÇYÐÎÛ¹ foÎÞÑ/!>¿×ÒŸÇýô(Üf­#›ðáÀß^žùÙžŸW˜R²êÕmC,]ÓýÒª*˜C+&;Bø–®!KÀà‡¬¥´6´ÿllç‚  `îÛ»z<1øÇe/éÑÃÓêoµÖ^Ü:)|"\RÊ;Yº–ûE©ôêàï?d£ð!dUÞŸ·'fÏî´áß/»¤o?ß
+K×ó¨;ý÷eOóãœŲÌø‚h¹›ô‘=7•/u6
+{})¥ôŽ÷rFÈZá9~YÈûÎûiõ6 À‘‹™ÞéöÓë–Åç²M–®íQ¶kgêð¦&½Ý‹ÏoüÐüš¿¿"iï~³d]ª>;üÔºyû¤l.K£Viå.Š¤ç—ÙnéºB÷ƒB²zß¹¡ƒ‰ã¦°Ë8p.# `htàr7…ÞFê_H¼<g¾¥k°&ß\š¹ÐÒ5 „~YÈ¡E/ýdéBÙ<ÇYBˆòÜö÷¤–®!„êÈ0ø!k¡çK•FKêØ´MU̱ߧË	!<Kׂ%à¡^d(¥µÏ-nZº„PÇF
+zh¬+å ËÒµ d	üBí¦¼Rk9üÏž–®ã!!z½ÛÇtp|©³iÄÌC%«gK±²IüjEƒÖ¨õÁÚ^–®ã¡0iÔóÚý^«N¾±Úas2>hïíZ³ò<çó¡Öù}j¢ÀŠKׁµ!”RK×€ÐñÜâFWK×€êøL`lZ=[Zké:²¼¸!„BÈF`ðCVÛ¹ „Bw‡ÁYO$Çv.¡;Ò6U1ÇV?kí\­Â‹;U ”Ö<·¸Q`é:B5衱¶€ØÎÙ(Üã‡BÈf˜Û¹PJ±²IüB!„l?„B!Á!„BÈF`ðCV¢8¿ëClç‚BÝ?d-LlŽÈdé"B¶sA¶Û¹ «@)­~nq#ßÒu „:6“N
+
+5yÀv.ÈFá?„B6C s7œu¤Û¹ […Á!„BÈF`ðC!„²üB!„l?d!w/Xº„B¨#Ãà‡¬aáEê¡;Ó©kÉñµ/È!\Kׂ%àoJd(¥UÏ-nľ\¡;2jˆªìª 8  ³t=µ7Üã‡BÈfdsŽQJ-]B–€Á!„BÈF`ðC!„²üB!„l?d°B!twüÕÀv.¡»Ñ©kIÜ_ÿ±Ãv.ÈVáoJd°B¨-ŒÚR]’"€JÀv.Èá?„B6C s7~3®Û¹ […Á!„BÈF`ðC!„²üB!„l?d!‰ûb;„Bè0ø!«AK—€êఝ²uØÎYlç‚jlç‚lîñC!d3°²uüB!„l?„B!Á!„BÈF`ðCV"OÚÿ•ØÒu „B?d-ƒ¾¿ŸBw¤S×’Óë_“b;d«°²
+”ÒÊç7âr„Ði5u¤²à‚ T¶sA6÷ „²{/Óè·OPJ,]B–€Á!„BÈF`ðC!„²üB!„l?d°B!twüµÀv.¡»ÒiêÉ™M³%ØÎý;÷ÒDpünnn·s³©Yºþ(&id¡%E%EEB õ""_ôBzå«^TjÚ¤à (	}!á¡|±YS›ÔTD]›yËyêÔmº9—·æn¦[/|Ó¼§ØõÒû}Þ~ùÝqpÏ#VpœØà8 @<Â!?îïÑ`æÇà8 Bð‡  €h¨4ÚÈùÊÞ)8Έ,ü     D~     "?     ‘€…Øp×X;ž’¨f35î±nªÙ{	×÷N䦐±¾&Âe3nL³ÂIëÑm Y15¬“£ÚÄ`‹ÂamÜ&‡Zå“_[Ñík«|rHxsXÛäƒ-
+T›ÖÉ™fÁÍIë™~tsÙ‰c}M²}ïL´÷6
+nî±n™ÍÔ€lÞñ^™íËkåµÏ/‘m~zPJ)ä;O‹FøûœÃRÚH‘‘e_ßçFh#E.s¬ Æzì	´‘"ÃK>Þ÷Ÿõ2k-àÔ~‡„6R$ÇÎòÇÎJh#EüA-ðJh#E²^&×–|kÍcçµeŽÅi#E.΍üµy¯ °«lÊ)ËûPá™Ê…õÁúññŽ¤Tm(óN¯™?ÖjIÕ6.kï)D{”Iiá¬üÓ‚ÚP{M&¡Lý¥-8ÇŸÓ×m—*È•]ûËø­½f»$XÝ]xA`«ÎÀp<š}ð2â~5[±hÏ.ØtÕ["«!iNñUÄóÝO_ႲÜC×5³®fshÉ'Ë-AÌ餅‚ó²=Gn æªRƒ—<ïh¹°¦¯JùésùÇn:×·ý=MÀÃ(óßâÍý«
+~x¸éÇì72ÿÄí™õÍò¡Zí6«
+NVLiVÕÇѧÚYxa&)EmuI³&UFV‘3-§$sMÃ3Òe7¨	M–;ûÀÅ•x›µû™rfX§–*“Üy%å1môE0æwꨛÛWZ±o³~¥°¼M^áXOaÙÝpLëy#éiH±noñ¥Z.Þ6bnI´vÕ'ýÌüáËÏC1sßÚ¤–®úä/í;~åÅÒŸmrô“ÔÒU¿i~ƲPz½!ˆjêôœU;‹ F¿f‘1¥Etå    IEND®B`‚
\ No newline at end of file

Added: trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_module.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,235 @@
+/*
+   MAPI Proxy
+
+   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 <mapiproxy/dcesrv_mapiproxy.h>
+#include "libmapiproxy.h"
+#include <util/debug.h>
+
+/**
+   \file dcesrv_mapiproxy_module.c
+
+   \brief mapiproxy modules management
+ */
+
+static struct mp_module {
+	struct mapiproxy_module	*mp_module;
+} *mp_modules = NULL;
+
+int					num_mp_modules;
+static struct mapiproxy_module_list	*mpm_list = NULL;
+
+
+NTSTATUS mapiproxy_module_push(struct dcesrv_call_state *dce_call,
+			       TALLOC_CTX *mem_ctx, void *r)
+{
+	struct mapiproxy_module_list		*mpm;
+	const struct ndr_interface_table	*table;
+	NTSTATUS				status;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+
+	for (mpm = mpm_list; mpm; mpm = mpm->next) {
+		if (mpm->module->endpoint && 
+		    ((strcmp(mpm->module->endpoint, "any") == 0) ||
+		     (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) {
+			if (mpm->module->push) {
+				status = mpm->module->push(dce_call, mem_ctx, r);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS mapiproxy_module_ndr_pull(struct dcesrv_call_state *dce_call,
+				   TALLOC_CTX *mem_ctx, struct ndr_pull *pull)
+{
+	struct mapiproxy_module_list		*mpm;
+	const struct ndr_interface_table	*table;
+	NTSTATUS				status;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+
+	for (mpm = mpm_list; mpm; mpm = mpm->next) {
+		if (mpm->module->endpoint && 
+		    ((strcmp(mpm->module->endpoint, "any") == 0) ||
+		     (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) {
+			if (mpm->module->ndr_pull) {
+				status = mpm->module->ndr_pull(dce_call, mem_ctx, pull);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS mapiproxy_module_pull(struct dcesrv_call_state *dce_call,
+			       TALLOC_CTX *mem_ctx, void *r)
+{
+	struct mapiproxy_module_list		*mpm;
+	const struct ndr_interface_table	*table;
+	NTSTATUS				status;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+
+	for (mpm = mpm_list; mpm; mpm = mpm->next) {
+		if (mpm->module->endpoint && 
+		    ((strcmp(mpm->module->endpoint, "any") == 0) ||
+		     (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) {
+			if (mpm->module->pull) {
+				status = mpm->module->pull(dce_call, mem_ctx, r);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS mapiproxy_module_dispatch(struct dcesrv_call_state *dce_call,
+				   TALLOC_CTX *mem_ctx, void *r, 
+				   struct mapiproxy *mapiproxy)
+{
+	struct mapiproxy_module_list		*mpm;
+	const struct ndr_interface_table	*table;
+	NTSTATUS				status;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+
+	for (mpm = mpm_list; mpm; mpm = mpm->next) {
+		if (mpm->module->endpoint && 
+		    ((strcmp(mpm->module->endpoint, "any") == 0) ||
+		     (table->name && (strcmp(table->name, mpm->module->endpoint) == 0)))) {
+			if (mpm->module->dispatch) {
+				status = mpm->module->dispatch(dce_call, mem_ctx, r, mapiproxy);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS mapiproxy_module_unbind(struct server_id server_id, uint32_t context_id)
+{
+	struct mapiproxy_module_list	*mpm;
+	NTSTATUS			status;
+
+	for (mpm = mpm_list; mpm; mpm = mpm->next) {
+		if (mpm->module->unbind) {
+			status = mpm->module->unbind(server_id, context_id);
+			NT_STATUS_NOT_OK_RETURN(status);
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+extern NTSTATUS mapiproxy_module_register(const void *_mp_module)
+{
+	const struct mapiproxy_module	*mp_module =_mp_module;
+
+	mp_modules = realloc_p(mp_modules, struct mp_module, num_mp_modules + 1);
+	if (!mp_modules) {
+		smb_panic("out of memory in mapiproxy_register");
+	}
+
+	mp_modules[num_mp_modules].mp_module = smb_xmemdup(mp_module, sizeof (*mp_module));
+	mp_modules[num_mp_modules].mp_module->name = smb_xstrdup(mp_module->name);
+
+	num_mp_modules++;
+
+	DEBUG(3, ("MAPIPROXY module '%s' registered\n", mp_module->name));
+
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS mapiproxy_module_load(struct dcesrv_context *dce_ctx)
+{
+	char				**modules;
+	struct mapiproxy_module_list	*module;
+	int				i;
+	NTSTATUS			status;
+
+	/* Fetch the module list from smb.conf */
+	modules = str_list_make(dce_ctx, lp_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "modules"), NULL);
+
+	/* Add modules to the list */
+	for (i = 0; modules[i]; i++) {
+		module = talloc_zero(dce_ctx, struct mapiproxy_module_list);
+		module->module = mapiproxy_module_byname(modules[i]);
+		if (module->module) {
+			DLIST_ADD_END(mpm_list, module, struct mapiproxy_module_list *);
+			DEBUG(3, ("MAPIPROXY module '%s' loaded\n", modules[i]));
+			if (module->module->init) {
+				status = module->module->init(dce_ctx);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		} else {
+			DEBUG(0, ("MAPIPROXY module '%s' not found\n", modules[i]));
+		}
+	}
+
+	for (module = mpm_list; module; module = module->next) {
+		DEBUG(3, ("mapiproxy_module_load '%s' (%s)\n", module->module->name, module->module->description));
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+_PUBLIC_ NTSTATUS mapiproxy_module_init(struct dcesrv_context *dce_ctx)
+{
+	init_module_fn			*mpm;
+	NTSTATUS			ret;
+
+	mpm = load_samba_modules(NULL, dce_ctx->lp_ctx, "dcerpc_mapiproxy");
+
+	run_init_functions(mpm);
+	talloc_free(mpm);
+	
+	ret = mapiproxy_module_load(dce_ctx);
+
+	return ret;
+}
+
+const struct mapiproxy_module *mapiproxy_module_byname(const char *name)
+{
+	int	i;
+
+	if (!name) return NULL;
+
+	for (i = 0; i < num_mp_modules; i++) {
+		if (strcmp(mp_modules[i].mp_module->name, name) == 0) {
+			return mp_modules[i].mp_module;
+		}
+	}
+
+	return NULL;
+}

Added: trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_server.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,362 @@
+/*
+   MAPI Proxy
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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 <mapiproxy/dcesrv_mapiproxy.h>
+#include "libmapiproxy.h"
+#include <util/debug.h>
+
+/**
+   \file dcesrv_mapiproxy_server.c
+
+   \brief mapiproxy server modules management
+ */
+
+static struct server_module {
+	struct mapiproxy_module	*server_module;
+} *server_modules = NULL;
+
+int					num_server_modules;
+static struct mapiproxy_module_list	*server_list = NULL;
+
+static TDB_CONTEXT			*emsabp_tdb_ctx = NULL;
+static void				*openchange_ldb_ctx = NULL;
+
+NTSTATUS mapiproxy_server_dispatch(struct dcesrv_call_state *dce_call,
+				   TALLOC_CTX *mem_ctx, void *r,
+				   struct mapiproxy *mapiproxy)
+{
+	struct mapiproxy_module_list		*server;
+	const struct ndr_interface_table	*table;
+	NTSTATUS				status;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+
+	for (server = server_list; server; server = server->next) {
+		if (server->module->endpoint && table->name &&
+		    !strcmp(table->name, server->module->endpoint)) {
+			if (server->module->dispatch) {
+				mapiproxy->norelay = true;
+				status = server->module->dispatch(dce_call, mem_ctx, r, mapiproxy);
+				NT_STATUS_NOT_OK_RETURN(status);
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS mapiproxy_server_unbind(struct server_id server_id, uint32_t context_id)
+{
+	struct mapiproxy_module_list		*server;
+	NTSTATUS				status;
+
+	for (server = server_list; server; server = server->next) {
+		if (server->module->unbind) {
+			status = server->module->unbind(server_id, context_id);
+			NT_STATUS_NOT_OK_RETURN(status);
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+extern NTSTATUS mapiproxy_server_register(const void *_server_module)
+{
+	const struct mapiproxy_module	*server_module = _server_module;
+
+	server_modules = realloc_p(server_modules, struct server_module, num_server_modules + 1);
+	if (!server_modules) {
+		smb_panic("out of memory in mapiproxy_server_register");
+	}
+
+	server_modules[num_server_modules].server_module = smb_xmemdup(server_module, sizeof (*server_module));
+	server_modules[num_server_modules].server_module->name = smb_xstrdup(server_module->name);
+
+	num_server_modules++;
+
+	DEBUG(3, ("MAPIPROXY server '%s' registered\n", server_module->name));
+
+	return NT_STATUS_OK;
+}
+
+
+_PUBLIC_ bool mapiproxy_server_loaded(const char *endpoint)
+{
+	struct mapiproxy_module_list	*server;
+	
+	if (!endpoint) return false;
+
+	for (server = server_list; server; server = server->next) {
+		if (server->module->endpoint && !strcmp(endpoint, server->module->endpoint)) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
+static NTSTATUS mapiproxy_server_overwrite(TALLOC_CTX *mem_ctx, const char *name, const char *endpoint)
+{
+	struct mapiproxy_module_list	*server;
+	struct mapiproxy_module_list	*server_load;
+
+	if (!name) return NT_STATUS_NOT_FOUND;
+	if (!endpoint) return NT_STATUS_NOT_FOUND;
+
+	/* Step 0. Ensure given module matches with endpoint */
+	server_load = talloc_zero(mem_ctx, struct mapiproxy_module_list);
+	server_load->module = mapiproxy_server_byname(name);
+	if (!server_load->module) {
+		DEBUG(0, ("MAPIPROXY ERROR: couldn't load server '%s'\n", name));
+		talloc_free(server_load);
+		return NT_STATUS_NOT_FOUND;
+	} else {
+		if (strcmp(server_load->module->endpoint, endpoint)) {
+			DEBUG(0, ("MAPIPROXY ERROR: %s endpoint expected for %s but %s found!\n",
+				  endpoint, server_load->module->name, server_load->module->endpoint));
+			talloc_free(server_load);
+			return NT_STATUS_NOT_FOUND;
+		}
+	}
+
+	/* Step 1. Seek if this module has already been loaded */
+	for (server = server_list; server; server = server->next) {
+		if (!strcmp(server->module->name, name) &&
+		    !strcmp(server->module->endpoint, endpoint)) {
+			DEBUG(0, ("MAPIPROXY: server '%s' already loaded - skipped\n", name));
+			talloc_free(server_load);
+			return NT_STATUS_OK;
+		}
+	}
+
+	/* Step 2. Delete any loaded server matching given endpoint */
+	for (server = server_list; server; server = server->next) {
+		if (!strcmp(server->module->endpoint, endpoint)) {
+			DLIST_REMOVE(server_list, server);
+			talloc_free(server);
+		}
+	}
+
+	/* Step 3. Load custom server */
+	DLIST_ADD_END(server_list, server_load, struct mapiproxy_module_list *);
+
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS mapiproxy_server_load(struct dcesrv_context *dce_ctx)
+{
+	NTSTATUS				status;
+	struct mapiproxy_module_list		*server;
+	bool					server_mode;
+	int					i;
+	const char				*nspi;
+	const char				*emsmdb;
+	const char				*rfr;
+	const char				*server_name[] = { NDR_EXCHANGE_NSP_NAME, 
+								   NDR_EXCHANGE_EMSMDB_NAME,
+								   NDR_EXCHANGE_DS_RFR_NAME, NULL };
+
+	/* Check server mode */
+	server_mode = lp_parm_bool(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "server", false);
+	DEBUG(0, ("MAPIPROXY server mode %s\n", (server_mode == false) ? "disabled" : "enabled"));
+
+	if (server_mode == true) {
+		DEBUG(0, ("MAPIPROXY proxy mode disabled\n"));
+
+		for (i = 0; server_name[i]; i++) {
+			server = talloc_zero(dce_ctx, struct mapiproxy_module_list);
+			server->module = mapiproxy_server_bystatus(server_name[i], MAPIPROXY_DEFAULT);
+			if (server->module) {
+				DLIST_ADD_END(server_list, server, struct mapiproxy_module_list *);
+			} else {
+				DEBUG(0, ("MAPIPROXY ERROR: couldn't load server '%s'\n", server_name[i]));
+			}
+		}
+	}
+
+	/* Check for override/custom NSPI server */
+	nspi = lp_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "nspi_server");
+	mapiproxy_server_overwrite(dce_ctx, nspi, NDR_EXCHANGE_NSP_NAME);
+
+	/* Check for override/custom EMSMDB server */
+	emsmdb = lp_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "emsmdb_server");
+	mapiproxy_server_overwrite(dce_ctx, emsmdb, NDR_EXCHANGE_EMSMDB_NAME);
+
+	/* Check for override/custom RFR server */
+	rfr = lp_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_mapiproxy", "rfr_server");
+	mapiproxy_server_overwrite(dce_ctx, rfr, NDR_EXCHANGE_DS_RFR_NAME);
+
+	for (server = server_list; server; server = server->next) {
+		DEBUG(3, ("mapiproxy_server_load '%s' (%s)\n", 
+			  server->module->name, server->module->description));
+		if (server->module->init) {
+			status = server->module->init(dce_ctx);
+			NT_STATUS_NOT_OK_RETURN(status);
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize mapiproxy servers modules
+
+   \param dce_ctx pointer to the connection context
+
+   \return NT_STATUS_OK on success otherwise NT error
+ */
+_PUBLIC_ NTSTATUS mapiproxy_server_init(struct dcesrv_context *dce_ctx)
+{
+	init_module_fn		*servers;
+	NTSTATUS		ret;
+
+	servers = load_samba_modules(NULL, dce_ctx->lp_ctx, "dcerpc_mapiproxy_server");
+
+	run_init_functions(servers);
+	talloc_free(servers);
+
+	ret = mapiproxy_server_load(dce_ctx);
+
+	return ret;
+}
+
+
+const struct mapiproxy_module *mapiproxy_server_bystatus(const char *name, enum mapiproxy_status status)
+{
+	int	i;
+
+	if (!name) return NULL;
+
+	for (i = 0; i < num_server_modules; i++) {
+		if ((strcmp(server_modules[i].server_module->name, name) == 0) && 
+		    (server_modules[i].server_module->status == status)) {
+			return server_modules[i].server_module;
+		}
+	}
+
+	return NULL;
+}
+
+
+const struct mapiproxy_module *mapiproxy_server_byname(const char *name)
+{
+	int	i;
+
+	if (!name) return NULL;
+
+	for (i = 0; i < num_server_modules; i++) {
+		if ((strcmp(server_modules[i].server_module->name, name) == 0)) {
+			return server_modules[i].server_module;
+		}
+	}
+
+	return NULL;
+}
+
+
+/**
+   \details Initialize an EMSABP TDB context available to all
+   instances when Samba is not run in single mode.
+
+   \param lp_ctx pointer to the loadparm context
+
+   \note TDB database can't be opened twice with O_RDWR flags. We
+   ensure here we have a general context initialized, which we'll
+   reopen within forked instances
+
+   return Allocated TDB context on success, otherwise NULL
+ */
+_PUBLIC_ TDB_CONTEXT *mapiproxy_server_emsabp_tdb_init(struct loadparm_context *lp_ctx)
+{
+	char			*tdb_path;
+	TALLOC_CTX		*mem_ctx;
+
+	if (emsabp_tdb_ctx) return emsabp_tdb_ctx;
+
+	mem_ctx = talloc_named(NULL, 0, "mapiproxy_server_emsabp_tdb_init");
+	if (!mem_ctx) return NULL;
+
+	/* Step 0. Retrieve a TDB context pointer on the emsabp_tdb database */
+	tdb_path = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(lp_ctx), EMSABP_TDB_NAME);
+	emsabp_tdb_ctx = tdb_open(tdb_path, 0, 0, O_RDWR|O_CREAT, 0600);
+	talloc_free(tdb_path);
+	if (!emsabp_tdb_ctx) {
+		DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno)));
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	talloc_free(mem_ctx);
+
+	return emsabp_tdb_ctx;
+}
+
+
+/**
+   \details Initialize an openchange LDB context available to all
+   mapiproxy instances. This LDB context points on the OpenChange
+   dispatcher database used within emsmdb default provider.
+
+   \param lp_ctx pointer to the loadparm context
+
+   \note The memory context is not free'd leading and causes a loss
+   record.
+
+   \return Allocated LDB context on success, otherwise NULL
+ */
+_PUBLIC_ void *mapiproxy_server_openchange_ldb_init(struct loadparm_context *lp_ctx)
+{
+	char			*ldb_path;
+	TALLOC_CTX		*mem_ctx;
+	struct tevent_context	*ev;
+	int			ret;
+
+	/* Sanity checks */
+	if (openchange_ldb_ctx) return openchange_ldb_ctx;
+
+	ev = tevent_context_init(talloc_autofree_context());
+	if (!ev) return NULL;
+
+	mem_ctx = talloc_named(NULL, 0, "openchange_ldb_init");
+	if (!mem_ctx) return NULL;
+
+	/* Step 0. Retrieve a LDB context pointer on openchange.ldb database */
+	ldb_path = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(lp_ctx), OPENCHANGE_LDB_NAME);
+	openchange_ldb_ctx = ldb_init(mem_ctx, ev);
+	if (!openchange_ldb_ctx) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	ret = ldb_connect(openchange_ldb_ctx, ldb_path, 0, NULL);
+	talloc_free(ldb_path);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	return openchange_ldb_ctx;
+}

Added: trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/dcesrv_mapiproxy_session.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,194 @@
+/*
+   MAPI Proxy
+
+   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 <mapiproxy/dcesrv_mapiproxy.h>
+#include "libmapiproxy.h"
+
+/**
+   \file dcesrv_mapiproxy_session.c
+
+   \brief session API for mapiproxy modules
+ */
+
+
+/**
+   \details Create and return an allocated pointer to a mpm session
+
+   \param mem_ctx pointer to the memory context
+   \param server_id reference to the session context server identifier
+   structure
+   \param context_id reference to the context identifier
+
+   \return Pointer to an allocated mpm_session structure on success,
+   otherwise NULL
+ */
+struct mpm_session *mpm_session_new(TALLOC_CTX *mem_ctx, 
+				     struct server_id server_id,
+				     uint32_t context_id)
+{
+	struct mpm_session	*session = NULL;
+
+	if (!mem_ctx) return NULL;
+
+	session = talloc_zero(mem_ctx, struct mpm_session);
+	if (!session) return NULL;
+
+	session->server_id.id = server_id.id;
+	session->server_id.id2 = server_id.id2;
+	session->server_id.node = server_id.node;
+	session->context_id = context_id;
+	session->destructor = NULL;
+	session->private_data = NULL;
+
+	return session;
+}
+
+
+/**
+   \details Create and return an allocated pointer to a mpm session
+
+   \param mem_ctx pointer to the memory context
+   \param dce_call pointer to the session context
+
+   \return Pointer to an allocated mpm_session structure on success,
+   otherwise NULL
+ */
+struct mpm_session *mpm_session_init(TALLOC_CTX *mem_ctx,
+				     struct dcesrv_call_state *dce_call)
+{
+	if (!mem_ctx) return NULL;
+	if (!dce_call) return NULL;
+	if (!dce_call->conn) return NULL;
+	if (!dce_call->context) return NULL;
+
+	return mpm_session_new(mem_ctx, dce_call->conn->server_id, 
+			       dce_call->context->context_id);
+}
+
+
+/**
+   \details Set the mpm session destructor
+
+   \param session pointer to the mpm session context
+   \param destructor pointer to the destructor function
+
+   \return true on success, otherwise false
+ */
+bool mpm_session_set_destructor(struct mpm_session *session,
+				bool (*destructor)(void *))
+{
+	if (!session) return false;
+	if (!destructor) return false;
+
+	session->destructor = destructor;
+
+	return true;
+}
+
+
+/**
+   \details Set the mpm session pointer on private data
+
+   \param session pointer to the mpm session context
+   \param private_data generic pointer on private data
+
+   \return true on success, otherwise false
+ */
+bool mpm_session_set_private_data(struct mpm_session *session,
+				  void *private_data)
+{
+	if (!session) return false;
+
+	session->private_data = private_data;
+
+	return true;
+}
+
+
+/**
+   \details Release a mapiproxy session context
+
+   \param session pointer to the mpm session context
+
+   \return true on success, otherwise false
+ */
+bool mpm_session_release(struct mpm_session *session)
+{
+	bool		ret;
+
+	if (!session) return false;
+
+	if (session->destructor) {
+		ret = session->destructor(session->private_data);
+		if (ret == false) return ret;
+	}
+
+	talloc_free(session);
+
+	return true;
+}
+
+
+/**
+   \details Compare the mpm session with the session context one
+
+   \param session pointer to the mapiproxy module session
+   \param sid reference to a server_id structure to compare
+   \param context_id the connection context id to compare
+ */
+bool mpm_session_cmp_sub(struct mpm_session *session, 
+			 struct server_id sid,
+			 uint32_t context_id)
+{
+	if (!session) return false;
+
+	if ((session->server_id.id   == sid.id) &&
+	    (session->server_id.id2  == sid.id2) &&
+	    (session->server_id.node == sid.node) &&
+	    (session->context_id == context_id)) {
+		return true;
+	}
+
+
+	return false;
+}
+
+
+/**
+   \details Compare the mpm session with the session context one
+
+   This function is a wrapper on mpm_session_cmp_sub
+
+   \param session pointer to the mapiproxy module session
+   \param dce_call pointer to the session context
+
+   \return true on success, otherwise false
+
+   \sa mpm_session_cmp_sub
+ */
+bool mpm_session_cmp(struct mpm_session *session,
+		     struct dcesrv_call_state *dce_call)
+{
+	if (!session || !dce_call) return false;
+
+	return mpm_session_cmp_sub(session, dce_call->conn->server_id, 
+				   dce_call->context->context_id);
+}

Added: trunk/openchange/mapiproxy/libmapiproxy/entryid.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/entryid.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/entryid.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,133 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file entryid.c
+
+   \brief EntryID convenient routines
+ */
+
+#include <mapiproxy/dcesrv_mapiproxy.h>
+#include "libmapiproxy.h"
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+
+/**
+   \details Build an Address Book EntryID from a legacyExchangeDN
+
+   \param mem_ctx pointer to the memory context
+   \param legacyExchangeDN
+ */
+_PUBLIC_ enum MAPISTATUS entryid_set_AB_EntryID(TALLOC_CTX *mem_ctx, 
+						const char *legacyExchangeDN,
+						struct SBinary_short *bin)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!legacyExchangeDN, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL);
+
+	bin->cb = 28 + strlen(legacyExchangeDN) + 1;
+	bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);
+	
+	/* Fill EntryID: FIXME we should use PermanentEntryID here */
+	memset(bin->lpb, 0, bin->cb);
+	memcpy(&bin->lpb[4], GUID_NSPI, 16);
+	bin->lpb[20] = 0x1;
+	memcpy(bin->lpb + 28, legacyExchangeDN, strlen(legacyExchangeDN));
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Build a folder EntryID
+
+   \param mem_ctx pointer to the memory context
+   \param MailboxGuid pointer to the Mailbox Guid
+   \param ReplGuid pointer to the Replica Guid
+   \param FolderType the type of folder
+   \param fid the folder identifier
+   \param rbin the Binary_r structure where the function stores results
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS entryid_set_folder_EntryID(TALLOC_CTX *mem_ctx,
+						    struct GUID *MailboxGuid,
+						    struct GUID *ReplGuid,
+						    uint16_t FolderType,
+						    uint64_t fid,
+						    struct Binary_r **rbin)
+{
+	struct Binary_r	*bin;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!MailboxGuid, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ReplGuid, MAPI_E_INVALID_PARAMETER, NULL);
+
+	bin = talloc_zero(mem_ctx, struct Binary_r);
+
+	bin->cb = 46;
+	bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);
+
+	/* 4 bytes:  EntryID flags set to 0 */
+	memset(bin->lpb, 0, bin->cb);
+
+	/* 16 bytes: MailboxGuid */
+	bin->lpb[4] = (MailboxGuid->time_low & 0xFF);
+	bin->lpb[5] = ((MailboxGuid->time_low >> 8)  & 0xFF);
+	bin->lpb[6] = ((MailboxGuid->time_low >> 16) & 0xFF);
+	bin->lpb[7] = ((MailboxGuid->time_low >> 24) & 0xFF);
+	bin->lpb[8] = (MailboxGuid->time_mid & 0xFF);
+	bin->lpb[9] = ((MailboxGuid->time_mid >> 8)  & 0xFF);
+	bin->lpb[10] = (MailboxGuid->time_hi_and_version & 0xFF);
+	bin->lpb[11] = ((MailboxGuid->time_hi_and_version >> 8) & 0xFF);
+	memcpy(&bin->lpb[12],  MailboxGuid->clock_seq, sizeof (uint8_t) * 2);
+	memcpy(&bin->lpb[14], MailboxGuid->node, sizeof (uint8_t) * 6);
+
+	/* 2 bytes: FolderType */
+	bin->lpb[20] = (FolderType & 0xFF);
+	bin->lpb[21] = ((FolderType >> 8) & 0xFF);
+
+	/* 16 bytes: ReplGuid */
+	bin->lpb[22] = (ReplGuid->time_low & 0xFF);
+	bin->lpb[23] = ((ReplGuid->time_low >> 8)  & 0xFF);
+	bin->lpb[24] = ((ReplGuid->time_low >> 16) & 0xFF);
+	bin->lpb[25] = ((ReplGuid->time_low >> 24) & 0xFF);
+	bin->lpb[26] = (ReplGuid->time_mid & 0xFF);
+	bin->lpb[27] = ((ReplGuid->time_mid >> 8)  & 0xFF);
+	bin->lpb[28] = (ReplGuid->time_hi_and_version & 0xFF);
+	bin->lpb[29] = ((ReplGuid->time_hi_and_version >> 8) & 0xFF);
+	memcpy(&bin->lpb[30],  ReplGuid->clock_seq, sizeof (uint8_t) * 2);
+	memcpy(&bin->lpb[32], ReplGuid->node, sizeof (uint8_t) * 6);
+
+	/* 8 bytes: FolderID, first byte unset */
+	bin->lpb[39] = ((fid >> 8) & 0xFF);
+	bin->lpb[40] = ((fid >> 16) & 0xFF);
+	bin->lpb[41] = ((fid >> 24) & 0xFF);
+	bin->lpb[42] = ((fid >> 32) & 0xFF);
+	bin->lpb[43] = ((fid >> 40) & 0xFF);
+	bin->lpb[44] = ((fid >> 48) & 0xFF);
+	bin->lpb[45] = ((fid >> 56) & 0xFF);
+
+	*rbin = bin;
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/libmapiproxy.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,230 @@
+/*
+   MAPI Proxy
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2008-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/>.
+ */
+
+#ifndef	__LIBMAPIPROXY_H__
+#define	__LIBMAPIPROXY_H__
+
+#include <signal.h>
+#include <dcerpc_server.h>
+#include <talloc.h>
+#include <tevent.h>
+#include <tdb.h>
+#include <ldb.h>
+#include <ldb_errors.h>
+#include <libmapi/dlinklist.h>
+#include <fcntl.h>
+#include <errno.h>
+
+struct mapiproxy {
+	bool			norelay;
+	bool			ahead;
+};
+
+
+enum mapiproxy_status {
+	MAPIPROXY_DEFAULT	= 0x0,
+	MAPIPROXY_CUSTOM	= 0x1
+};
+
+
+struct mapiproxy_module {
+	enum mapiproxy_status	status;
+	const char		*name;
+	const char		*description;
+	const char		*endpoint;
+	NTSTATUS		(*init)(struct dcesrv_context *);
+	NTSTATUS		(*push)(struct dcesrv_call_state *, TALLOC_CTX *, void *);
+	NTSTATUS		(*ndr_pull)(struct dcesrv_call_state *, TALLOC_CTX *, struct ndr_pull *);
+	NTSTATUS		(*pull)(struct dcesrv_call_state *, TALLOC_CTX *, void *);
+	NTSTATUS		(*dispatch)(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *);
+	NTSTATUS		(*unbind)(struct server_id, uint32_t);
+};
+
+
+struct mapiproxy_module_list {
+	const struct mapiproxy_module  	*module;
+	struct mapiproxy_module_list	*prev;
+	struct mapiproxy_module_list	*next;
+};
+
+
+struct mpm_session {
+	struct server_id		server_id;
+	uint32_t			context_id;
+	bool				(*destructor)(void *);
+	void				*private_data;
+};
+
+
+struct auth_serversupplied_info 
+{
+	struct dom_sid	*account_sid;
+	struct dom_sid	*primary_group_sid;
+
+	size_t		n_domain_groups;
+	struct dom_sid	**domain_groups;
+
+	DATA_BLOB	user_session_key;
+	DATA_BLOB	lm_session_key;
+
+	const char	*account_name;
+	const char	*domain_name;
+
+	const char	*full_name;
+	const char	*logon_script;
+	const char	*profile_path;
+	const char	*home_directory;
+	const char	*home_drive;
+	const char	*logon_server;
+	
+	NTTIME		last_logon;
+	NTTIME		last_logoff;
+	NTTIME		acct_expiry;
+	NTTIME		last_password_change;
+	NTTIME		allow_password_change;
+	NTTIME		force_password_change;
+
+	uint16_t	logon_count;
+	uint16_t	bad_password_count;
+
+	uint32_t	acct_flags;
+
+	bool		authenticated;
+};
+
+
+struct mapi_handles {
+	uint32_t	       	handle;
+	uint32_t		parent_handle;
+	void		       	*private_data;
+	int			systemfolder;
+	struct mapi_handles	*prev;
+	struct mapi_handles	*next;
+};
+
+
+struct mapi_handles_context {
+	TDB_CONTEXT	       	*tdb_ctx;
+	uint32_t		last_handle;
+	struct mapi_handles    	*handles;
+};
+
+
+#define	MAPI_HANDLES_RESERVED	0xFFFFFFFF
+#define	MAPI_HANDLES_ROOT	"root"
+#define	MAPI_HANDLES_NULL	"null"
+
+
+/**
+   EMSABP server defines
+ */
+#define	EMSABP_TDB_NAME		"emsabp_tdb.tdb"
+
+/**
+   Represents the NSPI Protocol in Permanent Entry IDs.
+ */
+static const uint8_t GUID_NSPI[] = {
+0xDC, 0xA7, 0x40, 0xC8, 0xC0, 0x42, 0x10, 0x1A, 0xB4, 0xB9,
+0x08, 0x00, 0x2B, 0x2F, 0xE1, 0x82
+};
+
+
+#define	OPENCHANGE_LDB_NAME	"openchange.ldb"
+
+#define	NTLM_AUTH_IS_OK(dce_call) \
+(dce_call->conn->auth_state.session_info->server_info->authenticated == true)
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+
+/* definitions from dcesrv_mapiproxy_module.c */
+NTSTATUS mapiproxy_module_register(const void *);
+NTSTATUS mapiproxy_module_init(struct dcesrv_context *);
+
+NTSTATUS mapiproxy_module_push(struct dcesrv_call_state *, TALLOC_CTX *, void *);
+NTSTATUS mapiproxy_module_pull(struct dcesrv_call_state *, TALLOC_CTX *, void *);
+NTSTATUS mapiproxy_module_ndr_pull(struct dcesrv_call_state *, TALLOC_CTX *, struct ndr_pull *);
+NTSTATUS mapiproxy_module_dispatch(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *);
+NTSTATUS mapiproxy_module_unbind(struct server_id, uint32_t);
+
+const struct mapiproxy_module *mapiproxy_module_byname(const char *);
+
+/* definitions from dcesrv_mapiproxy_server.c */
+NTSTATUS mapiproxy_server_register(const void *);
+NTSTATUS mapiproxy_server_init(struct dcesrv_context *);
+NTSTATUS mapiproxy_server_unbind(struct server_id, uint32_t);
+NTSTATUS mapiproxy_server_dispatch(struct dcesrv_call_state *, TALLOC_CTX *, void *, struct mapiproxy *);
+bool mapiproxy_server_loaded(const char *);
+
+const struct mapiproxy_module *mapiproxy_server_bystatus(const char *, enum mapiproxy_status);
+const struct mapiproxy_module *mapiproxy_server_byname(const char *);
+
+TDB_CONTEXT *mapiproxy_server_emsabp_tdb_init(struct loadparm_context *);
+void *mapiproxy_server_openchange_ldb_init(struct loadparm_context *);
+
+/* definitions from dcesrv_mapiproxy_session. c */
+struct mpm_session *mpm_session_new(TALLOC_CTX *, struct server_id, uint32_t);
+struct mpm_session *mpm_session_init(TALLOC_CTX *, struct dcesrv_call_state *);
+bool mpm_session_set_destructor(struct mpm_session *, bool (*destructor)(void *));
+bool mpm_session_set_private_data(struct mpm_session *, void *);
+bool mpm_session_release(struct mpm_session *);
+bool mpm_session_cmp_sub(struct mpm_session *, struct server_id, uint32_t);
+bool mpm_session_cmp(struct mpm_session *, struct dcesrv_call_state *);
+
+/* definitions from openchangedb.c */
+enum MAPISTATUS openchangedb_get_SystemFolderID(void *, char *, uint32_t, uint64_t *);
+enum MAPISTATUS	openchangedb_get_MailboxGuid(void *, char *, struct GUID *);
+enum MAPISTATUS	openchangedb_get_MailboxReplica(void *, char *, uint16_t *, struct GUID *);
+enum MAPISTATUS openchangedb_get_mapistoreURI(TALLOC_CTX *, void *, uint64_t, char **);
+enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *, void *, const char *, const char *, uint64_t *, const char **);
+enum MAPISTATUS openchangedb_lookup_folder_property(void *, uint32_t, uint64_t);
+enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *, void *, char *, uint32_t, uint64_t, void **);
+
+/* definitions from auto-generated openchangedb_property.c */
+const char *openchangedb_property_get_attribute(uint32_t);
+
+/* definitions from mapi_handles.c */
+struct mapi_handles_context *mapi_handles_init(TALLOC_CTX *);
+enum MAPISTATUS	mapi_handles_release(struct mapi_handles_context *);
+enum MAPISTATUS mapi_handles_search(struct mapi_handles_context *, uint32_t, struct mapi_handles **);
+enum MAPISTATUS mapi_handles_add(struct mapi_handles_context *, uint32_t, struct mapi_handles **);
+enum MAPISTATUS mapi_handles_delete(struct mapi_handles_context *, uint32_t);
+enum MAPISTATUS mapi_handles_get_private_data(struct mapi_handles *, void **);
+enum MAPISTATUS mapi_handles_set_private_data(struct mapi_handles *, void *);
+enum MAPISTATUS mapi_handles_get_systemfolder(struct mapi_handles *, int *);
+enum MAPISTATUS mapi_handles_set_systemfolder(struct mapi_handles *, int);
+
+/* definitions from entryid.c */
+enum MAPISTATUS entryid_set_AB_EntryID(TALLOC_CTX *, const char *, struct SBinary_short *);
+enum MAPISTATUS entryid_set_folder_EntryID(TALLOC_CTX *, struct GUID *, struct GUID *, uint16_t, uint64_t, struct Binary_r **);
+
+__END_DECLS
+
+#endif /* ! __LIBMAPIPROXY_H__ */

Added: trunk/openchange/mapiproxy/libmapiproxy/mapi_handles.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/mapi_handles.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/mapi_handles.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,544 @@
+/*
+   OpenChange Server implementation
+
+   MAPI handles API implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file mapi_handles.c
+
+   \brief API for MAPI handles management
+ */
+
+#include <mapiproxy/dcesrv_mapiproxy.h>
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include "libmapiproxy.h"
+
+
+/**
+   \details Initialize MAPI handles context
+
+   \param mem_ctx pointer to the memory context
+
+   \return Allocated MAPI handles context on success, otherwise NULL
+ */
+_PUBLIC_ struct mapi_handles_context *mapi_handles_init(TALLOC_CTX *mem_ctx)
+{
+	struct mapi_handles_context	*handles_ctx;
+
+	/* Step 1. Initialize the context */
+	handles_ctx = talloc_zero(mem_ctx, struct mapi_handles_context);
+	if (!handles_ctx) return NULL;
+
+	/* Step 2. Initialize the TDB context */
+	handles_ctx->tdb_ctx = tdb_open(NULL, 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0600);
+
+	/* Step 3. Initialize the handles list */
+	handles_ctx->handles = NULL;
+
+	/* Step 4. Set last_handle to the first valid value */
+	handles_ctx->last_handle = 1;
+
+	return handles_ctx;
+}
+
+
+/**
+   \details Release MAPI handles context
+
+   \param handles_ctx pointer to the MAPI handles context
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_release(struct mapi_handles_context *handles_ctx)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+	tdb_close(handles_ctx->tdb_ctx);
+	talloc_free(handles_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Search for a record in the TDB database
+
+   \param handles_ctx pointer to the MAPI handles context
+   \param handle MAPI handle to lookup
+   \param rec pointer to the MAPI handle structure the function
+   returns
+   
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_search(struct mapi_handles_context *handles_ctx,
+					     uint32_t handle, struct mapi_handles **rec)
+{
+	TALLOC_CTX		*mem_ctx;
+	TDB_DATA		key;
+	TDB_DATA		dbuf;
+	struct mapi_handles	*el;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!rec, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_search");
+
+	/* Step 1. Search for the handle within TDB database */
+	key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle);
+	key.dsize = strlen((const char *)key.dptr);
+
+	dbuf = tdb_fetch(handles_ctx->tdb_ctx, key);
+	talloc_free(key.dptr);
+	OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, mem_ctx);
+	OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Ensure this is not a free'd record */
+	OPENCHANGE_RETVAL_IF(!strncmp((char *)dbuf.dptr, MAPI_HANDLES_NULL, dbuf.dsize), 
+			     MAPI_E_NOT_FOUND, mem_ctx);
+	free(dbuf.dptr);
+
+	/* Step 2. Return the record within the double chained list */
+	for (el = handles_ctx->handles; el; el = el->next) {
+		if (el->handle == handle) {
+			*rec = el;
+			return MAPI_E_SUCCESS;
+		}
+	}
+
+	return MAPI_E_CORRUPT_STORE;
+}
+
+
+/**
+   \details Set a TDB record data as null meaning it can be reused in
+   the future.
+
+   \param handles_ctx pointer to the MAPI handles context
+   \param handle handle key value to free
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS mapi_handles_tdb_free(struct mapi_handles_context *handles_ctx,
+					     uint32_t handle)
+{
+	TALLOC_CTX		*mem_ctx;
+	TDB_DATA		key;
+	TDB_DATA		dbuf;
+	int			ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_tdb_free");
+	
+	key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle);
+	key.dsize = strlen((const char *)key.dptr);
+
+	/* Step 1. Makes sure the record exists */
+	ret = tdb_exists(handles_ctx->tdb_ctx, key);
+	OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Update existing record */
+	dbuf.dptr = (unsigned char *)MAPI_HANDLES_NULL;
+	dbuf.dsize = strlen(MAPI_HANDLES_NULL);
+
+	ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_MODIFY);
+	if (ret == -1) {
+		DEBUG(3, ("[%s:%d]: Unable to create 0x%x record: %s\n", __FUNCTION__, __LINE__,
+			  handle, tdb_errorstr(handles_ctx->tdb_ctx)));
+
+		talloc_free(mem_ctx);
+		return MAPI_E_CORRUPT_STORE;
+	}
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Update a TDB record
+
+   
+ */
+static enum MAPISTATUS mapi_handles_tdb_update(struct mapi_handles_context *handles_ctx,
+					       uint32_t handle, uint32_t container_handle)
+{
+	TALLOC_CTX	*mem_ctx;
+	TDB_DATA	key;
+	TDB_DATA	dbuf;
+	int		ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_tdb_update");
+
+	key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle);
+	key.dsize = strlen((const char *)key.dptr);
+
+	/* Step 1. Makes sure the record exists */
+	ret = tdb_exists(handles_ctx->tdb_ctx, key);
+	OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Update record */
+	dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", container_handle);
+	dbuf.dsize = strlen((const char *)dbuf.dptr);
+
+	ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_MODIFY);
+	if (ret == -1) {
+		DEBUG(3, ("[%s:%d]: Unable to update 0x%x record: %s\n", __FUNCTION__, __LINE__,
+			  handle, tdb_errorstr(handles_ctx->tdb_ctx)));
+
+		talloc_free(mem_ctx);
+		return MAPI_E_CORRUPT_STORE;	
+	}
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Traverse TDB database and search for the first record
+   which dbuf value is "null" string.
+ 
+   \param tdb_ctx pointer to the TDB context
+   \param key the current TDB key
+   \param dbuf the current TDB value
+   \param state pointer on private data
+
+   \return 1 when a free record is found, otherwise 0
+*/
+static int mapi_handles_traverse_null(TDB_CONTEXT *tdb_ctx,
+				      TDB_DATA key, TDB_DATA dbuf,
+				      void *state)
+{
+	TALLOC_CTX	*mem_ctx;
+	uint32_t	*handle = (uint32_t *) state;
+	char		*handle_str = NULL;
+
+	if (dbuf.dptr && !strncmp((const char *)dbuf.dptr, MAPI_HANDLES_NULL, dbuf.dsize)) {
+		mem_ctx = talloc_named(NULL, 0, "mapi_handles_traverse_null");
+		handle_str = talloc_strndup(mem_ctx, (char *)key.dptr, key.dsize);
+		*handle = strtol((const char *) handle_str, NULL, 16);
+		talloc_free(handle_str);
+		talloc_free(mem_ctx);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+
+/**
+   \details Add a handles to the database and return a pointer on
+   created record
+
+   \param handles_ctx pointer to the MAPI handles context
+   \param container_handle the container handle if available
+   \param rec pointer on pointer to the MAPI handle structure the function
+   returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_add(struct mapi_handles_context *handles_ctx,
+					  uint32_t container_handle, struct mapi_handles **rec)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	TDB_DATA		key;
+	TDB_DATA		dbuf;
+	uint32_t		handle = 0;
+	struct mapi_handles	*el;
+	int			ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!rec, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_add");
+
+	/* Step 1. Seek the TDB database for the first free record */
+	ret = tdb_traverse(handles_ctx->tdb_ctx, mapi_handles_traverse_null, (void *)&handle);
+	if (ret > -1 && handle > 0) {
+		DEBUG(0, ("We have found free record 0x%x\n", handle));
+		retval = mapi_handles_tdb_update(handles_ctx, handle, container_handle);
+		OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+		
+		el = talloc_zero((TALLOC_CTX *)handles_ctx, struct mapi_handles);
+		if (!el) {
+			mapi_handles_tdb_free(handles_ctx, handle);
+			OPENCHANGE_RETVAL_IF(!el, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+		}
+
+		el->handle = handle;
+		el->parent_handle = container_handle;
+		el->private_data = NULL;
+		*rec = el;
+		DLIST_ADD_END(handles_ctx->handles, el, struct mapi_handles *);
+
+		return MAPI_E_SUCCESS;
+	}
+
+	/* Step 2. If no record is available, create a new one */
+	key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handles_ctx->last_handle);
+	key.dsize = strlen((const char *)key.dptr);
+
+	if (container_handle) {
+		dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", container_handle);
+		dbuf.dsize = strlen((const char *)dbuf.dptr);
+	} else {
+		dbuf.dptr = (unsigned char *) MAPI_HANDLES_ROOT;
+		dbuf.dsize = strlen(MAPI_HANDLES_ROOT);
+	}
+
+	ret = tdb_store(handles_ctx->tdb_ctx, key, dbuf, TDB_INSERT);
+	if (ret == -1) {
+		DEBUG(3, ("[%s:%d]: Unable to create 0x%x record: %s\n", __FUNCTION__, __LINE__,
+			  handles_ctx->last_handle, tdb_errorstr(handles_ctx->tdb_ctx)));
+		talloc_free(mem_ctx);
+
+		return MAPI_E_CORRUPT_STORE;
+	}
+
+	el = talloc_zero((TALLOC_CTX *)handles_ctx, struct mapi_handles);
+	if (!el) {
+		mapi_handles_tdb_free(handles_ctx, handles_ctx->last_handle);
+		OPENCHANGE_RETVAL_IF(!el, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
+	}
+
+	el->handle = handles_ctx->last_handle;
+	el->parent_handle = container_handle;
+	el->private_data = NULL;
+	el->systemfolder = -1;
+	*rec = el;
+	DLIST_ADD_END(handles_ctx->handles, el, struct mapi_handles *);
+
+	handles_ctx->last_handle += 1;
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the private data associated to a MAPI handle
+
+   \param handle pointer to the MAPI handle structure
+   \param private_data pointer on pointer to the private data the
+   function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_get_private_data(struct mapi_handles *handle, void **private_data)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handle->private_data, MAPI_E_NOT_FOUND, NULL);
+
+	*private_data = handle->private_data;
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the private data associated to a MAPI handle
+
+   \param handle pointer to the MAPI handle structure
+   \param private_data pointer to the private data to associate to the
+   MAPI handle
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_set_private_data(struct mapi_handles *handle, void *private_data)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(handle->private_data, MAPI_E_UNABLE_TO_COMPLETE, NULL);
+
+	handle->private_data = private_data;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Get the system folder identifier associated to a MAPI handle
+
+   \param handle pointer to the MAPI handle structure
+   \param systemFolderIdx pointer to the system folder index to retrieve
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND.
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_get_systemfolder(struct mapi_handles *handle, int *systemfolder)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!systemfolder, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(handle->systemfolder == -1, MAPI_E_NOT_FOUND, NULL);
+
+	*systemfolder = handle->systemfolder;
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Set the system folder identifier associated to a MAPI handle
+
+   \param handle pointer to the MAPI handle structure
+   \param systemFolderIdx the system folder index to set
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_set_systemfolder(struct mapi_handles *handle, int systemfolder)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(handle->systemfolder != -1, MAPI_E_UNABLE_TO_COMPLETE, NULL);
+
+	handle->systemfolder = systemfolder;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+struct mapi_handles_private {
+	struct mapi_handles_context	*handles_ctx;
+	uint32_t			container_handle;
+};
+
+/**
+   \details Traverse TDB database and search for records
+   which dbuf value is set to state.
+ 
+   \param tdb_ctx pointer to the TDB context
+   \param key the current TDB key
+   \param dbuf the current TDB value
+   \param state pointer on private data
+
+   \return 1 when a free record is found, otherwise 0
+*/
+static int mapi_handles_traverse_delete(TDB_CONTEXT *tdb_ctx,
+					TDB_DATA key, TDB_DATA dbuf,
+					void *state)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_handles_private	*handles_private = (struct mapi_handles_private *) state;
+	uint32_t			handle;
+	char				*container_handle_str = NULL;
+	char				*handle_str = NULL;
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_traverse_delete");
+	container_handle_str = talloc_asprintf(mem_ctx, "0x%x", handles_private->container_handle);
+
+	if (dbuf.dptr && !strncmp((const char *)dbuf.dptr, container_handle_str, dbuf.dsize)) {
+		handle_str = talloc_strndup(mem_ctx, (char *)key.dptr, key.dsize);
+		handle = strtol((const char *) handle_str, NULL, 16);
+		talloc_free(handle_str);
+		mapi_handles_delete(handles_private->handles_ctx, handle);
+	}
+
+	talloc_free(container_handle_str);
+	talloc_free(mem_ctx);
+
+	return 0;
+}
+
+
+
+/**
+   \details Remove the MAPI handle referenced by the handle parameter
+   from the double chained list and mark its associated TDB record as
+   null
+
+   \param handles_ctx pointer to the MAPI handles context
+   \param handle the handle to delete
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS mapi_handles_delete(struct mapi_handles_context *handles_ctx, 
+					     uint32_t handle)
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	TDB_DATA			key;
+	struct mapi_handles		*el;
+	struct mapi_handles_private	handles_private;
+	int				ret;
+	bool				found = false;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!handles_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!handles_ctx->tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(handle == MAPI_HANDLES_RESERVED, MAPI_E_INVALID_PARAMETER, NULL);
+
+	DEBUG(4, ("[%s:%d]: Deleting MAPI handle 0x%x\n", __FUNCTION__, __LINE__, handle));
+
+	mem_ctx = talloc_named(NULL, 0, "mapi_handles_delete");
+
+	key.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", handle);
+	key.dsize = strlen((const char *)key.dptr);
+
+	/* Step 1. Make sure the record exists */
+	ret = tdb_exists(handles_ctx->tdb_ctx, key);
+	OPENCHANGE_RETVAL_IF(!ret, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Delete this record from the double chained list */
+	for (el = handles_ctx->handles; el; el = el->next) {
+		if (el->handle == handle) {
+			DLIST_REMOVE(handles_ctx->handles, el);
+			talloc_free(el);
+			found = true;
+		}
+	}
+	/* This case should never occur */
+	OPENCHANGE_RETVAL_IF(found == false, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	/* Step 3. Free this record within the TDB database */
+	retval = mapi_handles_tdb_free(handles_ctx, handle);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	/* Step 4. Delete hierarchy of children */
+	handles_private.handles_ctx = handles_ctx;
+	handles_private.container_handle = handle;
+	ret = tdb_traverse(handles_ctx->tdb_ctx, mapi_handles_traverse_delete, (void *)&handles_private);
+
+	talloc_free(mem_ctx);
+
+	DEBUG(4, ("[%s:%d]: Deleting MAPI handle 0x%x COMPLETE\n", __FUNCTION__, __LINE__, handle));
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy/openchangedb.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,503 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file openchangedb.c
+
+   \brief OpenChange Dispatcher database routines
+ */
+
+#include <mapiproxy/dcesrv_mapiproxy.h>
+#include "libmapiproxy.h"
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <libmapi/defs_private.h>
+
+/**
+   \details Retrieve the mailbox FolderID for given recipient from
+   openchange dispatcher database
+
+   \param ldb_ctx pointer to the OpenChange LDB context
+   \param recipient the mailbox username
+   \param SystemIdx the system folder index
+   \param FolderId pointer to the folder identifier the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_SystemFolderID(void *ldb_ctx,
+							 char *recipient, uint32_t SystemIdx,
+							 uint64_t *FolderId)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_result		*res = NULL;
+	char				*ldb_filter;
+	const char * const		attrs[] = { "*", NULL };
+	int				ret;
+	const char			*dn;
+	struct ldb_dn			*ldb_dn = NULL;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	mem_ctx = talloc_named(NULL, 0, "get_SystemFolderID");
+
+	/* Step 1. Search Mailbox Root DN */
+	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. If Mailbox root folder, check for FolderID within current record */
+	if (SystemIdx == 0x1) {
+		*FolderId = ldb_msg_find_attr_as_int64(res->msgs[0], "PidTagFolderId", 0);
+		OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+		talloc_free(mem_ctx);
+		return MAPI_E_SUCCESS;
+	}
+
+	dn = ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL);
+	OPENCHANGE_RETVAL_IF(!dn, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	/* Step 3. Search FolderID */
+	ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
+	OPENCHANGE_RETVAL_IF(!ldb_dn, MAPI_E_CORRUPT_STORE, mem_ctx);
+	talloc_free(res);
+
+	ldb_filter = talloc_asprintf(mem_ctx, "(&(objectClass=systemfolder)(SystemIdx=%d))", SystemIdx);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_dn, LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	*FolderId = ldb_msg_find_attr_as_int64(res->msgs[0], "PidTagFolderId", 0);
+	OPENCHANGE_RETVAL_IF(!*FolderId, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the mailbox GUID for given recipient from
+   openchange dispatcher database
+
+   \param ldb_ctx pointer to the OpenChange LDB context
+   \param recipient the mailbox username
+   \param MailboxGUID pointer to the mailbox GUID the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxGuid(void *ldb_ctx,
+						      char *recipient,
+						      struct GUID *MailboxGUID)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_result		*res = NULL;
+	char				*ldb_filter;
+	const char			*guid;
+	const char * const		attrs[] = { "*", NULL };
+	int				ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!MailboxGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "get_MailboxGuid");
+
+	/* Step 1. Search Mailbox DN */
+	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+	
+	/* Step 2. Retrieve MailboxGUID attribute's value */
+	guid = ldb_msg_find_attr_as_string(res->msgs[0], "MailboxGUID", NULL);
+	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	GUID_from_string(guid, MailboxGUID);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the mailbox replica identifier and GUID for given
+   recipient from openchange dispatcher database
+
+   \param ldb_ctx pointer to the OpenChange LDB context
+   \param recipient the mailbox username
+   \param ReplID pointer to the replica identifier the function returns
+   \param ReplGUID pointer to the replica GUID the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_MailboxReplica(void *ldb_ctx,
+							 char *recipient, uint16_t *ReplID,
+							 struct GUID *ReplGUID)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_result		*res = NULL;
+	char				*ldb_filter;
+	const char			*guid;
+	const char * const		attrs[] = { "*", NULL };
+	int				ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!ldb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ReplID, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ReplGUID, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "get_MailboxReplica");
+
+	/* Step 1. Search Mailbox DN */
+	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Retrieve ReplicaID attribute's value */
+	*ReplID = ldb_msg_find_attr_as_int(res->msgs[0], "ReplicaID", 0);
+
+	/* Step 3/ Retrieve ReplicaGUID attribute's value */
+	guid = ldb_msg_find_attr_as_string(res->msgs[0], "ReplicaGUID", 0);
+	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	GUID_from_string(guid, ReplGUID);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the mapistore URI associated to a mailbox system
+   folder.
+
+   \param parent_ctx pointer to the memory context
+   \param ldb_ctx pointer to the openchange LDB context
+   \param fid the Folder identifier to search for
+   \param mapistoreURL pointer on pointer to the mapistore URI the
+   function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_mapistoreURI(TALLOC_CTX *parent_ctx,
+						       void *ldb_ctx,
+						       uint64_t fid,
+						       char **mapistoreURL)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_result	*res = NULL;
+	char			*ldb_filter;
+	const char * const	attrs[] = { "*", NULL };
+	int			ret;
+
+	mem_ctx = talloc_named(NULL, 0, "get_mapistoreURI");
+
+	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	*mapistoreURL = talloc_strdup(parent_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "mapistore_uri", NULL));
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the Explicit message class and Folder identifier
+   associated to the MessageClass search pattern.
+
+   \param parent_ctx pointer to the memory context
+   \param ldb_ctx pointer to the openchange LDB context
+   \param recipient pointer to the mailbox's username
+   \param MessageClass substring to search for
+   \param fid pointer to the folder identifier the function returns
+   \param ExplicitMessageClass pointer on pointer to the complete
+   message class the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_ReceiveFolder(TALLOC_CTX *parent_ctx,
+							void *ldb_ctx,
+							const char *recipient,
+							const char *MessageClass,
+							uint64_t *fid,
+							const char **ExplicitMessageClass)
+{
+	TALLOC_CTX			*mem_ctx;
+	struct ldb_result		*res = NULL;
+	struct ldb_dn			*dn;
+	struct ldb_message_element	*ldb_element;
+	char				*dnstr;
+	char				*ldb_filter;
+	const char * const		attrs[] = { "*", NULL };
+	int				ret;
+	int				i;
+	int				length;
+
+	mem_ctx = talloc_named(NULL, 0, "get_ReceiveFolder");
+
+	/* Step 1. Search Mailbox DN */
+	ldb_filter = talloc_asprintf(mem_ctx, "CN=%s", recipient);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	dnstr = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL));
+	OPENCHANGE_RETVAL_IF(!dnstr, MAPI_E_NOT_FOUND, mem_ctx);
+
+	talloc_free(res);
+
+	/* Step 2. Search for MessageClass substring within user's mailbox */
+	dn = ldb_dn_new(mem_ctx, ldb_ctx, dnstr);
+	talloc_free(dnstr);
+
+	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagMessageClass=%s*)", MessageClass);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+	
+	*fid = ldb_msg_find_attr_as_uint64(res->msgs[0], "PidTagFolderId", 0x0);
+
+	/* Step 3. Find the longest ExplicitMessageClass matching MessageClass */
+	ldb_element = ldb_msg_find_element(res->msgs[0], "PidTagMessageClass");
+	for (i = 0, length = 0; i < ldb_element[0].num_values; i++) {
+		if (!strncasecmp(MessageClass, (char *)ldb_element->values[i].data, 
+				 strlen((char *)ldb_element->values[i].data)) &&
+		    strlen((char *)ldb_element->values[i].data) > length) {
+
+			if (*ExplicitMessageClass && strcmp(*ExplicitMessageClass, "")) {
+				talloc_free((char *)*ExplicitMessageClass);
+			}
+
+			if (MessageClass && !strcmp(MessageClass, "All")) {
+				*ExplicitMessageClass = "";
+			} else {
+				*ExplicitMessageClass = talloc_strdup(parent_ctx, (char *)ldb_element->values[i].data);
+			}
+			length = strlen((char *)ldb_element->values[i].data);
+		}
+	}
+	OPENCHANGE_RETVAL_IF(!*ExplicitMessageClass, MAPI_E_NOT_FOUND, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Check if a property exists within an openchange dispatcher
+   database record
+
+   \param ldb_ctx pointer to the openchange LDB context
+   \param proptag the MAPI property tag to lookup
+   \param fid the record folder identifier
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_lookup_folder_property(void *ldb_ctx, 
+							     uint32_t proptag, 
+							     uint64_t fid)
+{
+	TALLOC_CTX	       	*mem_ctx;
+	struct ldb_result      	*res = NULL;
+	char		       	*ldb_filter;
+	const char * const     	attrs[] = { "*", NULL };
+	const char	       	*PidTagAttr = NULL;
+	int		       	ret;
+
+	mem_ctx = talloc_named(NULL, 0, "get_folder_property");
+
+	/* Step 1. Find PidTagFolderId record */
+	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Convert proptag into PidTag attribute */
+	PidTagAttr = openchangedb_property_get_attribute(proptag);
+
+	/* Step 3. Search for attribute */
+	OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve a special MAPI property from a folder record
+
+   \param mem_ctx pointer to the memory context
+   \param ldb_ctx pointer to the OpenChange LDB context
+   \param recipient the mailbox username
+   \param res pointer to the LDB result
+   \param proptag the MAPI property tag to lookup
+   \param PidTagAttr the mapped MAPI property name
+
+   \return pointer to valid data on success, otherwise NULL
+ */
+static void *openchangedb_get_folder_special_property(TALLOC_CTX *mem_ctx,
+						      void *ldb_ctx,
+						      char *recipient,
+						      struct ldb_result *res,
+						      uint32_t proptag,
+						      const char *PidTagAttr)
+{
+	enum MAPISTATUS		retval;
+	struct GUID		MailboxGUID;
+	struct GUID		ReplGUID;
+	uint16_t		ReplID;
+	struct Binary_r		*bin;
+	uint16_t		FolderType;
+	uint64_t		FolderId;
+	const char		*tmp;
+
+	switch (proptag) {
+	case PR_IPM_APPOINTMENT_ENTRYID:
+	case PR_IPM_CONTACT_ENTRYID:
+	case PR_IPM_JOURNAL_ENTRYID:
+	case PR_IPM_NOTE_ENTRYID:
+	case PR_IPM_TASK_ENTRYID:
+	case PR_REMINDERS_ONLINE_ENTRYID:
+	case PR_IPM_DRAFTS_ENTRYID:
+		retval = openchangedb_get_MailboxGuid(ldb_ctx, recipient, &MailboxGUID);
+		retval = openchangedb_get_MailboxReplica(ldb_ctx, recipient, &ReplID, &ReplGUID);
+		FolderType = (uint16_t) ldb_msg_find_attr_as_int(res->msgs[0], "FolderType", 0x1);
+
+		tmp = ldb_msg_find_attr_as_string(res->msgs[0], PidTagAttr, NULL);
+		FolderId = strtoul(tmp, NULL, 16);
+		retval = entryid_set_folder_EntryID(mem_ctx, &MailboxGUID, &ReplGUID, FolderType, FolderId, &bin);
+		return (void *)bin;
+		break;
+	}
+
+	return NULL;
+}
+
+
+/**
+   \details Retrieve a MAPI property value from a folder record
+
+   \param parent_ctx pointer to the memory context
+   \param ldb_ctx pointer to the openchange LDB context
+   \param recipient the mailbox username
+   \param proptag the MAPI property tag to retrieve value for
+   \param fid the record folder identifier
+   \param data pointer on pointer to the data the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS openchangedb_get_folder_property(TALLOC_CTX *parent_ctx, 
+							  void *ldb_ctx,
+							  char *recipient,
+							  uint32_t proptag,
+							  uint64_t fid,
+							  void **data)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_result	*res = NULL;
+	char			*ldb_filter;
+	const char * const	attrs[] = { "*", NULL };
+	const char		*PidTagAttr = NULL;
+	int			ret;
+	const char     		*str;
+	uint64_t		*d;
+	uint32_t		l;
+	int			*b;
+
+	mem_ctx = talloc_named(NULL, 0, "get_folder_property");
+
+	/* Step 1. Find PidTagFolderId record */
+	ldb_filter = talloc_asprintf(mem_ctx, "(PidTagFolderId=0x%.16"PRIx64")", fid);
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx),
+			 LDB_SCOPE_SUBTREE, attrs, ldb_filter);
+	talloc_free(ldb_filter);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 2. Convert proptag into PidTag attribute */
+	PidTagAttr = openchangedb_property_get_attribute(proptag);
+	OPENCHANGE_RETVAL_IF(!PidTagAttr, MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 3. Ensure the element exists */
+	OPENCHANGE_RETVAL_IF(!ldb_msg_find_element(res->msgs[0], PidTagAttr), MAPI_E_NOT_FOUND, mem_ctx);
+
+	/* Step 4. Check if this is a "special property" */
+	*data = openchangedb_get_folder_special_property(parent_ctx, ldb_ctx, recipient, res, proptag, PidTagAttr);
+	OPENCHANGE_RETVAL_IF(*data != NULL, MAPI_E_SUCCESS, mem_ctx);
+
+	/* Step 5. If this is not a "special property" */
+	switch (proptag & 0xFFFF) {
+	case PT_BOOLEAN:
+		b = talloc_zero(parent_ctx, int);
+		*b = ldb_msg_find_attr_as_bool(res->msgs[0], PidTagAttr, 0x0);
+		*data = (void *)b;
+		break;
+	case PT_LONG:
+		l = ldb_msg_find_attr_as_int(res->msgs[0], PidTagAttr, 0x0);
+		*data = (void *)&l;
+		break;
+	case PT_I8:
+		str = ldb_msg_find_attr_as_string(res->msgs[0], PidTagAttr, 0x0);
+		d = talloc_zero(parent_ctx, uint64_t);
+		*d = strtoull(str, NULL, 16);
+		*data = (void *)d;
+		break;
+	case PT_STRING8:
+	case PT_UNICODE:
+		str = ldb_msg_find_attr_as_string(res->msgs[0], PidTagAttr, NULL);
+		*data = (char *) talloc_strdup(parent_ctx, str);
+		break;
+	default:
+		talloc_free(mem_ctx);
+		DEBUG(0, ("[%s:%d] Property Type 0x%.4x not supported\n", __FUNCTION__, __LINE__, (proptag & 0xFFFF)));
+		return MAPI_E_NOT_FOUND;
+	}
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/libmapiproxy.pc.in
===================================================================
--- trunk/openchange/mapiproxy/libmapiproxy.pc.in	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiproxy.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: MAPIPROXY
+Description: MAPI Proxy and Server Module Library
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lmapiproxy
+Libs.private: @LIBS@
+Cflags: -I${includedir}
+Requires: talloc dcerpc ndr ldb
+Requires.private: samba-hostconfig

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,109 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__LIBMAPISERVER_H__
+#define	__LIBMAPISERVER_H__
+
+#ifndef	_GNU_SOURCE
+#define	_GNU_SOURCE 1
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <dcerpc.h>
+#include <param.h>
+
+#include <gen_ndr/exchange.h>
+
+#ifndef	__BEGIN_DECLS
+#ifdef	__cplusplus
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+#endif
+
+#define	SIZE_DFLT_MAPI_RESPONSE	6
+
+/* Rops default and static size */
+
+/**
+   \details OpenFolderRop has fixed response size for
+   -# HasRules: uint8_t
+   -# IsGhosted: uint8_t   
+ */
+#define	SIZE_DFLT_ROPOPENFOLDER			2
+
+/**
+   \details GetPropertiesSpecificRop has fixed response size for:
+   -# layout: uint8_t
+ */
+#define	SIZE_DFLT_ROPGETPROPERTIESSPECIFIC	1
+
+/**
+   \details GetReceiveFolder has fixed response size for:
+   -# folder_id: uint64_t
+ */
+#define	SIZE_DFLT_ROPGETRECEIVEFOLDER		8
+
+/**
+   \details LogonRop has a fixed size for mailbox:
+   -# LogonFlags: uint8_t
+   -# FolderIDs: uint64_t * 13
+   -# ResponseFlags: uint8_t
+   -# MailboxGUID: sizeof (struct GUID)
+   -# ReplID: uint16_t
+   -# ReplGUID: sizeof (struct GUID)
+   -# LogonTime: uint8_t * 6 + uint16_t
+   -# GwartTime: uint64_t
+   -# StoreState: uint32_t
+ */
+#define	SIZE_DFLT_ROPLOGON_MAILBOX	160
+
+#define	SIZE_NULL_TRANSACTION		2
+
+__BEGIN_DECLS
+
+/* definitions from libmapiserver_oxcfold.c */
+uint16_t libmapiserver_RopOpenFolder_size(struct EcDoRpc_MAPI_REPL *);
+
+/* definitions from libmapiserver_oxcnotif.c */
+uint16_t libmapiserver_RopRegisterNotification_size(void);
+
+/* definitions from libmapiserver_oxcprpt.c */
+uint16_t libmapiserver_RopGetPropertiesSpecific_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *);
+int libmapiserver_push_property(TALLOC_CTX *, struct smb_iconv_convenience *, uint32_t, const void *, DATA_BLOB *, uint8_t);
+
+/* definitions from libmapiserver_oxcstor.c */
+uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *);
+uint16_t libmapiserver_RopRelease_size(void);
+uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *);
+
+__END_DECLS
+
+#endif /* ! __LIBMAPISERVER_H__ */

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcfold.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,50 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file libmapiserver_oxcfold.c
+
+   \brief OXCFOLD Rops
+ */
+
+#include "libmapiserver.h"
+
+/**
+   \details Calculate OpenFolder Rop size
+
+   \param response pointer to the OpenFolder EcDoRpc_MAPI_REPL
+   structure
+
+   \return Size of OpenFolder response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopOpenFolder_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPOPENFOLDER;
+	
+	/* No ghosted folder for the moment */
+	return size;
+}

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcnotif.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcnotif.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcnotif.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,38 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file libmapiserver_oxcfold.c
+
+   \brief OXCNOTIF Rops
+ */
+
+#include "libmapiserver.h"
+
+/**
+   \details Calculate RegisterNotification Rop size
+
+   \return Size of RegisterNotification response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopRegisterNotification_size(void)
+{
+	return SIZE_DFLT_MAPI_RESPONSE;
+}

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,151 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file libmapiserver_oxcprpt.c
+
+   \brief OXCPRPT Rops
+ */
+
+#include "libmapiserver.h"
+#include <libmapi/mapidefs.h>
+#include <gen_ndr/ndr_exchange.h>
+
+#include <util/debug.h>
+
+/**
+   \details Calculate GetPropertiesSpecific Rop size
+
+   \param request pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REQ structure
+   \param response pointer to the GetPropertiesSpecific EcDoRpc_MAPI_REPL structure
+
+   \return Size of GetPropsSpecific response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopGetPropertiesSpecific_size(struct EcDoRpc_MAPI_REQ *request,
+							      struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPGETPROPERTIESSPECIFIC;
+	size += response->u.mapi_GetProps.prop_data.length;
+
+	return size;
+}
+
+
+/**
+   \details Add a property value to a DATA blob. This convenient
+   function should be used when creating a GetPropertiesSpecific reply
+   response blob.
+
+   \param mem_ctx pointer to the memory context
+   \param iconv_convenience pointer to the iconv_convenience context
+   \param property the property tag which value is meant to be
+   appended to the blob
+   \param value generic pointer on the property value
+   \param blob the data blob the function uses to return the blob
+   \param layout whether values should be prefixed by a layout
+
+   \note blob.length must be set to 0 before this function is called
+   the first time. Also the function only supports a limited set of
+   property types at the moment.
+
+   \return 0 on success;
+ */
+_PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx,
+					 struct smb_iconv_convenience *iconv_convenience,
+					 uint32_t property, 
+					 const void *value, 
+					 DATA_BLOB *blob,
+					 uint8_t layout)
+{
+	struct ndr_push		*ndr;
+	
+	ndr = ndr_push_init_ctx(mem_ctx, iconv_convenience);
+	ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+	ndr->offset = 0;
+	if (blob->length) {
+		talloc_free(ndr->data);
+		ndr->data = blob->data;
+		ndr->offset = blob->length;
+	}
+
+	/* Step 1. Set the layout */
+	if (layout) {
+		switch (property & 0xFFFF) {
+		case PT_ERROR:
+			ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR);
+			break;
+		default:
+			ndr_push_uint8(ndr, NDR_SCALARS, 0x0);
+		}
+	}
+
+	/* Step 2. Push property data if supported */
+	switch (property & 0xFFFF) {
+	case PT_I2:
+		ndr_push_uint16(ndr, NDR_SCALARS, *(uint16_t *) value);
+		break;
+	case PT_LONG:
+	case PT_ERROR:
+	case PT_OBJECT:
+		ndr_push_uint32(ndr, NDR_SCALARS, *(uint32_t *) value);
+		break;
+	case PT_DOUBLE:
+	case PT_I8:
+		ndr_push_dlong(ndr, NDR_SCALARS, *(uint64_t *) value);
+		break;
+	case PT_BOOLEAN:
+		ndr_push_uint8(ndr, NDR_SCALARS, *(uint8_t *) value);
+		break;
+	case PT_STRING8:
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM|LIBNDR_FLAG_STR_ASCII);
+		ndr_push_string(ndr, NDR_SCALARS, (char *) value);
+		break;
+	case PT_UNICODE:
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM);
+		ndr_push_string(ndr, NDR_SCALARS, (char *) value);
+		break;
+	case PT_BINARY:
+		ndr_push_SBinary_short(ndr, NDR_SCALARS, (struct SBinary_short *) value);
+		break;
+	case PT_CLSID:
+		ndr_push_GUID(ndr, NDR_SCALARS, (struct GUID *) value);
+		break;
+	case PT_SYSTIME:
+		ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value);
+		break;
+	default:
+		break;
+	}
+
+	/* Step 3. Steal ndr context */
+	blob->data = ndr->data;
+	talloc_steal(mem_ctx, blob->data);
+	blob->length = ndr->offset;
+
+	talloc_free(ndr);
+	return 0;
+}

Added: trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver/libmapiserver_oxcstor.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,78 @@
+/*
+   libmapiserver - MAPI library for Server side
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file libmapiserver_oxcstor.c
+
+   \brief OXCSTOR Rops
+ */
+
+#include "libmapiserver.h"
+#include <string.h>
+
+/**
+   \details Calculate Logon Rop size
+
+   \param request pointer to the Logon EcDoRpc_MAPI_REQ structure
+   \param response pointer to the Logon EcDoRpc_MAPI_REPL structure
+
+   \return Size of Logon response
+ */
+_PUBLIC_ uint16_t libmapiserver_RopLogon_size(struct EcDoRpc_MAPI_REQ *request,
+					      struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response) {
+		return size;
+	}
+
+	switch (request->u.mapi_Logon.LogonFlags) {
+	case LogonPrivate:
+		size += SIZE_DFLT_ROPLOGON_MAILBOX;
+		break;
+	default:
+		break;
+	}
+
+	return size;
+}
+
+
+_PUBLIC_ uint16_t libmapiserver_RopRelease_size(void)
+{
+	return SIZE_NULL_TRANSACTION;
+}
+
+
+_PUBLIC_ uint16_t libmapiserver_RopGetReceiveFolder_size(struct EcDoRpc_MAPI_REPL *response)
+{
+	uint16_t	size = SIZE_DFLT_MAPI_RESPONSE;
+
+	if (!response || response->error_code != MAPI_E_SUCCESS) {
+		return size;
+	}
+
+	size += SIZE_DFLT_ROPGETRECEIVEFOLDER;
+	size += strlen(response->u.mapi_GetReceiveFolder.MessageClass) + 1;
+
+	return size;
+}

Added: trunk/openchange/mapiproxy/libmapiserver.pc.in
===================================================================
--- trunk/openchange/mapiproxy/libmapiserver.pc.in	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapiserver.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: MAPISERVER 
+Description: Server side MAPI library
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lmapiserver
+Libs.private: @LIBS@
+Cflags: -I${includedir}
+Requires: talloc

Added: trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,126 @@
+/*
+   OpenChange Storage Abstraction Layer library
+   MAPIStore SQLite backend
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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 "mapistore_sqlite3.h"
+
+
+/**
+   \details Initialize sqlite3 mapistore backend
+
+   \return MAPISTORE_SUCCESS on success
+ */
+static int sqlite3_init(void)
+{
+	DEBUG(0, ("sqlite3 backend initialized\n"));
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Create a connection context to the sqlite3 backend
+
+   \param mem_ctx pointer to the memory context
+   \param uri pointer to the database path
+   \param context_id pointer to the context identifier the function
+   returns
+
+   \return MAPISTORE_SUCCESS on success
+ */
+static int sqlite3_create_context(TALLOC_CTX *mem_ctx, const char *uri, void **private_data)
+{
+	struct sqlite3_context		*sqlite_ctx;
+	sqlite3				*db;
+	int				ret;
+
+	DEBUG(0, ("[%s:%d]\n", __FUNCTION__, __LINE__));
+
+	ret = sqlite3_open(uri, &db);
+	if (ret) {
+		DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__,
+			  sqlite3_errmsg(db)));
+		sqlite3_close(db);
+		return -1;
+	}
+
+	sqlite_ctx = talloc_zero(mem_ctx, struct sqlite3_context);
+	sqlite_ctx->db = db;
+	sqlite_ctx->private_data = NULL;
+
+	*private_data = (void *)sqlite_ctx;
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Delete a connection context from the sqlite3 backend
+
+   \return MAPISTORE_SUCCESS on success
+ */
+static int sqlite3_delete_context(void *private_data)
+{
+	struct sqlite3_context	*sqlite_ctx = (struct sqlite3_context *)private_data;
+	int			ret;
+
+	DEBUG(5, ("[%s:%d]\n", __FUNCTION__, __LINE__));
+
+	if (!private_data) {
+		return MAPISTORE_SUCCESS;
+	}
+
+	ret = sqlite3_close(sqlite_ctx->db);
+	if (ret) return MAPISTORE_ERROR;
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Entry point for mapistore SQLite backend
+
+   \return MAPISTORE_SUCCESS on success, otherwise -1
+ */
+int mapistore_init_backend(void)
+{
+	struct mapistore_backend	backend;
+	int				ret;
+
+	/* Fill in our name */
+	backend.name = "sqlite3";
+	backend.description = "mapistore sqlite3 backend";
+	backend.namespace = "sqlite://";
+
+	/* Fill in all the operations */
+	backend.init = sqlite3_init;
+	backend.create_context = sqlite3_create_context;
+	backend.delete_context = sqlite3_delete_context;
+
+	/* Register ourselves with the MAPIPROXY subsystem */
+	ret = mapistore_backend_register(&backend);
+	if (ret != MAPISTORE_SUCCESS) {
+		DEBUG(0, ("Failed to register the '%s' mapistore backend!\n", backend.name));
+		return ret;
+	}
+
+	return MAPISTORE_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/backends/mapistore_sqlite3.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,43 @@
+/*
+   OpenChange Storage Abstraction Layer library
+   MAPIStore SQLite backend
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__MAPISTORE_SQLITE3_H
+#define	__MAPISTORE_SQLITE3_H
+
+#include <mapiproxy/libmapistore/mapistore.h>
+#include <mapiproxy/libmapistore/mapistore_errors.h>
+#include <libmapi/dlinklist.h>
+#include <sqlite3.h>
+
+struct sqlite3_context {
+	sqlite3		*db;
+	void		*private_data;
+};
+
+
+__BEGIN_DECLS
+
+int	mapistore_init_backend(void);
+
+__END_DECLS
+
+#endif	/* ! __MAPISTORE_SQLITE3_H */

Added: trunk/openchange/mapiproxy/libmapistore/mapistore.h
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,110 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__MAPISTORE_H
+#define	__MAPISTORE_H
+
+#ifndef	_GNU_SOURCE
+#define	_GNU_SOURCE
+#endif
+
+#ifndef	_PUBLIC_
+#define	_PUBLIC_
+#endif
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <tdb.h>
+#include <talloc.h>
+#include <util/debug.h>
+
+#define	MAPISTORE_SUCCESS	0
+
+typedef	int (*init_backend_fn) (void);
+
+#define	MAPISTORE_INIT_MODULE	"mapistore_init_backend"
+
+struct mapistore_backend {
+	const char	*name;
+	const char	*description;
+	const char	*namespace;
+
+	int (*init)(void);
+	int (*create_context)(TALLOC_CTX *, const char *, void **);
+	int (*delete_context)(void *);
+};
+
+struct backend_context {
+	const struct mapistore_backend	*backend;
+	void				*private_data;
+	uint32_t			context_id;
+};
+
+struct backend_context_list {
+	struct backend_context		*ctx;
+	struct backend_context_list	*prev;
+	struct backend_context_list	*next;
+};
+
+struct processing_context;
+
+struct mapistore_context {
+	struct processing_context	*processing_ctx;
+	struct backend_context_list    	*context_list;
+};
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+
+/* definitions from mapistore_interface.c */
+struct mapistore_context *mapistore_init(TALLOC_CTX *, const char *);
+int mapistore_release(struct mapistore_context *);
+int mapistore_add_context(struct mapistore_context *, const char *uri, uint32_t *);
+int mapistore_del_context(struct mapistore_context *, uint32_t);
+const char *mapistore_errstr(int);
+
+/* definitions from mapistore_processing.c */
+int mapistore_set_mapping_path(const char *);
+
+/* definitions from mapistore_backend.c */
+extern int	mapistore_backend_register(const void *);
+const char	*mapistore_backend_get_installdir(void);
+init_backend_fn	*mapistore_backend_load(TALLOC_CTX *, const char *);
+
+bool		mapistore_backend_run_init(init_backend_fn *);
+
+__END_DECLS
+
+#endif	/* ! __MAPISTORE_H */

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_backend.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,307 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Note: init and load functions have been copied from
+   samba4/source4/param/util.c initially wrote by Jelmer.
+
+   Copyright (C) Jelmer Vernooij 2005-2007
+   Copyright (C) Julien Kerihuel 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 <sys/types.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <dirent.h>
+
+#include "mapistore.h"
+#include "mapistore_errors.h"
+#include "mapistore_private.h"
+#include <libmapi/dlinklist.h>
+
+#include <util.h>
+#include <util/debug.h>
+
+/**
+   \file mapistore_backend.c
+
+   \brief mapistore backends management API
+ */
+
+
+static struct mstore_backend {
+	struct mapistore_backend	*backend;
+} *backends = NULL;
+
+int					num_backends;
+
+
+/**
+   \details Register mapistore backends
+
+   \param _backend pointer to the mapistore backend to register
+
+   \return MAPISTORE_SUCCESS on success
+ */
+_PUBLIC_ extern int mapistore_backend_register(const void *_backend)
+{
+	const struct mapistore_backend	*backend = _backend;
+
+	backends = realloc_p(backends, struct mstore_backend, num_backends + 1);
+	if (!backends) {
+		smb_panic("out of memory in mapistore_backend_register");
+	}
+
+	backends[num_backends].backend = smb_xmemdup(backend, sizeof (*backend));
+	backends[num_backends].backend->name = smb_xstrdup(backend->name);
+
+	num_backends++;
+
+	DEBUG(3, ("MAPISTORE backend '%s' registered\n", backend->name));
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Return the full path where mapistore backends are
+   installed.
+
+   \return Pointer to the full path where backends are installed.
+ */
+_PUBLIC_ const char *mapistore_backend_get_installdir(void)
+{
+	return MAPISTORE_BACKEND_INSTALLDIR;
+}
+
+
+/**
+   \details Obtain the backend init function from a shared library
+   file
+
+   \param path full path to the backend shared library
+
+   \return Pointer to the initialization function on success,
+   otherwise NULL.
+ */
+static init_backend_fn load_backend(const char *path)
+{
+	void	*handle;
+	void	*init_fn;
+
+	handle = dlopen(path, RTLD_NOW);
+	if (handle == NULL) {
+		DEBUG(0, ("Unable to open %s: %s\n", path, dlerror()));
+		return NULL;
+	}
+
+	init_fn = dlsym(handle, MAPISTORE_INIT_MODULE);
+
+	if (init_fn == NULL) {
+		DEBUG(0, ("Unable to find %s() in %s: %s\n",
+			  MAPISTORE_INIT_MODULE, path, dlerror()));
+		DEBUG(1, ("Loading mapistore backend '%s' failed\n", path));
+		dlclose(handle);
+		return NULL;
+	}
+
+	return (init_backend_fn) init_fn;
+}
+
+
+/**
+   \details Load backends from specified directory
+
+   \param mem_ctx pointer to the memory context
+   \param pointer to the backends shared library folder
+
+   \return allocated array of functions pointers to initialization
+   functions on success, otherwise NULL.
+ */
+static init_backend_fn *load_backends(TALLOC_CTX *mem_ctx, const char *path)
+{
+	DIR		*dir;
+	struct dirent	*entry;
+	char		*filename;
+	int		success = 0;
+	init_backend_fn	*ret;
+
+	ret = talloc_array(mem_ctx, init_backend_fn, 2);
+	ret[0] = NULL;
+
+	dir = opendir(path);
+	if (dir == NULL) {
+		talloc_free(ret);
+		return NULL;
+	}
+
+	while ((entry = readdir(dir))) {
+		if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name)) {
+			continue;
+		}
+		
+		filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name);
+		ret[success] = load_backend(filename);
+		if (ret[success]) {
+			ret = talloc_realloc(mem_ctx, ret, init_backend_fn, success + 2);
+			success++;
+			ret[success] = NULL;
+		}
+
+		talloc_free(filename);
+	}
+
+	closedir(dir);
+
+	return ret;
+}
+
+
+/**
+   \details Load the initialization functions from backends DSO
+
+   \param mem_ctx pointer to the memory context
+   \param path pointer to the backend's DSO folder
+
+   \return allocated array of functions pointers to initialization
+   functions on success, otherwise NULL.
+ */
+_PUBLIC_ init_backend_fn *mapistore_backend_load(TALLOC_CTX *mem_ctx, const char *path)
+{
+	if (!path) {
+		path = mapistore_backend_get_installdir();
+	}
+
+	return load_backends(mem_ctx, path);
+}
+
+
+/**
+   \details Run specified initialization functions.
+
+   \param fns pointer to an array of mapistore backends initialization
+   functions
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapistore_backend_run_init(init_backend_fn *fns)
+{
+	int				i;
+	bool				ret = true;
+
+	if (fns == NULL) {
+		return true;
+	}
+
+	for (i = 0; fns[i]; i++) {
+		ret &= (bool)fns[i]();
+	}
+
+	return ret;
+}
+
+
+/**
+   \details Initialize mapistore backends
+
+   \param mem_ctx pointer to the memory context
+   \param path pointer to folder where mapistore backends are
+   installed
+
+   \return MAPISTORE_SUCCESS on success, otherwise
+   MAPISTORE_ERR_BACKEND_INIT
+ */
+int mapistore_backend_init(TALLOC_CTX *mem_ctx, const char *path)
+{
+	init_backend_fn			*ret;
+	bool				status;
+	int				retval;
+	int				i;
+
+	ret = mapistore_backend_load(mem_ctx, path);
+	status = mapistore_backend_run_init(ret);
+	talloc_free(ret);
+
+	for (i = 0; i < num_backends; i++) {
+		if (backends[i].backend) {
+			DEBUG(3, ("MAPISTORE backend '%s' loaded\n", backends[i].backend->name));
+			retval = backends[i].backend->init();
+		}
+	}
+
+	return (status != true) ? MAPISTORE_SUCCESS : MAPISTORE_ERR_BACKEND_INIT;
+}
+
+
+/**
+   \details Create backend context
+
+   \param mem_ctx pointer to the memory context
+   \param namespace the backend namespace
+   \param uri the backend parameters which can be passes inline
+
+   \return a valid backend_context pointer on success, otherwise NULL
+ */
+struct backend_context *mapistore_backend_create_context(TALLOC_CTX *mem_ctx, const char *namespace, 
+							 const char *uri)
+{
+	struct backend_context		*context;
+	int				retval;
+	bool				found;
+	void				*private_data = NULL;
+	int				i;
+
+	DEBUG(0, ("namespace is %s and backend_uri is '%s'\n", namespace, uri));
+	for (i = 0; i < num_backends; i++) {
+		if (backends[i].backend->namespace && 
+		    !strcmp(namespace, backends[i].backend->namespace)) {
+			found = true;
+			retval = backends[i].backend->create_context(mem_ctx, uri, &private_data);
+			if (retval != MAPISTORE_SUCCESS) {
+				return NULL;
+			}
+
+			break;
+		}
+	}
+	if (found == false) {
+		DEBUG(0, ("MAPISTORE: no backend with namespace '%s' is available\n", namespace));
+		return NULL;
+	}
+
+	context = talloc_zero(mem_ctx, struct backend_context);
+	context->backend = backends[i].backend;
+	context->private_data = private_data;
+	talloc_steal(context, context->private_data);
+
+	return context;
+}
+
+
+/**
+   \details Delete a context from the specified backend
+
+   \param bctx pointer to the backend context
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ int mapistore_backend_delete_context(struct backend_context *bctx)
+{
+	if (!bctx->backend->delete_context) return MAPISTORE_ERROR;
+
+	return bctx->backend->delete_context(bctx->private_data);
+}

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_errors.h
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_errors.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_errors.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,109 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file mapistore_errors.h
+
+   \brief Thie header providers a set of result codes for MAPISTORE
+   function calls.
+ */
+
+#ifndef	__MAPISTORE_ERRORS_H
+#define	__MAPISTORE_ERRORS_H
+
+/**
+   The function call succeeded.
+ */
+#define	MAPISTORE_SUCCESS			0
+
+/**
+   The function call failed for some non-specific reason.
+ */
+#define	MAPISTORE_ERROR				1
+
+/**
+   The function call failed because it was unable to allocate the
+   memory required by underlying operations.
+ */
+#define	MAPISTORE_ERR_NO_MEMORY			2
+
+/**
+   The function call failed because underlying context has already
+   been initialized
+ */
+#define	MAPISTORE_ERR_ALREADY_INITIALIZED	3
+
+/**
+   The function call failed because context has not been initialized.
+ */
+#define	MAPISTORE_ERR_NOT_INITIALIZED		4
+
+/**
+   The function call failed because an internal mapistore storage
+   component has corrupted data.
+ */
+#define	MAPISTORE_ERR_CORRUPTED			5
+
+/**
+   The function call failed because one of the function parameters is
+   invalid
+ */
+#define	MAPISTORE_ERR_INVALID_PARAMETER		6
+
+/**
+   The function call failed because the directory doesn't exist
+ */
+#define	MAPISTORE_ERR_NO_DIRECTORY		7
+
+/**
+   The function call failed because the underlying function couldn't
+   open a database.
+ */
+#define	MAPISTORE_ERR_DATABASE_INIT		8
+
+/**
+   The function call failed because the underlying function didn't run
+   a database operation successfully.
+ */
+#define	MAPISTORE_ERR_DATABASE_OPS		9
+
+/**
+   The function failed to register a storage backend
+ */
+#define	MAPISTORE_ERR_BACKEND_REGISTER		10
+
+/**
+   One of more storage backend initialization functions failed to
+   complete successfully.
+ */
+#define	MAPISTORE_ERR_BACKEND_INIT		11
+
+/**
+   The function failed because mapistore failed to create a context
+ */
+#define	MAPISTORE_ERR_CONTEXT_FAILED		12
+
+/**
+   The function failed because the provided namespace is invalid
+ */
+#define	MAPISTORE_ERR_INVALID_NAMESPACE		13
+
+#endif /* ! __MAPISTORE_ERRORS_H */

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_interface.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,234 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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 "mapistore.h"
+#include "mapistore_errors.h"
+#include "mapistore_private.h"
+#include <libmapi/dlinklist.h>
+
+#include <string.h>
+
+/**
+   \details Initialize the mapistore context
+
+   \param mem_ctx pointer to the memory context
+
+   \return allocate mapistore context on success, otherwise NULL
+ */
+_PUBLIC_ struct mapistore_context *mapistore_init(TALLOC_CTX *mem_ctx, const char *path)
+{
+	int				retval;
+	struct mapistore_context	*mstore_ctx;
+
+	mstore_ctx = talloc_zero(mem_ctx, struct mapistore_context);
+	if (!mstore_ctx) {
+		return NULL;
+	}
+
+	mstore_ctx->processing_ctx = talloc_zero(mstore_ctx, struct processing_context);
+
+	retval = mapistore_init_mapping_context(mstore_ctx->processing_ctx);
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(5, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval)));
+		talloc_free(mstore_ctx);
+		return NULL;
+	}
+
+	retval = mapistore_backend_init(mstore_ctx, path);
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(5, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, mapistore_errstr(retval)));
+		talloc_free(mstore_ctx);
+		return NULL;
+	}
+
+	mstore_ctx->context_list = NULL;
+
+	return mstore_ctx;
+}
+
+
+/**
+   \details Release the mapistore context and destroy any data
+   associated
+
+   \param mstore_ctx pointer to the mapistore context
+
+   \note The function needs to rely on talloc destructors which is not
+   implemented in code yet.
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ int mapistore_release(struct mapistore_context *mstore_ctx)
+{
+	if (!mstore_ctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+
+	talloc_free(mstore_ctx->processing_ctx);
+	talloc_free(mstore_ctx->context_list);
+	talloc_free(mstore_ctx);
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Add a new connection context to mapistore
+
+   \param mstore_ctx pointer to the mapistore context
+   \param uri the connection context URI
+   \param pointer to the context identifier the function returns
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ int mapistore_add_context(struct mapistore_context *mstore_ctx, 
+				   const char *uri, uint32_t *context_id)
+{
+	TALLOC_CTX				*mem_ctx;
+	int					retval;
+	struct backend_context			*backend_ctx;
+	struct backend_context_list    		*backend_list;
+	char					*namespace;
+	char					*namespace_start;
+	char					*backend_uri;
+
+	/* Step 1. Perform Sanity Checks on URI */
+	if (!uri || strlen(uri) < 4) {
+		return MAPISTORE_ERR_INVALID_NAMESPACE;
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "mapistore_add_context");
+	namespace = talloc_strdup(mem_ctx, uri);
+	namespace_start = namespace;
+	namespace = strchr(namespace, ':');
+	if (!namespace) {
+		DEBUG(0, ("[%s:%d]: Error - Invalid namespace '%s'\n", __FUNCTION__, __LINE__, namespace_start));
+		talloc_free(mem_ctx);
+		return MAPISTORE_ERR_INVALID_NAMESPACE;
+	}
+
+	if (namespace[1] && namespace[1] == '/' &&
+	    namespace[2] && namespace[2] == '/' &&
+	    namespace[3]) {
+		backend_uri = talloc_strdup(mem_ctx, &namespace[3]);
+		namespace[3] = '\0';
+		backend_ctx = mapistore_backend_create_context((TALLOC_CTX *)mstore_ctx, namespace_start, backend_uri);
+		if (!backend_ctx) {
+			return MAPISTORE_ERR_CONTEXT_FAILED;
+		}
+
+		backend_list = talloc_zero((TALLOC_CTX *) mstore_ctx, struct backend_context_list);
+		talloc_steal(backend_list, backend_ctx);
+		backend_list->ctx = backend_ctx;
+		retval = mapistore_get_context_id(mstore_ctx->processing_ctx, &backend_list->ctx->context_id);
+		if (retval != MAPISTORE_SUCCESS) {
+			talloc_free(mem_ctx);
+			return MAPISTORE_ERR_CONTEXT_FAILED;
+		}
+		*context_id = backend_list->ctx->context_id;
+		DLIST_ADD_END(mstore_ctx->context_list, backend_list, struct backend_context_list *);
+
+	} else {
+		DEBUG(0, ("[%s:%d]: Error - Invalid URI '%s'\n", __FUNCTION__, __LINE__, uri));
+		talloc_free(mem_ctx);
+		return MAPISTORE_ERR_INVALID_NAMESPACE;
+	}
+
+	talloc_free(mem_ctx);
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Delete an existing connection context from mapistore
+
+   \param mstore_ctx pointer to the mapistore context
+   \param context_id the context identifier referencing the context to
+   delete
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ int mapistore_del_context(struct mapistore_context *mstore_ctx, 
+				   uint32_t context_id)
+{
+	struct backend_context_list	*el;
+	int				retval;
+	bool				found = false;
+
+	/* Sanity checks */
+	if (!mstore_ctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+	if (!mstore_ctx->processing_ctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+	if (!mstore_ctx->context_list) return MAPISTORE_ERR_NOT_INITIALIZED;
+
+	/* Step 0. Ensure the context exists */
+	for (el = mstore_ctx->context_list; el; el = el->next) {
+		if (el->ctx && el->ctx->context_id == context_id) {
+			found = true;
+			break;
+		}
+	}
+	if (found == false) return MAPISTORE_ERR_INVALID_PARAMETER;
+
+	/* Step 1. Delete the context within backend */
+	retval = mapistore_backend_delete_context(el->ctx);
+	if (retval) return retval;
+
+	/* Step 2. Delete the context from the processing layer */
+
+	/* Step 2. Add the free'd context id to the free list */
+	retval = mapistore_free_context_id(mstore_ctx->processing_ctx, context_id);
+	return retval;
+}
+
+
+/**
+   \details return a string explaining what a mapistore error constant
+   means.
+
+   \param mapistore_err the mapistore error constant
+
+   \return constant string
+ */
+_PUBLIC_ const char *mapistore_errstr(int mapistore_err)
+{
+	switch (mapistore_err) {
+	case MAPISTORE_SUCCESS:
+		return "Success";
+	case MAPISTORE_ERROR:
+		return "Non-specific error";
+	case MAPISTORE_ERR_NO_MEMORY:
+		return "No memory available";
+	case MAPISTORE_ERR_ALREADY_INITIALIZED:
+		return "Already initialized";
+	case MAPISTORE_ERR_NOT_INITIALIZED:
+		return "Not initialized";
+	case MAPISTORE_ERR_NO_DIRECTORY:
+		return "No such file or directory";
+	case MAPISTORE_ERR_DATABASE_INIT:
+		return "Database initialization failed";
+	case MAPISTORE_ERR_DATABASE_OPS:
+		return "database operation failed";
+	case MAPISTORE_ERR_BACKEND_REGISTER:
+		return "storage backend registration failed";
+	case MAPISTORE_ERR_BACKEND_INIT:
+		return "storage backend initialization failed";
+	}
+
+	return "Unknown error";
+}

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_private.h
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_private.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_private.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,116 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__MAPISTORE_PRIVATE_H__
+#define	__MAPISTORE_PRIVATE_H__
+
+#ifndef	ISDOT
+#define ISDOT(path) ( \
+			*((const char *)(path)) == '.' && \
+			*(((const char *)(path)) + 1) == '\0' \
+		    )
+#endif
+
+#ifndef	ISDOTDOT
+#define ISDOTDOT(path)	( \
+			    *((const char *)(path)) == '.' && \
+			    *(((const char *)(path)) + 1) == '.' && \
+			    *(((const char *)(path)) + 2) == '\0' \
+			)
+#endif
+
+
+struct tdb_wrap {
+	struct tdb_context	*tdb;
+	const char		*name;
+	struct tdb_wrap		*prev;
+	struct tdb_wrap		*next;
+};
+
+/**
+   Identifier mapping context.
+
+   This structure stores PR_MID and PR_FID identifiers to backend
+   identifiers mapping. It points on 2 databases, one with "in use"
+   identifiers and another one with a list of "free identifiers" which
+   are added when an object is deleted, moved, etc.
+
+   The last_id structure member references the last identifier value
+   which got created. There is no identifier available with a value
+   higher than last_id.
+ */
+struct id_mapping_context {
+	struct tdb_wrap		*used_ctx;
+	struct tdb_wrap		*free_ctx;
+	uint64_t		last_id;
+};
+
+
+/**
+   Free context identifier list
+
+   This structure is a double chained list storing unused context
+   identifiers.
+ */
+struct context_id_list {
+	uint32_t		context_id;
+	struct context_id_list	*prev;
+	struct context_id_list	*next;
+};
+
+
+struct processing_context {
+	struct id_mapping_context	*mapping_ctx;
+	struct context_id_list		*free_ctx;
+	uint32_t			last_context_id;
+	uint64_t			dflt_start_id;
+};
+
+
+/**
+   The database name where in use ID mappings are stored
+ */
+#define	MAPISTORE_DB_LAST_ID_KEY	"mapistore_last_id"
+#define	MAPISTORE_DB_LAST_ID_VAL	0x15000
+
+#define	MAPISTORE_DB_NAME_USED_ID	"mapistore_id_mapping_used.tdb"
+#define	MAPISTORE_DB_NAME_FREE_ID	"mapistore_id_mapping_free.tdb"
+
+__BEGIN_DECLS
+
+/* definitions from mapistore_processing.c */
+const char *mapistore_get_mapping_path(void);
+int mapistore_init_mapping_context(struct processing_context *);
+int mapistore_get_context_id(struct processing_context *, uint32_t *);
+int mapistore_free_context_id(struct processing_context *, uint32_t);
+
+
+/* definitions from mapistore_backend.c */
+int mapistore_backend_init(TALLOC_CTX *, const char *);
+struct backend_context *mapistore_backend_create_context(TALLOC_CTX *, const char *, const char *);
+int mapistore_backend_delete_context(struct backend_context *);
+
+/* definitions from mapistore_tdb_wrap.c */
+struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *, const char *, int, int, int, mode_t);
+
+__END_DECLS
+
+#endif	/* ! __MAPISTORE_PRIVATE_H__ */

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_processing.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,247 @@
+/*
+   OpenChange Storage Abstraction Layer library
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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 <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#include "mapistore.h"
+#include "mapistore_errors.h"
+#include "mapistore_private.h"
+#include <libmapi/dlinklist.h>
+#include <libmapi/defs_private.h>
+
+#include <tdb.h>
+
+char *mapping_path = NULL;
+
+/**
+   \details Set the mapping path
+
+   \param path pointer to the mapping path
+
+   \note The mapping path can be set unless id_mapping_context is
+   initialized. If path is NULL and mapping path is not yet
+   initialized, then mapping_path will be reset to its default value
+   when the initialization routine is called.
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+_PUBLIC_ int mapistore_set_mapping_path(const char *path)
+{
+	TALLOC_CTX	*mem_ctx;
+	DIR		*dir;
+
+	/* Case 1. Path is set to NULL */
+	if (!path) {
+		if (mapping_path) {
+			talloc_free(mapping_path);
+		}
+		mapping_path = NULL;
+		return MAPISTORE_SUCCESS;
+	}
+
+	if (mapping_path) {
+		talloc_free(mapping_path);
+	}
+
+	/* Case 2. path is initialized */
+
+	/* Step 1. Check if path is valid path */
+	dir = opendir(path);
+	if (!dir) {
+		return MAPISTORE_ERR_NO_DIRECTORY;
+	}
+
+	/* Step 2. TODO: Check for write permissions */
+	
+	mem_ctx = talloc_autofree_context();
+	mapping_path = talloc_strdup(mem_ctx, path);
+	return MAPISTORE_SUCCESS;
+}
+
+/**
+   \details Return the current mapping path
+
+   \return pointer to the mapping path.
+ */
+const char *mapistore_get_mapping_path(void)
+{
+	return (!mapping_path) ? MAPISTORE_MAPPING_PATH : (const char *)mapping_path;
+}
+
+
+/**
+   \details Initialize the ID mapping context or return the existing
+   one if already initialized.
+
+   \param pctx pointer to the processing context
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+int mapistore_init_mapping_context(struct processing_context *pctx)
+{
+	TDB_DATA	key;
+	TDB_DATA	dbuf;
+	TALLOC_CTX	*mem_ctx;
+	char		*dbpath;
+	uint64_t	last_id;
+	char		*tmp_buf;
+	int		ret;
+
+	if (!pctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+	if (pctx->mapping_ctx) return MAPISTORE_ERR_ALREADY_INITIALIZED;
+
+	pctx->mapping_ctx = talloc_zero(pctx, struct id_mapping_context);
+	if (!pctx->mapping_ctx) return MAPISTORE_ERR_NO_MEMORY;
+
+	mem_ctx = talloc_named(NULL, 0, "mapistore_init_mapping_context");
+
+	/* Step 1. Open/Create the used ID database */
+	if (!pctx->mapping_ctx->used_ctx) {
+		dbpath = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAME_USED_ID);
+		pctx->mapping_ctx->used_ctx = tdb_wrap_open(pctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600);
+		talloc_free(dbpath);
+		if (!pctx->mapping_ctx->used_ctx) {
+			DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno)));
+			talloc_free(mem_ctx);
+			talloc_free(pctx->mapping_ctx);
+			return MAPISTORE_ERR_DATABASE_INIT;
+		}
+	}
+
+	/* Step 2. Open/Create the free ID database */
+	if (!pctx->mapping_ctx->free_ctx) {
+		dbpath = talloc_asprintf(mem_ctx, "%s/%s", mapistore_get_mapping_path(), MAPISTORE_DB_NAME_FREE_ID);
+		pctx->mapping_ctx->free_ctx = tdb_wrap_open(pctx, dbpath, 0, 0, O_RDWR|O_CREAT, 0600);
+		talloc_free(dbpath);
+		if (!pctx->mapping_ctx->free_ctx) {
+			DEBUG(3, ("[%s:%d]: %s\n", __FUNCTION__, __LINE__, strerror(errno)));
+			talloc_free(mem_ctx);
+			talloc_free(pctx->mapping_ctx);
+			return MAPISTORE_ERR_DATABASE_INIT;
+		}
+	}
+
+	/* Step 3. Retrieve the last ID value */
+	key.dptr = (unsigned char *) MAPISTORE_DB_LAST_ID_KEY;
+	key.dsize = strlen(MAPISTORE_DB_LAST_ID_KEY);
+
+	dbuf = tdb_fetch(pctx->mapping_ctx->used_ctx->tdb, key);
+
+	/* If the record doesn't exist, insert it */
+	if (!dbuf.dptr || !dbuf.dsize) {
+		dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%"PRIx64, (uint64_t) MAPISTORE_DB_LAST_ID_VAL);
+		dbuf.dsize = strlen((const char *) dbuf.dptr);
+		last_id = MAPISTORE_DB_LAST_ID_VAL;
+
+		ret = tdb_store(pctx->mapping_ctx->used_ctx->tdb, key, dbuf, TDB_INSERT);
+		talloc_free(dbuf.dptr);
+		if (ret == -1) {
+			DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__,
+				  MAPISTORE_DB_LAST_ID_KEY, tdb_errorstr(pctx->mapping_ctx->used_ctx->tdb)));
+			talloc_free(mem_ctx);
+			talloc_free(pctx->mapping_ctx);
+
+			return MAPISTORE_ERR_DATABASE_OPS;
+		}
+
+	} else {
+		tmp_buf = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize);
+		free(dbuf.dptr);
+		last_id = strtoull(tmp_buf, NULL, 16);
+		talloc_free(tmp_buf);
+	}
+
+	pctx->mapping_ctx->last_id = last_id;
+
+	talloc_free(mem_ctx);
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Return an unused or new context identifier
+
+   \param pctx pointer to the processing context
+   \param context_id pointer to the context identifier the function
+   returns
+
+   \return a non zero context identifier on success, otherwise 0.
+ */
+int mapistore_get_context_id(struct processing_context *pctx, uint32_t *context_id)
+{
+	struct context_id_list	*el;
+
+	/* Sanity checks */
+	if (!pctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+
+	/* Step 1. The free context list doesn't exist yet */
+	if (!pctx->free_ctx) {
+		pctx->last_context_id++;
+		*context_id = pctx->last_context_id;
+	}
+
+	/* Step 2. We have a free list */
+	for (el = pctx->free_ctx; el; el = el->next) {
+		if (el->context_id) {
+			*context_id = el->context_id;
+			DLIST_REMOVE(pctx->free_ctx, el);
+			break;
+		}
+	}
+
+	return MAPISTORE_SUCCESS;
+}
+
+
+/**
+   \details Add a context identifier to the list
+
+   \param pctx pointer to the processing context
+   \param context_id the identifier referencing the context to free
+
+   \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error
+ */
+int mapistore_free_context_id(struct processing_context *pctx, uint32_t context_id)
+{
+	struct context_id_list	*el;
+
+	/* Sanity checks */
+	if (!pctx) return MAPISTORE_ERR_NOT_INITIALIZED;
+
+	/* Step 1. Ensure the list is not corrupted */
+	for (el = pctx->free_ctx; el; el = el->next) {
+		if (el->context_id == context_id) {
+			return MAPISTORE_ERR_CORRUPTED;
+		}
+	}
+
+	/* Step 2. Create the element and add it to the list */
+	el = talloc_zero((TALLOC_CTX *)pctx, struct context_id_list);
+	el->context_id = context_id;
+	DLIST_ADD_END(pctx->free_ctx, el, struct context_id_list *);
+
+	return MAPISTORE_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/mapistore_tdb_wrap.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,132 @@
+/* 
+   Unix SMB/CIFS implementation.
+   TDB wrap functions
+
+   Copyright (C) Andrew Tridgell 2004
+   Copyright (C) Jelmer Vernooij <jelmer at samba.org> 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/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "mapistore.h"
+#include "mapistore_errors.h"
+#include "mapistore_private.h"
+#include <libmapi/dlinklist.h>
+
+static struct tdb_wrap *tdb_list;
+
+/* destroy the last connection to a tdb */
+static int tdb_wrap_destructor(struct tdb_wrap *w)
+{
+	tdb_close(w->tdb);
+	DLIST_REMOVE(tdb_list, w);
+	return 0;
+}				 
+
+/*
+ Log tdb messages via DEBUG().
+*/
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
+			 const char *format, ...) PRINTF_ATTRIBUTE(3,4);
+
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
+			 const char *format, ...)
+{
+	va_list ap;
+	char	*ptr = NULL;
+	int	dl;
+	int	ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&ptr, format, ap);
+	va_end(ap);
+	
+	switch (level) {
+	case TDB_DEBUG_FATAL:
+		dl = 0;
+		break;
+	case TDB_DEBUG_ERROR:
+		dl = 1;
+		break;
+	case TDB_DEBUG_WARNING:
+		dl = 2;
+		break;
+	case TDB_DEBUG_TRACE:
+		dl = 5;
+		break;
+	default:
+		dl = 0;
+	}		
+
+	if (ptr != NULL) {
+		const char *name = tdb_name(tdb);
+		DEBUG(dl, ("tdb(%s): %s", name ? name : "unnamed", ptr));
+		free(ptr);
+	}
+}
+
+
+/**
+   \details wrapped connection to a tdb database
+
+   \param mem_ctx pointer to the memory context
+   \param name tdb database name
+   \param hash_size the hash size
+   \param tdb_flags TDB flags
+   \param open_flags open flags
+   \param mode 
+
+   \note to close just talloc_free() the tdb_wrap pointer
+
+   \return pointer to an allocated tdb_wrap structure on success,
+   otherwise NULL
+ */
+struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, const char *name, 
+			       int hash_size, int tdb_flags,
+			       int open_flags, mode_t mode)
+{
+	struct tdb_wrap			*w;
+	struct tdb_logging_context	log_ctx;
+
+	log_ctx.log_fn = tdb_wrap_log;
+
+	for (w = tdb_list; w; w = w->next) {
+		if (strcmp(name, w->name) == 0) {
+			return talloc_reference(mem_ctx, w);
+		}
+	}
+
+	w = talloc(mem_ctx, struct tdb_wrap);
+	if (w == NULL) {
+		return NULL;
+	}
+
+	w->name = talloc_strdup(w, name);
+
+	w->tdb = tdb_open_ex(name, hash_size, tdb_flags, 
+			     open_flags, mode, &log_ctx, NULL);
+	if (w->tdb == NULL) {
+		talloc_free(w);
+		return NULL;
+	}
+
+	talloc_set_destructor(w, tdb_wrap_destructor);
+
+	DLIST_ADD(tdb_list, w);
+
+	return w;
+}

Added: trunk/openchange/mapiproxy/libmapistore/tests/mapistore_test.c
===================================================================
--- trunk/openchange/mapiproxy/libmapistore/tests/mapistore_test.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore/tests/mapistore_test.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,112 @@
+/*
+   OpenChange Storage Abstraction Layer library test tool
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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 "mapiproxy/libmapistore/mapistore.h"
+#include <talloc.h>
+#include <core/ntstatus.h>
+#include <samba/popt.h>
+#include <param.h>
+#include <util/debug.h>
+
+/**
+   \file mapistore_test.c
+
+   \brief Test mapistore implementation
+ */
+
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX			*mem_ctx;
+	int				retval;
+	struct mapistore_context	*mstore_ctx;
+	struct loadparm_context		*lp_ctx;
+	poptContext			pc;
+	int				opt;
+	const char			*opt_debug = NULL;
+	uint32_t			context_id = 0;
+	uint32_t			context_id2 = 0;
+
+	enum { OPT_DEBUG=1000 };
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{ "debuglevel",	'd', POPT_ARG_STRING, NULL, OPT_DEBUG,	"set the debug level", NULL },
+		{ NULL, 0, 0, NULL, 0, NULL, NULL }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "mapistore_test");
+	lp_ctx = loadparm_init(mem_ctx);
+	lp_load_default(lp_ctx);
+	setup_logging(NULL, DEBUG_STDOUT);
+	
+	pc = poptGetContext("mapistore_test", argc, argv, long_options, 0);
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		}
+	}
+
+	poptFreeContext(pc);
+
+	if (opt_debug) {
+		lp_set_cmdline(lp_ctx, "log level", opt_debug);
+	}
+	
+	retval = mapistore_set_mapping_path("/tmp");
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
+		exit (1);
+	}
+
+	mstore_ctx = mapistore_init(mem_ctx, NULL);
+	if (!mstore_ctx) {
+		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
+		exit (1);
+	}
+
+	retval = mapistore_add_context(mstore_ctx, "sqlite:///tmp/test.db", &context_id);
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
+		exit (1);
+	}
+
+	retval = mapistore_add_context(mstore_ctx, "sqlite:///tmp/test2.db", &context_id2);
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
+		exit (1);
+	}
+
+	DEBUG(0, ("Context ID: [1] = %d and [2] = %d\n", context_id, context_id2));
+
+	retval = mapistore_del_context(mstore_ctx, context_id);
+	retval = mapistore_del_context(mstore_ctx, context_id2);
+
+	retval = mapistore_release(mstore_ctx);
+	if (retval != MAPISTORE_SUCCESS) {
+		DEBUG(0, ("%s\n", mapistore_errstr(retval)));
+		exit (1);
+	}
+
+	return 0;
+}

Added: trunk/openchange/mapiproxy/libmapistore.pc.in
===================================================================
--- trunk/openchange/mapiproxy/libmapistore.pc.in	                        (rev 0)
+++ trunk/openchange/mapiproxy/libmapistore.pc.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@prefix@/share
+datadir=@datadir@
+
+Name: MAPISTORE
+Description: MAPI Storage Abstraction Layer library
+Version: @PACKAGE_VERSION@ 
+Libs: -L${libdir} -lmapistore
+Libs.private: @LIBS@
+Cflags: -I${includedir}
+Requires: talloc tdb

Added: trunk/openchange/mapiproxy/modules/mpm_cache.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_cache.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1174 @@
+/*
+   MAPI Proxy - Cache module
+
+   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/>.
+ */
+
+/**
+   \file mpm_cache.c
+   
+   \brief Cache messages and attachments so we can reduce WAN traffic
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/defs_private.h>
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/modules/mpm_cache.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <time.h>
+
+struct mpm_cache *mpm = NULL;
+
+/**
+   \details Find the position of the given MAPI call in a serialized
+   MAPI request.
+
+   If the request includes a Release call, then request and replies
+   indexes for other calls will mismatch.
+
+   \param opnum The MAPI opnum to seek
+   \param mapi_req Pointer to the MAPI request calls array
+
+   \return On success, returns the call position, otherwise -1.
+ */
+static uint32_t cache_find_call_request_index(uint8_t opnum, struct EcDoRpc_MAPI_REQ *mapi_req)
+{
+	uint32_t	i;
+
+	for (i = 0; mapi_req[i].opnum; i++) {
+		if (mapi_req[i].opnum == opnum) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/**
+   \details Dump time statistic between OpenStream and Release
+
+   This function monitors the effective time required to open, read
+   and close a stream.
+
+   \param stream the mpm_stream entry
+ */
+static void cache_dump_stream_stat(struct mpm_stream *stream)
+{
+	TALLOC_CTX	*mem_ctx;
+	struct timeval	tv_end;
+	uint64_t       	sec;
+	uint64_t       	usec;
+	char		*name;
+	const char	*stage;
+
+	mem_ctx = (TALLOC_CTX *)mpm;
+
+	if (stream->attachment) {
+		name = talloc_asprintf(mem_ctx, "0x%"PRIx64"/0x%"PRIx64"/%d",
+				       stream->attachment->message->FolderId,
+				       stream->attachment->message->MessageId,
+				       stream->attachment->AttachmentID);
+	} else if (stream->message) {
+		name = talloc_asprintf(mem_ctx, "0x%"PRIx64"/0x%"PRIx64,
+				       stream->message->FolderId,
+				       stream->message->MessageId);
+	} else {
+		return;
+	}
+
+	gettimeofday(&tv_end, NULL);
+	sec = tv_end.tv_sec - stream->tv_start.tv_sec;
+	if ((tv_end.tv_usec - stream->tv_start.tv_usec) < 0) {
+		sec -= 1;
+		usec = tv_end.tv_usec + stream->tv_start.tv_usec;
+		while (usec > 1000000) {
+			usec -= 1000000;
+			sec += 1;
+		}
+	} else {
+		usec = tv_end.tv_usec - stream->tv_start.tv_usec;
+	}
+
+	if (stream->ahead == true) {
+		stage = "[read ahead]";
+	} else if ((stream->ahead == false) && (stream->cached == true)) {
+		stage = "[cached mode]";
+	} else {
+		stage = "[non cached]";
+	}
+
+	DEBUG(1, ("STATISTIC: %-20s %s The difference is %ld seconds %ld microseconds\n", 
+		  stage, name, (long int)sec, (long int)usec));
+	talloc_free(name);
+}
+
+
+/**
+   \details
+
+   1. close the existing FILE *
+   2. build complete file path
+   3. replace __FILE__ arguments with complete file path
+   4. call execve
+   5. stat the sync'd file
+   6. open the stream again
+   7. mark the file as cached
+
+   \param stream pointer on the mpm_stream entry
+ */
+static NTSTATUS cache_exec_sync_cmd(struct mpm_stream *stream)
+{
+	uint32_t	i;
+	int		ret = 0;
+	char		**args;
+	struct stat	sb;
+	pid_t		pid;
+	int		status;
+
+	mpm_cache_stream_close(stream);
+
+	for (i = 0; mpm->sync_cmd[i]; i++);
+
+	args = talloc_array((TALLOC_CTX *)mpm, char *, i + 1);
+
+	for (i = 0; mpm->sync_cmd[i]; i++){
+		if (strstr(mpm->sync_cmd[i], "__FILE__")) {
+			args[i] = string_sub_talloc((TALLOC_CTX *)args, mpm->sync_cmd[i], "__FILE__", stream->filename);
+		} else {
+			args[i] = talloc_strdup((TALLOC_CTX *)args, mpm->sync_cmd[i]);
+		}
+	}
+	args[i] = NULL;
+
+	for (i = 0; args[i]; i++){
+		DEBUG(0, ("'%s' ", args[i]));
+	}
+	DEBUG(0, ("\n"));
+
+	switch(pid = fork()) {
+	case -1:
+		DEBUG(0, ("Failed to fork\n"));
+		break;
+	case 0:
+		ret = execve(args[0], args, NULL);
+		break;
+	default:
+		wait(&status);
+		break;
+	}
+	talloc_free(args);
+	if (ret == -1) {
+		perror("execve: ");
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	stat(stream->filename, &sb);
+	if (sb.st_size != stream->StreamSize) {
+		DEBUG(0, ("Sync'd file size is 0x%x and 0x%x was expected\n",
+			  (uint32_t)sb.st_size, stream->StreamSize));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	mpm_cache_stream_open(mpm, stream);
+	stream->cached = true;
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Track down Release calls and update the mpm_cache global
+   list - removing associated entries.
+
+   This function recursively remove child entries whenever necessary.
+
+   \param dce_call pointer to the session context
+   \param EcDoRpc pointer to the EcDoRpc operation
+   \param handle_idx the handle to track down
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_pull_Release(struct dcesrv_call_state *dce_call,
+				   struct EcDoRpc *EcDoRpc, 
+				   uint32_t handle_idx)
+{
+	struct mpm_message		*message;
+	struct mpm_attachment		*attach;
+	struct mpm_stream		*stream;
+
+	/* Look over messages */
+	for (message = mpm->messages; message; message = message->next) {
+		if ((mpm_session_cmp(message->session, dce_call) == true) &&
+		    (EcDoRpc->in.mapi_request->handles[handle_idx] == message->handle)) {
+			DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Message 0x%"PRIx64" 0x%"PRIx64": 0x%x\n", 
+				  MPM_LOCATION, MPM_SESSION(message), message->FolderId, 
+				  message->MessageId, message->handle));
+
+			/* Loop over children attachments */
+			attach = mpm->attachments;
+			while (attach) {
+				if ((mpm_session_cmp(attach->session, dce_call) == true) &&
+				    (message->handle == attach->parent_handle)) {
+					DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del recursive 1: Attachment %d: 0x%x\n", MPM_LOCATION,
+						  MPM_SESSION(attach), attach->AttachmentID, attach->handle));
+
+					/* Loop over children streams */
+					stream = mpm->streams;
+					while (stream) {
+						if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+						    (attach->handle == stream->parent_handle)) {
+							DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del recursive 1-2: Stream 0x%x\n", 
+								  MPM_LOCATION, MPM_SESSION(stream), stream->handle));
+							mpm_session_release(stream->session);
+							mpm_cache_stream_close(stream);
+							talloc_free(stream->filename);
+							DLIST_REMOVE(mpm->streams, stream);
+							talloc_free(stream);
+							stream = mpm->streams;
+						} else {
+							stream = stream->next;
+						}
+					}
+
+					mpm_session_release(attach->session);
+					DLIST_REMOVE(mpm->attachments, attach);
+					talloc_free(attach);
+					attach = mpm->attachments;
+				} else {
+					attach = attach->next;
+				}
+			}
+
+			/* Look over children streams */
+			stream = mpm->streams;
+			while (stream) {
+				if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+				    (message->handle == stream->parent_handle)) {
+					DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del recursive 1: Stream 0x%x\n", 
+						  MPM_LOCATION, MPM_SESSION(stream), stream->handle));
+					mpm_session_release(stream->session);
+					mpm_cache_stream_close(stream);
+					DLIST_REMOVE(mpm->streams, stream);
+					talloc_free(stream->filename);
+					talloc_free(stream);
+					stream = mpm->streams;
+				} else {
+					stream = stream->next;
+				}
+			}
+
+			mpm_session_release(message->session);
+			DLIST_REMOVE(mpm->messages, message);
+			talloc_free(message);
+			return NT_STATUS_OK;
+		}
+	}
+
+ 	/* Look over attachments */
+	for (attach = mpm->attachments; attach; attach = attach->next) {
+		if ((mpm_session_cmp(attach->session, dce_call) == true) &&
+		    (EcDoRpc->in.mapi_request->handles[handle_idx] == attach->handle)) {
+			DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Attachment %d: 0x%x\n", MPM_LOCATION, 
+				  MPM_SESSION(attach), attach->AttachmentID, attach->handle));
+
+
+			/* Loop over children streams */
+			stream = mpm->streams;
+			while (stream) {
+				if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+				    (attach->handle == stream->parent_handle)) {
+					DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del recursive 2: Stream 0x%x\n", 
+						  MPM_LOCATION, MPM_SESSION(stream), stream->handle));
+					mpm_session_release(stream->session);
+					mpm_cache_stream_close(stream);
+					DLIST_REMOVE(mpm->streams, stream);
+					talloc_free(stream->filename);
+					talloc_free(stream);
+					stream = mpm->streams;
+				} else {
+					stream = stream->next;
+				}
+			}			
+
+			mpm_session_release(attach->session);
+			DLIST_REMOVE(mpm->attachments, attach);
+			talloc_free(attach);
+			return NT_STATUS_OK;
+		}
+	}
+
+	/* Look over streams */
+	for (stream = mpm->streams; stream; stream = stream->next) {
+		if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+		    (EcDoRpc->in.mapi_request->handles[handle_idx] == stream->handle)) {
+			DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Stream 0x%x\n", MPM_LOCATION, 
+				  MPM_SESSION(stream), stream->handle));
+			mpm_session_release(stream->session);
+			mpm_cache_stream_close(stream);
+			DLIST_REMOVE(mpm->streams, stream);
+			talloc_free(stream->filename);
+			talloc_free(stream);
+			return NT_STATUS_OK;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenMessage requests and register a message in the
+   mpm_messages list.
+
+   This is the first step for message registration: 
+   * set Folder ID and Message ID
+   * set the handle to 0xFFFFFFFF
+   * Insert the message to the list
+
+   \param dce_call pointer to the session context
+   \param mem_ctx the memory context
+   \param request reference to the OpenMessage request
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS cache_pull_OpenMessage(struct dcesrv_call_state *dce_call,
+				       TALLOC_CTX *mem_ctx, 
+				       struct OpenMessage_req request)
+{
+	struct mpm_message		*message;
+
+	/* Check if the message has already been registered */
+	for (message = mpm->messages; message; message = message->next) {
+		if ((mpm_session_cmp(message->session, dce_call) == true) &&
+		    (request.FolderId == message->FolderId) &&
+		    (request.MessageId == message->MessageId)) {
+			DLIST_REMOVE(mpm->messages, message);
+		}
+	}
+
+	message = talloc((TALLOC_CTX *)mpm, struct mpm_message);
+	NT_STATUS_HAVE_NO_MEMORY(message);
+	
+	message->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call);
+	NT_STATUS_HAVE_NO_MEMORY(message->session);
+
+	message->FolderId = request.FolderId;
+	message->MessageId = request.MessageId;
+	message->handle = 0xFFFFFFFF;
+	
+	DLIST_ADD_END(mpm->messages, message, struct mpm_message *);
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenMessage replies and store OpenMessage MAPI
+   handle.
+
+   This is the second step for message registration:
+
+   * Seek for a given FolderId/MessageId in the mpm_message list
+
+   * If a match is found (expected) and MAPI retval is set to
+     MAPI_E_SUCCESS, update the handle field for the element and
+     commit this message in the tdb store.
+     
+   * If retval is different from MAPI_E_SUCCESS, then delete the
+     record
+
+
+   \param dce_call pointer to the session context
+   \param mapi_req reference to the OpenMessage MAPI request entry
+   \param mapi_repl reference to the OpenMessage MAPI response entry
+   \param EcDoRpc pointer to the current EcDoRpc operation
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_push_OpenMessage(struct dcesrv_call_state *dce_call,
+				       struct EcDoRpc_MAPI_REQ mapi_req, 
+				       struct EcDoRpc_MAPI_REPL mapi_repl, 
+				       struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_message	*el;
+	struct mapi_response	*mapi_response;
+	struct OpenMessage_req	request;
+
+	request = mapi_req.u.mapi_OpenMessage;
+
+	mapi_response = EcDoRpc->out.mapi_response;
+
+	for (el = mpm->messages; el; el = el->next) {
+		if ((el->FolderId == request.FolderId) && (el->MessageId == request.MessageId) &&
+		    (mpm_session_cmp(el->session, dce_call) == true)) {
+			if (mapi_repl.error_code == MAPI_E_SUCCESS) {
+				mpm_cache_ldb_add_message((TALLOC_CTX *)mpm, mpm->ldb_ctx, el);
+				el->handle = mapi_response->handles[request.handle_idx];
+				DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Add: Message 0x%"PRIx64" 0x%"PRIx64" 0x%x\n", 
+					  MPM_LOCATION, MPM_SESSION(el), el->FolderId, el->MessageId, el->handle));
+			} else {
+				DEBUG(0, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Message OpenMessage returned %s\n", 
+					  MPM_LOCATION, MPM_SESSION(el), mapi_get_errstr(mapi_repl.error_code)));
+				DLIST_REMOVE(mpm->messages, el);
+			}
+			return NT_STATUS_OK;
+		}
+	}
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenAttach requests and register an attachment in
+   the mpm_messages list.
+
+   This is the first step for attachment registration.  This
+   function first ensures the attachment is not already registered,
+   otherwise delete it. It next creates the attachment entry in the
+   global mpm_message structure.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx the memory context
+   \param mapi_req reference to the OpenAttach EcDoRpc_MAPI_REQ entry
+   \param EcDoRpc pointer to the EcDoRpc operation
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY
+ */
+static NTSTATUS cache_pull_OpenAttach(struct dcesrv_call_state *dce_call,
+				      TALLOC_CTX *mem_ctx, 
+				      struct EcDoRpc_MAPI_REQ mapi_req, 
+				      struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_message	*el;
+	struct mpm_attachment	*attach;
+	struct mapi_request	*mapi_request;
+	struct OpenAttach_req	request;
+
+	mapi_request = EcDoRpc->in.mapi_request;
+	request = mapi_req.u.mapi_OpenAttach;
+
+	for (attach = mpm->attachments; attach; attach = attach->next) {
+		/* Check if the attachment has already been registered */
+		if ((mpm_session_cmp(attach->session, dce_call) == true) &&
+		    (mapi_request->handles[mapi_req.handle_idx] == attach->parent_handle) && (request.AttachmentID == attach->AttachmentID)) {
+			DLIST_REMOVE(mpm->attachments, attach);
+		}
+	}
+
+	attach = talloc((TALLOC_CTX *)mpm, struct mpm_attachment);
+	NT_STATUS_HAVE_NO_MEMORY(attach);
+
+	attach->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call);
+	NT_STATUS_HAVE_NO_MEMORY(attach->session);
+
+	attach->AttachmentID = request.AttachmentID;
+	attach->parent_handle = mapi_request->handles[mapi_req.handle_idx];
+	attach->handle = 0xFFFFFFFF;
+
+	for (el = mpm->messages; el; el = el->next) {
+		if ((mpm_session_cmp(el->session, dce_call) == true) && attach->parent_handle == el->handle) {
+			attach->message = el;
+			break;
+		}
+	}
+
+	DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Add [1]: Attachment %d  parent handle (0x%x) 0x%"PRIx64", 0x%"PRIx64" added to the list\n", 
+		  MPM_LOCATION, MPM_SESSION(attach), request.AttachmentID, attach->parent_handle, 
+		  attach->message->FolderId, attach->message->MessageId));
+	DLIST_ADD_END(mpm->attachments, attach, struct mpm_attachment *);
+	
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenAttach replies and store OpenAttach MAPI
+   handle.
+
+   This is the second step for attachment registration:
+
+   * Seek for a given parent_handle/attachmentID in the
+     mpm_attachments list.
+
+   * if a match is found (expected) and MAPI retval is set to
+     MAPI_E_SUCCESS, update the handle parameter for the element and
+     commit this attachment in the tdb store.
+
+   * If retval is different from MAPI_E_SUCCESS, then delete the
+     element.
+     
+   \param dce_call pointer to the session context
+   \param mapi_req reference to the OpenAttach request entry
+   \param mapi_repl reference to the OpenAttach MAPI response entry
+   \param EcDoRpc pointer to the current EcDoRpc operation
+
+   \return NT_STATUS_OK
+
+ */
+static NTSTATUS cache_push_OpenAttach(struct dcesrv_call_state *dce_call,
+				      struct EcDoRpc_MAPI_REQ mapi_req, 
+				      struct EcDoRpc_MAPI_REPL mapi_repl, 
+				      struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_attachment		*el;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	struct OpenAttach_req		request;
+
+	mapi_request = EcDoRpc->in.mapi_request;
+	mapi_response = EcDoRpc->out.mapi_response;
+	request = mapi_req.u.mapi_OpenAttach;
+
+	for (el = mpm->attachments; el; el = el->next) {
+		if ((mpm_session_cmp(el->session, dce_call) == true) &&
+		    (mapi_request->handles[mapi_req.handle_idx] == el->parent_handle) &&
+		    (request.AttachmentID == el->AttachmentID)) {
+			if (mapi_repl.error_code == MAPI_E_SUCCESS) {
+				el->handle = mapi_response->handles[request.handle_idx];
+				DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Add [2]: Attachment %d with handle 0x%x and parent handle 0x%x\n", 
+					  MPM_LOCATION, MPM_SESSION(el), el->AttachmentID, el->handle, el->parent_handle));
+				mpm_cache_ldb_add_attachment((TALLOC_CTX *)mpm, mpm->ldb_ctx, el);
+			} else {
+				DEBUG(0, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Attachment OpenAttach returned %s\n", 
+					  MPM_LOCATION, MPM_SESSION(el), mapi_get_errstr(mapi_repl.error_code)));
+				DLIST_REMOVE(mpm->attachments, el);
+			}
+			return NT_STATUS_OK;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenStream requests and register a stream in the
+   mpm_streams list.
+
+   We are only interested in monitoring streams related to attachments
+   or messages. This is the first step for stream registration:
+
+   * Look whether this stream inherits from a message or attachment
+   * Fill the stream element according to previous statement
+   * Add it to the mpm_stream list
+
+   \param dce_call pointer to the session context
+   \param mem_ctx the memory context
+   \param mapi_req reference to the OpenStream MAPI request
+   \param EcDoRpc pointer to the current EcDoRpc operation
+   
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY
+ */
+static NTSTATUS cache_pull_OpenStream(struct dcesrv_call_state *dce_call,
+				      TALLOC_CTX *mem_ctx, 
+				      struct EcDoRpc_MAPI_REQ mapi_req, 
+				      struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_stream	*stream;
+	struct mpm_attachment	*attach;
+	struct mpm_message	*message;
+	struct mapi_request	*mapi_request;
+	struct OpenStream_req	request;
+
+	mapi_request = EcDoRpc->in.mapi_request;
+	request = mapi_req.u.mapi_OpenStream;
+
+	for (attach = mpm->attachments; attach; attach = attach->next) {
+		if ((mpm_session_cmp(attach->session, dce_call) == true) &&
+		    mapi_request->handles[mapi_req.handle_idx] == attach->handle) {
+			stream = talloc((TALLOC_CTX *)mpm, struct mpm_stream);
+			NT_STATUS_HAVE_NO_MEMORY(stream);
+
+			stream->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call);
+			NT_STATUS_HAVE_NO_MEMORY(stream->session);
+
+			stream->handle = 0xFFFFFFFF;
+			stream->parent_handle = attach->handle;
+			stream->PropertyTag = request.PropertyTag;
+			stream->StreamSize = 0;
+			stream->filename = NULL;
+			stream->attachment = attach;
+			stream->cached = false;
+			stream->message = NULL;
+			stream->ahead = (mpm->ahead == true) ? true : false;
+			gettimeofday(&stream->tv_start, NULL);
+			DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Stream::attachment added 0x%x 0x%"PRIx64" 0x%"PRIx64"\n", 
+				  MPM_LOCATION, MPM_SESSION(stream), stream->parent_handle, 
+				  stream->attachment->message->FolderId, stream->attachment->message->MessageId));
+			DLIST_ADD_END(mpm->streams, stream, struct mpm_stream *);
+			return NT_STATUS_OK;
+		}
+	}
+
+	for (message = mpm->messages; message; message = message->next) {
+		if ((mpm_session_cmp(message->session, dce_call) == true) &&
+		    mapi_request->handles[mapi_req.handle_idx] == message->handle) {
+			stream = talloc((TALLOC_CTX *)mpm, struct mpm_stream);
+			NT_STATUS_HAVE_NO_MEMORY(stream);
+
+			stream->session = mpm_session_init((TALLOC_CTX *)mpm, dce_call);
+			NT_STATUS_HAVE_NO_MEMORY(stream->session);
+
+			stream->handle = 0xFFFFFFFF;
+			stream->parent_handle = message->handle;
+			stream->PropertyTag = request.PropertyTag;
+			stream->StreamSize = 0;
+			stream->filename = NULL;
+			stream->attachment = NULL;
+			stream->cached = false;
+			stream->ahead = (mpm->ahead == true) ? true : false;
+			gettimeofday(&stream->tv_start, NULL);
+			DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Stream::message added 0x%x\n", 
+				  MPM_LOCATION, MPM_SESSION(stream), stream->parent_handle));
+			stream->message = message;
+			DLIST_ADD_END(mpm->streams, stream, struct mpm_stream *);
+			return NT_STATUS_OK;
+		}
+	}
+
+	DEBUG(1, ("* [%s:%d] Stream: Not related to any attachment or message ?!?\n",
+		      MPM_LOCATION));
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor OpenStream replies and store the OpenStream MAPI
+   handle.
+
+   This is the second step for stream registration:
+
+   * Seek the parent_handle/PropertyTag couple in the mpm_streams
+     list.
+
+   * If a match is found (expected) and MAPI retval is set to
+     MAPI_E_SUCCESS, update the handle field and StreamSize parameters
+     for the element and commit this stream in the tdb store.
+
+   * If retval is different from MAPI_E_SUCCESS, then delete the
+   * element.
+
+   \param dce_call pointer to the session context
+   \param mapi_req reference to the OpenStream MAPI request entry
+   \param mapi_repl reference to the OpenStream MAPI response entry
+   \param EcDoRpc pointer to the current EcDoRpc operation
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_push_OpenStream(struct dcesrv_call_state *dce_call,
+				      struct EcDoRpc_MAPI_REQ mapi_req, 
+				      struct EcDoRpc_MAPI_REPL mapi_repl, 
+				      struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_stream	*el;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct OpenStream_req	request;
+	struct OpenStream_repl	response;
+
+	mapi_request = EcDoRpc->in.mapi_request;
+	mapi_response = EcDoRpc->out.mapi_response;
+	request = mapi_req.u.mapi_OpenStream;
+	response = mapi_repl.u.mapi_OpenStream;
+
+	for (el = mpm->streams; el; el = el->next) {
+		if ((mpm_session_cmp(el->session, dce_call) == true) &&
+		    (mapi_request->handles[mapi_req.handle_idx] == el->parent_handle)) {
+			if (request.PropertyTag == el->PropertyTag) {
+				if (mapi_repl.error_code == MAPI_E_SUCCESS) {
+					el->handle = mapi_response->handles[request.handle_idx];
+					el->StreamSize = response.StreamSize;
+					DEBUG(2, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Add [2]: Stream for Property Tag 0x%x, handle 0x%x and size = %d\n", 
+						  MPM_LOCATION, MPM_SESSION(el), el->PropertyTag, el->handle, el->StreamSize));
+					mpm_cache_ldb_add_stream(mpm, mpm->ldb_ctx, el);
+				} else {
+					DEBUG(0, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Del: Stream OpenStream returned %s\n", 
+						  MPM_LOCATION, MPM_SESSION(el), mapi_get_errstr(mapi_repl.error_code)));
+					DLIST_REMOVE(mpm->streams, el);
+				}
+				return NT_STATUS_OK;
+			}
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Monitor ReadStream replies.
+
+   This function writes ReadStream data received from remote server
+   and associated to messages or attachments to the opened associated
+   file. This function only writes data if the file is not already
+   cached, otherwise it just returns.
+
+   \param dce_call pointer to the session context
+   \param mapi_req reference to the ReadStream MAPI request
+   \param mapi_repl reference to the ReadStream MAPI reply
+   \param EcDoRpc pointer to the current EcDoRpc operation
+
+   \return NT_STATUS_OK
+
+   \sa cache_dispatch
+ */
+static NTSTATUS cache_push_ReadStream(struct dcesrv_call_state *dce_call,
+				      struct EcDoRpc_MAPI_REQ mapi_req,
+				      struct EcDoRpc_MAPI_REPL mapi_repl, 
+				      struct EcDoRpc *EcDoRpc)
+{
+	struct mpm_stream	*stream;
+	struct mapi_response	*mapi_response;
+	struct ReadStream_repl	response;
+	struct ReadStream_req	request;
+
+	mapi_response = EcDoRpc->out.mapi_response;
+	response = mapi_repl.u.mapi_ReadStream;
+	request = mapi_req.u.mapi_ReadStream;
+
+	/* Check if the handle is registered */
+	for (stream = mpm->streams; stream; stream = stream->next) {
+		if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+		    mapi_response->handles[mapi_repl.handle_idx] == stream->handle) {
+			if (stream->fp && stream->cached == false) {
+				if (mpm->sync == true && stream->StreamSize > mpm->sync_min) {
+					cache_exec_sync_cmd(stream);
+				} else {
+					DEBUG(5, ("* [%s:%d] [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] %zd bytes from remove server\n", 
+						  MPM_LOCATION, MPM_SESSION(stream), response.data.length));
+					mpm_cache_stream_write(stream, response.data.length, response.data.data);
+					if (stream->offset == stream->StreamSize) {
+						if (response.data.length) {
+							cache_dump_stream_stat(stream);
+						}
+					}
+				}
+			} else if (stream->cached == true) {
+				/* This is managed by the dispatch routine */
+			}
+			return NT_STATUS_OK;
+		}
+	}
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Analyze EcDoRpc MAPI requests
+
+   This function loops over EcDoRpc MAPI calls and search for the
+   opnums required by the cache module to monitor Stream traffic
+   properly.
+
+   \param dce_call the session context
+   \param mem_ctx the memory context
+   \param r generic pointer on EcDoRpc operation
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	struct EcDoRpc		*EcDoRpc;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	uint32_t		i;
+
+	if (dce_call->pkt.u.request.opnum != 0x2) {
+		return NT_STATUS_OK;
+	}
+
+	EcDoRpc = (struct EcDoRpc *) r;
+	if (!EcDoRpc) return NT_STATUS_OK;
+	if (!&(EcDoRpc->in)) return NT_STATUS_OK;
+	if (!EcDoRpc->in.mapi_request) return NT_STATUS_OK;
+	if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK;
+
+	/* If this is an idle request, do not go further */
+	if (EcDoRpc->in.mapi_request->length == 2) {
+		return NT_STATUS_OK;
+	}
+
+	mapi_req = EcDoRpc->in.mapi_request->mapi_req;
+	for (i = 0; mapi_req[i].opnum; i++) {
+		switch (mapi_req[i].opnum) {
+		case op_MAPI_OpenMessage:
+			cache_pull_OpenMessage(dce_call, (TALLOC_CTX *)mpm, mapi_req[i].u.mapi_OpenMessage);
+			break;
+		case op_MAPI_OpenAttach:
+			cache_pull_OpenAttach(dce_call, (TALLOC_CTX *)mpm, mapi_req[i], EcDoRpc);
+			break;
+		case op_MAPI_OpenStream:
+			cache_pull_OpenStream(dce_call, (TALLOC_CTX *)mpm, mapi_req[i], EcDoRpc);
+			break;
+		case op_MAPI_Release:
+			cache_pull_Release(dce_call, EcDoRpc, mapi_req[i].handle_idx);
+			break;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Analyze EcDoRpc MAPI responses
+
+   This function loops over EcDoRpc MAPI calls and search for the
+   opnums required by the cache module to monitor Stream traffic
+   properly.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx the memory context
+   \param r generic pointer on EcDoRpc operation
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_push(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	struct EcDoRpc			*EcDoRpc;
+	struct EcDoRpc_MAPI_REPL	*mapi_repl;
+	struct EcDoRpc_MAPI_REQ		*mapi_req;
+	uint32_t			i;
+	uint32_t			index;
+
+	if (dce_call->pkt.u.request.opnum != 0x2) {
+		return NT_STATUS_OK;
+	}
+
+	EcDoRpc = (struct EcDoRpc *) r;
+	if (!EcDoRpc) return NT_STATUS_OK;
+	if (!&(EcDoRpc->out)) return NT_STATUS_OK;
+	if (!EcDoRpc->out.mapi_response) return NT_STATUS_OK;
+	if (!EcDoRpc->out.mapi_response->mapi_repl) return NT_STATUS_OK;
+
+	/* If this is an idle request, do not got further */
+	if (EcDoRpc->out.mapi_response->length == 2) {
+		return NT_STATUS_OK;
+	}
+
+	mapi_repl = EcDoRpc->out.mapi_response->mapi_repl;
+	mapi_req = EcDoRpc->in.mapi_request->mapi_req;
+
+	for (i = 0; mapi_repl[i].opnum; i++) {
+		switch (mapi_repl[i].opnum) {
+		case op_MAPI_OpenMessage:
+			index = cache_find_call_request_index(op_MAPI_OpenMessage, mapi_req);
+			if (index == -1) break;
+			cache_push_OpenMessage(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc);
+			break;
+		case op_MAPI_OpenAttach:
+			index = cache_find_call_request_index(op_MAPI_OpenAttach, mapi_req);
+			if (index == -1) break;
+			cache_push_OpenAttach(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc);
+			break;
+		case op_MAPI_OpenStream:
+			index = cache_find_call_request_index(op_MAPI_OpenStream, mapi_req);
+			if (index == -1) break;
+			cache_push_OpenStream(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc);
+			break;
+		case op_MAPI_ReadStream:
+			index = cache_find_call_request_index(op_MAPI_ReadStream, mapi_req);
+			if (index == -1) break;
+			cache_push_ReadStream(dce_call, mapi_req[index], mapi_repl[i], EcDoRpc);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Dispatch function. 
+
+   This function avoids calling dcerpc_ndr_request - understand
+   forwarding client request to remove server - when the client is
+   reading a message/attachment stream available in the cache.
+
+   This function can also be used to loop over dcerpc_ndr_request and
+   perform a read-ahead operation.
+
+   \param dce_call the session context
+   \param mem_ctx the memory context
+   \param r pointer on EcDoRpc operation
+   \param mapiproxy pointer to a mapiproxy structure controlling
+   mapiproxy behavior.
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS cache_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+			       void *r, struct mapiproxy *mapiproxy)
+{
+	struct EcDoRpc		*EcDoRpc;
+	struct mapi_request	*mapi_request;
+	struct mapi_response	*mapi_response;
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct mpm_stream	*stream;
+	uint32_t		i;
+	uint32_t		count;
+
+	if (dce_call->pkt.u.request.opnum != 0x2) {
+		return NT_STATUS_OK;
+	}
+
+	EcDoRpc = (struct EcDoRpc *) r;
+	if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK;
+
+	/* If this is an idle request, do not got further */
+	if (EcDoRpc->in.mapi_request->length == 2) {
+		return NT_STATUS_OK;
+	}
+
+	mapi_request = EcDoRpc->in.mapi_request;
+	mapi_response = EcDoRpc->out.mapi_response;
+	mapi_req = mapi_request->mapi_req;
+	
+	for (count = 0, i = 0; mapi_req[i].opnum; i++) {
+		switch (mapi_req[i].opnum) {
+		case op_MAPI_ReadStream:
+			count++;
+			break;
+		}
+	}
+
+	/* If we have more than count cached calls, forward to Exchange */
+	if (i > count) return NT_STATUS_OK;
+
+	for (i = 0; mapi_req[i].opnum; i++) {
+		switch (mapi_req[i].opnum) {
+		case op_MAPI_ReadStream:
+		{
+			struct ReadStream_req	request;
+
+			request = mapi_req[i].u.mapi_ReadStream;
+			for (stream = mpm->streams; stream; stream = stream->next) {
+				if ((mpm_session_cmp(stream->session, dce_call) == true) &&
+				    (mapi_request->handles[mapi_req[i].handle_idx] == stream->handle)) {
+					if (stream->cached == true) {
+					cached:
+						mapiproxy->norelay = true;
+						mapiproxy->ahead = false;
+						/* Create a fake ReadStream reply */
+						mapi_response->mapi_repl = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REPL, i + 2);
+						mapi_response->mapi_repl[i].opnum = op_MAPI_ReadStream;
+						mapi_response->mapi_repl[i].handle_idx = mapi_req[i].handle_idx;
+						mapi_response->mapi_repl[i].error_code = MAPI_E_SUCCESS;
+						mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length = 0;
+						mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data = talloc_size(mem_ctx, request.ByteCount);
+						mpm_cache_stream_read(stream, (size_t) request.ByteCount, 
+								      &mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length,
+								      &mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data);
+						if (stream->offset == stream->StreamSize) {
+							if (mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length) {
+								cache_dump_stream_stat(stream);
+							}
+						}
+						DEBUG(5, ("* [%s:%d] %zd bytes read from cache\n", MPM_LOCATION,
+							  mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length));
+						mapi_response->handles = talloc_array(mem_ctx, uint32_t, 1);
+						mapi_response->handles[0] = stream->handle;
+						mapi_response->mapi_len = 0xE + mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length;
+						mapi_response->length = mapi_response->mapi_len - 4;
+						*EcDoRpc->out.length = mapi_response->mapi_len;
+						EcDoRpc->out.size = EcDoRpc->in.size;
+						break;
+					} else if ((stream->cached == false) && (stream->ahead == true)) {
+						if (mapiproxy->ahead == true)  {
+							mpm_cache_stream_write(stream,
+									       mapi_response->mapi_repl[i].u.mapi_ReadStream.data.length,
+									       mapi_response->mapi_repl[i].u.mapi_ReadStream.data.data);
+							/* When read ahead is over */
+							if (stream->offset == stream->StreamSize) {
+								cache_dump_stream_stat(stream);
+								mpm_cache_stream_reset(stream);
+								stream->cached = true;
+								stream->ahead = false;
+								goto cached;
+							}
+						} else {
+							mapiproxy->ahead = true;
+						}
+					}
+				}
+			}
+		}
+		break;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details 
+ */
+static NTSTATUS cache_unbind(struct server_id server_id, uint32_t context_id)
+{
+	struct mpm_message	*message;
+	struct mpm_attachment	*attach;
+	struct mpm_stream	*stream;
+
+	/* Look over messages still attached to the session */
+	message = mpm->messages;
+	while (message) {
+		if ((mpm_session_cmp_sub(message->session, server_id, context_id) == true)) {
+			DEBUG(2, ("[%s:%d]: [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Message - 0x%"PRIx64"/0x%"PRIx64" handle(0x%x)\n",
+				  MPM_LOCATION, MPM_SESSION(message), message->FolderId, message->MessageId, 
+				  message->handle));
+			mpm_session_release(message->session);
+			DLIST_REMOVE(mpm->messages, message);
+			talloc_free(message);
+			message = mpm->messages;
+		} else {
+			message = message->next;
+		}
+	}
+
+	/* Look over attachments still attached to the session */
+	attach = mpm->attachments;
+	while (attach) {
+		if ((mpm_session_cmp_sub(attach->session, server_id, context_id) == true)) {
+			DEBUG(2, ("[%s:%d]: [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Attachment - AttachmentID(0x%x) handle(0x%x)\n",
+				  MPM_LOCATION, MPM_SESSION(attach), attach->AttachmentID, attach->handle));
+			mpm_session_release(attach->session);
+			DLIST_REMOVE(mpm->attachments, attach);
+			talloc_free(attach);
+			attach = mpm->attachments;
+		} else {
+			attach = attach->next;
+		}
+	}
+
+	stream = mpm->streams;
+	while (stream) {
+		if ((mpm_session_cmp_sub(stream->session, server_id, context_id) == true)) {
+			DEBUG(2, ("[%s:%d]: [s(0x%"PRIx64"-0x%x-0x%x),c(0x%x)] Stream - handle(0x%x)\n", MPM_LOCATION,
+				  MPM_SESSION(stream), stream->handle));
+			mpm_session_release(stream->session);
+			mpm_cache_stream_close(stream);
+			talloc_free(stream->filename);
+			DLIST_REMOVE(mpm->streams, stream);
+			talloc_free(stream);
+			stream = mpm->streams;
+		} else {
+			stream = stream->next;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize the cache module and retrieve configuration from
+   smb.conf
+
+   Possible smb.conf parameters:
+	* mpm_cache:database
+
+   \param dce_ctx the session context
+
+   \return NT_STATUS_OK on success otherwise
+   NT_STATUS_INVALID_PARAMETER, NT_STATUS_NO_MEMORY
+ */
+static NTSTATUS cache_init(struct dcesrv_context *dce_ctx)
+{
+	char			*database;
+	struct loadparm_context	*lp_ctx;
+	NTSTATUS		status;
+
+	mpm = talloc_zero(dce_ctx, struct mpm_cache);
+	if (!mpm) return NT_STATUS_NO_MEMORY;
+	mpm->messages = NULL;
+	mpm->attachments = NULL;
+	mpm->streams = NULL;
+
+	mpm->ahead = lp_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "ahead", false);
+	mpm->sync = lp_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync", false);
+	mpm->sync_min = lp_parm_int(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync_min", 500000);
+	mpm->sync_cmd = str_list_make(dce_ctx, lp_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "sync_cmd"), " ");
+	mpm->dbpath = lp_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "path");
+
+	if ((mpm->ahead == true) && mpm->sync) {
+		DEBUG(0, ("%s: cache:ahead and cache:sync are exclusive!\n", MPM_ERROR));
+		talloc_free(mpm);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (!mpm->dbpath) {
+		DEBUG(0, ("%s: Missing mpm_cache:path parameter\n", MPM_ERROR));
+		talloc_free(mpm);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	database = talloc_asprintf(dce_ctx->lp_ctx, "tdb://%s/%s", mpm->dbpath, MPM_DB);
+	status = mpm_cache_ldb_createdb(dce_ctx, database, &mpm->ldb_ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(database);
+		talloc_free(mpm);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	lp_ctx = loadparm_init(dce_ctx);
+	lp_load_default(lp_ctx);
+	dcerpc_init(lp_ctx);
+
+	talloc_free(database);
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Entry point for the cache mapiproxy module
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	module;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	module.name = "cache";
+	module.description = "Cache MAPI messages and attachments";
+	module.endpoint = "exchange_emsmdb";
+
+	/* Fill in all the operations */
+	module.init = cache_init;
+	module.unbind = cache_unbind;
+	module.push = cache_push;
+	module.ndr_pull = NULL;
+	module.pull = cache_pull;
+	module.dispatch = cache_dispatch;
+
+	/* Register ourselves with the MAPIPROXY subsystem */
+	ret = mapiproxy_module_register(&module);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'cache' mapiproxy module!\n"));
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/modules/mpm_cache.h
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_cache.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,124 @@
+/*
+   MAPI Proxy - Cache module
+
+   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	__MPM_CACHE_H
+#define	__MPM_CACHE_H
+
+#include <stdio.h>
+
+#include <libmapi/dlinklist.h>
+#include <ldb_errors.h>
+#include <ldb.h>
+
+#ifndef	__BEGIN_DECLS
+#ifdef	__cplusplus
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+#endif
+
+struct mpm_message {
+	struct mpm_session	*session;
+	uint32_t		handle;
+	uint64_t       		FolderId;
+	uint64_t       		MessageId;
+	struct mpm_message	*prev;
+	struct mpm_message	*next;
+};
+
+struct mpm_attachment {
+	struct mpm_session	*session;
+	uint32_t		parent_handle;
+	uint32_t		handle;
+	uint32_t		AttachmentID;
+	struct mpm_message	*message;
+	struct mpm_attachment	*prev;
+	struct mpm_attachment	*next;
+};
+
+/**
+   A stream can either be for a message or attachment
+ */
+struct mpm_stream {
+	struct mpm_session	*session;
+	uint32_t		parent_handle;
+	uint32_t		handle;
+	enum MAPITAGS		PropertyTag;
+	uint32_t		StreamSize;
+	size_t			offset;
+	FILE			*fp;
+	char			*filename;
+	bool			cached;
+	bool			ahead;
+	struct timeval		tv_start;
+	struct mpm_attachment	*attachment;
+	struct mpm_message	*message;
+	struct mpm_stream	*prev;
+	struct mpm_stream	*next;
+};
+
+/* TODO: Make use of dce_ctx->context->context_id to differentiate sessions ? */
+
+struct mpm_cache {
+	struct ldb_context	*ldb_ctx;
+	struct mpm_message	*messages;
+	struct mpm_attachment	*attachments;
+	struct mpm_stream	*streams;
+	const char		*dbpath;
+	bool			ahead;
+	bool			sync;
+	int			sync_min;
+	char     		**sync_cmd;
+};
+
+__BEGIN_DECLS
+
+NTSTATUS       	samba_init_module(void);
+
+NTSTATUS	mpm_cache_ldb_createdb(struct dcesrv_context *, const char *, struct ldb_context **);
+NTSTATUS	mpm_cache_ldb_add_message(TALLOC_CTX *, struct ldb_context *, struct mpm_message *);
+NTSTATUS	mpm_cache_ldb_add_attachment(TALLOC_CTX *, struct ldb_context *, struct mpm_attachment *);
+NTSTATUS	mpm_cache_ldb_add_stream(struct mpm_cache *, struct ldb_context *, struct mpm_stream *);
+
+NTSTATUS	mpm_cache_stream_open(struct mpm_cache *, struct mpm_stream *);
+NTSTATUS	mpm_cache_stream_close(struct mpm_stream *);
+NTSTATUS	mpm_cache_stream_write(struct mpm_stream *, uint16_t, uint8_t *);
+NTSTATUS	mpm_cache_stream_read(struct mpm_stream *, size_t, size_t *, uint8_t **);
+NTSTATUS	mpm_cache_stream_reset(struct mpm_stream *);
+
+__END_DECLS
+
+/*
+ * Defines
+ */
+
+#define	MPM_NAME	"mpm_cache"
+#define	MPM_ERROR	"[ERROR] mpm_cache:"
+#define	MPM_DB		"mpm_cache.ldb"
+#define	MPM_DB_STORAGE	"data"
+
+#define	MPM_LOCATION	__FUNCTION__, __LINE__
+#define	MPM_SESSION(x)	x->session->server_id.id, x->session->server_id.id2, x->session->server_id.node, x->session->context_id
+
+#endif /* __MPM_CACHE_H */

Added: trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_cache_ldb.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,371 @@
+/*
+   MAPI Proxy - Cache module
+
+   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/>.
+ */
+
+/**
+   \file mpm_cache_ldb.c
+
+   \brief LDB routines for the cache module
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/modules/mpm_cache.h"
+#include <libmapi/defs_private.h>
+#include <util/debug.h>
+
+/**
+   \details Create the cache database
+
+   \param dce_ctx pointer to the session context
+   \param database the complete path to the tdb store
+   \param ldb_ctx pointer to pointer on the the LDB context
+
+   \return NT_STATUS_OK on success, otherwise NT_ERROR:
+   NT_STATUS_NO_MEMORY, NT_STATUS_NOT_FOUND.
+ */
+NTSTATUS mpm_cache_ldb_createdb(struct dcesrv_context *dce_ctx, 
+				const char *database, 
+				struct ldb_context **ldb_ctx)
+{
+	struct ldb_context	*tmp_ctx;
+	struct tevent_context	*ev;
+	int			ret;
+
+	ev = tevent_context_init(dce_ctx);
+	if (!ev) return NT_STATUS_NO_MEMORY;
+
+	tmp_ctx = ldb_init(dce_ctx, ev);
+	if (!tmp_ctx) return NT_STATUS_NO_MEMORY;
+	
+	ret = ldb_connect(tmp_ctx, database, 0, NULL);
+	if (ret != LDB_SUCCESS) {
+		return NT_STATUS_NOT_FOUND;
+	}
+
+	*ldb_ctx = tmp_ctx;
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Add a folder record to the TDB store
+
+   \param mem_ctx pointer to the memory context
+   \param ldb_ctx pointer to the LDB context
+   \param FolderId the ID we will be using to uniquely create the
+   record
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND
+ */
+static NTSTATUS  mpm_cache_ldb_add_folder(TALLOC_CTX *mem_ctx, 
+					  struct ldb_context *ldb_ctx,
+					  uint64_t FolderId)
+{
+	struct ldb_message	*msg;
+	char			*dn;
+	int			ret;
+
+	msg = ldb_msg_new(mem_ctx);
+	if (msg == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	dn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=Cache", FolderId);
+	msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	talloc_free(dn);
+	if (!msg->dn) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	ret = ldb_add(ldb_ctx, msg);
+	if (ret != 0) {
+		DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n",
+			  MPM_LOCATION, ldb_dn_get_linearized(msg->dn), 
+			  ldb_errstring(ldb_ctx)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Add a message record to the TDB store
+
+   \param mem_ctx pointer to the memory context
+   \param ldb_ctx pointer to the LDB context
+   \param message pointer to the mpm_message entry with the folder and
+   message ID
+
+   \return NT_STATUS_OK on success, otherwise a NT error
+ */
+NTSTATUS mpm_cache_ldb_add_message(TALLOC_CTX *mem_ctx, 
+				   struct ldb_context *ldb_ctx, 
+				   struct mpm_message *message)
+{
+	NTSTATUS	       	status;
+	struct ldb_message     	*msg;
+	struct ldb_dn	       	*dn;
+	struct ldb_result      	*res;
+	char		       	*basedn;
+	int		       	ret;
+
+	/* First check if the CN=Folder,CN=Cache entry exists */
+	basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=Cache", message->FolderId);
+	dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!dn) return NT_STATUS_UNSUCCESSFUL;
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
+	if (ret == LDB_SUCCESS && !res->count) {
+		DEBUG(5, ("* [%s:%d] We have to create folder TDB record: CN=0x%"PRIx64",CN=Cache\n", 
+			  MPM_LOCATION, message->FolderId));
+		status = mpm_cache_ldb_add_folder(mem_ctx, ldb_ctx, message->FolderId);
+		if (!NT_STATUS_IS_OK(status)) return status;
+	}
+
+	/* Search if the message doesn't already exist */
+	basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", 
+				 message->MessageId, message->FolderId);
+	dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!dn) return NT_STATUS_UNSUCCESSFUL;
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
+	if (res->count) return NT_STATUS_OK;
+
+	/* Create the CN=Message,CN=Folder,CN=Cache */
+	msg = ldb_msg_new(mem_ctx);
+	if (msg == NULL) return NT_STATUS_NO_MEMORY;
+
+	basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache", 
+				 message->MessageId, message->FolderId);
+	msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!msg->dn) return NT_STATUS_NO_MEMORY;
+
+	ret = ldb_add(ldb_ctx, msg);
+	if (ret != 0) {
+		DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n",
+			  MPM_LOCATION, ldb_dn_get_linearized(msg->dn), 
+			  ldb_errstring(ldb_ctx)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Add an attachment record to the TDB store
+ 
+   \param mem_ctx pointer to the memory context
+   \param ldb_ctx pointer to the LDB context
+   \param attach pointer to the mpm_attachment entry
+
+   \return NT_STATUS_OK on success, otherwise a NT error
+*/
+NTSTATUS mpm_cache_ldb_add_attachment(TALLOC_CTX *mem_ctx,
+				      struct ldb_context *ldb_ctx,
+				      struct mpm_attachment *attach)
+{
+	struct mpm_message	*message;
+	struct ldb_message	*msg;
+	struct ldb_dn		*dn;
+	struct ldb_result	*res;
+	char			*basedn;
+	int			ret;
+
+	message = attach->message;
+
+	/* Search if the attachment doesn't already exist */
+	basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+				 attach->AttachmentID, message->MessageId, 
+				 message->FolderId);
+	dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!dn) return NT_STATUS_UNSUCCESSFUL;
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL);
+	if (ret == LDB_SUCCESS && res->count) return NT_STATUS_OK;
+
+	DEBUG(2, ("* [%s:%d] Create the attachment TDB record\n", MPM_LOCATION));
+
+	msg = ldb_msg_new(mem_ctx);
+	if (msg == NULL) return NT_STATUS_NO_MEMORY;
+	
+	basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+				 attach->AttachmentID, message->MessageId, 
+				 message->FolderId);
+	msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!msg->dn) return NT_STATUS_NO_MEMORY;
+
+	ret = ldb_add(ldb_ctx, msg);
+	if (ret != 0) {
+		DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n",
+			  MPM_LOCATION, ldb_dn_get_linearized(msg->dn), 
+			  ldb_errstring(ldb_ctx)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Add stream references to a message or attachment in the
+   TDB store
+
+   \param mpm pointer to the cache module general structure
+   \param ldb_ctx pointer to the LDB context
+   \param stream pointer to the mpm_stream entry
+
+   \return NT_STATUS_OK on success, otherwise NT error
+ */
+NTSTATUS mpm_cache_ldb_add_stream(struct mpm_cache *mpm, 
+				  struct ldb_context *ldb_ctx,
+				  struct mpm_stream *stream)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct mpm_message	*message;
+	struct mpm_attachment	*attach;
+	struct ldb_message	*msg;
+	struct ldb_dn		*dn;
+	const char * const	attrs[] = { "*", NULL };
+	struct ldb_result	*res;
+	char			*basedn = NULL;
+	char			*attribute;
+	int			ret;
+	uint32_t		i;
+
+	mem_ctx = (TALLOC_CTX *) mpm;
+	
+	if (stream->attachment) {
+		attach = stream->attachment;
+		message = attach->message;
+	} else if (stream->message) {
+		attach = NULL;
+		message = stream->message;
+	} else {
+		return NT_STATUS_OK;
+	}
+
+	/* This is a stream for an attachment */
+	if (stream->attachment) {
+		basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+					 attach->AttachmentID, message->MessageId,
+					 message->FolderId);
+		dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn);
+		talloc_free(basedn);
+		if (!dn) return NT_STATUS_UNSUCCESSFUL;
+		
+		attribute = talloc_asprintf(mem_ctx, "(0x%x=*)", stream->PropertyTag);
+		ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, 
+						 attribute);
+		talloc_free(attribute);
+
+		if (ret == LDB_SUCCESS && res->count == 1) {
+			attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag);
+			basedn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], attribute, NULL);
+			talloc_free(attribute);
+			DEBUG(2, ("* [%s:%d] Loading from cache 0x%x = %s\n", MPM_LOCATION,
+				  stream->PropertyTag, basedn));
+			stream->filename = talloc_strdup(mem_ctx, basedn);
+			stream->cached = true;
+			stream->ahead = false;
+			mpm_cache_stream_open(mpm, stream);
+
+			return NT_STATUS_OK;
+		}
+
+		/* Otherwise create the stream with basedn above */
+		basedn = talloc_asprintf(mem_ctx, "CN=%d,CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+					 attach->AttachmentID, message->MessageId,
+					 message->FolderId);
+
+		DEBUG(2, ("* [%s:%d] Create the stream TDB record for attachment\n", MPM_LOCATION));
+	} 
+
+	if (stream->message) {
+		basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+					 message->MessageId, message->FolderId);
+		dn = ldb_dn_new(mem_ctx, ldb_ctx, basedn);
+		talloc_free(basedn);
+		if (!dn) return NT_STATUS_UNSUCCESSFUL;
+
+		attribute = talloc_asprintf(mem_ctx, "(0x%x=*)", stream->PropertyTag);
+		ret = ldb_search(ldb_ctx, mem_ctx, &res, dn, LDB_SCOPE_BASE, attrs, attribute);
+		talloc_free(attribute);
+
+		if (ret == LDB_SUCCESS && res->count == 1) {
+			attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag);
+			basedn = (char *) ldb_msg_find_attr_as_string(res->msgs[0], attribute, NULL);
+			talloc_free(attribute);
+			DEBUG(2, ("* [%s:%d] Loading from cache 0x%x = %s\n", MPM_LOCATION,
+				  stream->PropertyTag, basedn));
+			stream->filename = talloc_strdup(mem_ctx, basedn);
+			stream->cached = true;
+			stream->ahead = false;
+			mpm_cache_stream_open(mpm, stream);
+
+			return NT_STATUS_OK;
+		}
+
+		/* Otherwise create the stream with basedn above */
+		basedn = talloc_asprintf(mem_ctx, "CN=0x%"PRIx64",CN=0x%"PRIx64",CN=Cache",
+					 message->MessageId, message->FolderId);
+		
+		DEBUG(2, ("* [%s:%d] Modify the message TDB record and append stream information\n",
+			  MPM_LOCATION));
+	}
+
+	stream->cached = false;
+	mpm_cache_stream_open(mpm, stream);
+
+	msg = ldb_msg_new(mem_ctx);
+	if (msg == NULL) return NT_STATUS_NO_MEMORY;
+
+	msg->dn = ldb_dn_new(ldb_ctx, ldb_ctx, basedn);
+	talloc_free(basedn);
+	if (!msg->dn) return NT_STATUS_NO_MEMORY;
+	
+	attribute = talloc_asprintf(mem_ctx, "0x%x", stream->PropertyTag);
+	ldb_msg_add_fmt(msg, attribute, "%s", stream->filename);
+	talloc_free(attribute);
+	
+	attribute = talloc_asprintf(mem_ctx, "0x%x_StreamSize", stream->PropertyTag);
+	ldb_msg_add_fmt(msg, attribute, "%d", stream->StreamSize);
+	talloc_free(attribute);
+
+	/* mark all the message elements as LDB_FLAG_MOD_REPLACE */
+	for (i=0;i<msg->num_elements;i++) {
+		msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
+	}
+	
+	ret = ldb_modify(ldb_ctx, msg);
+	if (ret != 0) {
+		DEBUG(0, ("* [%s:%d] Failed to modify record %s: %s\n",
+			  MPM_LOCATION, ldb_dn_get_linearized(msg->dn), 
+			  ldb_errstring(ldb_ctx)));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return NT_STATUS_OK;
+}

Added: trunk/openchange/mapiproxy/modules/mpm_cache_stream.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_cache_stream.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_cache_stream.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,201 @@
+/*
+   MAPI Proxy - Cache module
+
+   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/>.
+ */
+
+/**
+   \file mpm_cache_stream.c
+
+   \brief Storage routines for the cache module
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/modules/mpm_cache.h"
+#include <libmapi/defs_private.h>
+#include <util/debug.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <errno.h>
+
+/**
+   \details Create a file: message or attachment in the cache
+
+   If the stream is attached to an attachment:	FolderID/MessageID/AttachmentID.stream
+   If the stream is attached to a message:	FolderID/MessageID.stream
+
+   \param mpm pointer to the cache module general structure
+   \param stream pointer to the mpm_stream entry
+
+   \return Return a FILE pointer otherwise NULL
+ */
+NTSTATUS mpm_cache_stream_open(struct mpm_cache *mpm, struct mpm_stream *stream)
+{
+	TALLOC_CTX	*mem_ctx;
+	char		*file;
+	int		ret;
+
+	mem_ctx = (TALLOC_CTX *) mpm;
+
+	if (stream->filename) {
+		stream->fp = fopen(stream->filename, "r");
+		stream->offset = 0;
+		return NT_STATUS_OK;
+	}
+
+	if (stream->message) {
+		/* Create the folder */
+		file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64, mpm->dbpath, stream->message->FolderId);
+		ret = mkdir(file, 0777);
+		talloc_free(file);
+		if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL;
+
+		/* Open the file */
+		file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64".stream",
+				       mpm->dbpath, stream->message->FolderId,
+				       stream->message->MessageId);
+
+		DEBUG(2, ("* [%s:%d]: Opening Message stream %s\n", MPM_LOCATION, file));
+		stream->filename = talloc_strdup(mem_ctx, file);
+		stream->fp = fopen(file, "w+");
+		stream->offset = 0;
+		talloc_free(file);
+		
+		return NT_STATUS_OK;
+	}
+
+	if (stream->attachment) {
+		/* Create the folders */
+		file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64, mpm->dbpath, 
+				       stream->attachment->message->FolderId);
+		ret = mkdir(file, 0777);
+		talloc_free(file);
+		if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL;
+
+		file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64, mpm->dbpath,
+				       stream->attachment->message->FolderId, 
+				       stream->attachment->message->MessageId);
+		ret = mkdir(file, 0777);
+		talloc_free(file);
+		if ((ret == -1) && (errno != EEXIST)) return NT_STATUS_UNSUCCESSFUL;
+
+		file = talloc_asprintf(mem_ctx, "%s/0x%"PRIx64"/0x%"PRIx64"/%d.stream", 
+				       mpm->dbpath,
+				       stream->attachment->message->FolderId, 
+				       stream->attachment->message->MessageId,
+				       stream->attachment->AttachmentID);
+
+		DEBUG(2, ("* [%s:%d]: Opening Attachment stream %s\n", MPM_LOCATION, file));
+		stream->filename = talloc_strdup(mem_ctx, file);
+		stream->fp = fopen(file, "w+");
+		stream->offset = 0;
+		talloc_free(file);
+
+		return NT_STATUS_OK;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Close the filesystem stream
+
+   \param stream pointer to the mpm_stream entry
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_NOT_FOUND
+ */
+NTSTATUS mpm_cache_stream_close(struct mpm_stream *stream)
+{
+	if (stream && stream->fp) {
+		fclose(stream->fp);
+		stream->fp = NULL;
+	} else {
+		return NT_STATUS_NOT_FOUND;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Read input_size bytes from a local binary stream
+
+   \param stream pointer to the mpm_stream entry
+   \param input_size the number of bytes to read
+   \param length output pointer to the length effectively read from the
+   stream
+   \param data output pointer to the binary data read from the stream
+
+   \return NT_STATUS_OK
+ */
+NTSTATUS mpm_cache_stream_read(struct mpm_stream *stream, size_t input_size, size_t *length, uint8_t **data)
+{
+	fseek(stream->fp, stream->offset, SEEK_SET);
+	*length = fread(*data, sizeof (uint8_t), input_size, stream->fp);
+	stream->offset += *length;
+	DEBUG(5, ("* [%s:%d]: Current offset: 0x%zx\n", MPM_LOCATION,
+		  stream->offset));
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Write length bytes to a local stream
+
+   \param stream pointer to the mpm_stream entry
+   \param length the data length to write to the stream
+   \param data pointer to the data to write to the stream
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_UNSUCCESSFUL
+ */
+NTSTATUS mpm_cache_stream_write(struct mpm_stream *stream, uint16_t length, uint8_t *data)
+{
+	uint32_t	WrittenSize;
+
+	fseek(stream->fp, stream->offset, SEEK_SET);
+	WrittenSize = fwrite(data, sizeof (uint8_t), length, stream->fp);
+	if (WrittenSize != length) {
+		DEBUG(0, ("* [%s:%d] WrittenSize != length\n", MPM_LOCATION));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	stream->offset += WrittenSize;
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Rewind a stream to the beginning
+
+   \param stream pointer to the mpm_stream entry
+
+   \return NT_STATUS_OK on success
+ */
+NTSTATUS mpm_cache_stream_reset(struct mpm_stream *stream)
+{
+	fseek(stream->fp, 0, SEEK_SET);
+	stream->offset = 0;
+
+	return NT_STATUS_OK;
+}

Added: trunk/openchange/mapiproxy/modules/mpm_downgrade.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_downgrade.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_downgrade.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,148 @@
+/*
+   MAPI Proxy - Downgrade Module
+
+   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/>.
+ */
+
+/**
+   \file mpm_downgrade.c
+
+   \brief Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include <util/debug.h>
+
+
+/**
+   \details This function replaces the store_version short array
+   returned by Exchange in EcDoConnect with a version matching
+   Exchange 2000. Otherwise Outlook tries to upgrade indefinitely.
+
+   \param dce_call pointer to the session context
+   \param r pointer to the EcDoConnect structure
+
+   \return true on success
+ */
+static bool downgrade_EcDoConnect(struct dcesrv_call_state *dce_call, struct EcDoConnect *r)
+{
+	r->out.rgwServerVersion[0] = 0x0006;
+	r->out.rgwServerVersion[1] = 0x1141;
+	r->out.rgwServerVersion[2] = 0x0005;
+
+	return true;
+}
+
+
+static NTSTATUS downgrade_push(struct dcesrv_call_state *dce_call,
+			       TALLOC_CTX *mem_ctx, void *r)
+{
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+	const char				*name;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+	name = table->calls[opnum].name;
+
+	if (table->name && !strcmp(table->name, "exchange_emsmdb")) {
+		if (name && !strcmp(name, "EcDoConnect")) {
+			downgrade_EcDoConnect(dce_call, (struct EcDoConnect *)r);
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS downgrade_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull)
+{
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS downgrade_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Returns the nca_op_rng_error DCERPC status code when
+   Outlook sends an EcDoConnectEx requrest.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r generic pointer to EcDoConnectEx structure
+   \param mapiproxy pointer to the mapiproxy structure
+
+   \return NT_STATUS_NET_WRITE_FAULT when EcDoConnectEx is detected,
+   otherwise NT_STATUS_OK
+
+*/
+static NTSTATUS downgrade_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r,
+				   struct mapiproxy *mapiproxy)
+{
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+
+	table = (const struct ndr_interface_table *)dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+	
+	if ((opnum == 0xA) && (table->name && !strcmp(table->name, "exchange_emsmdb"))) {
+		dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
+		return NT_STATUS_NET_WRITE_FAULT;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/**
+   \details Entry point for the downgrade mapiproxy module
+   
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	module;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	module.name = "downgrade";
+	module.description = "Downgrade EMSMDB protocol version EcDoConnect/EcDoRpc";
+	module.endpoint = "exchange_emsmdb";
+
+	/* Fill in all the operations */
+	module.init = NULL;
+	module.unbind = NULL;
+	module.push = downgrade_push;
+	module.ndr_pull = downgrade_ndr_pull;
+	module.pull = downgrade_pull;
+	module.dispatch = downgrade_dispatch;
+
+	/* Register ourselves with the MAPIPROXY subsystem */
+	ret = mapiproxy_module_register(&module);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'downgrade' mapiproxy module!\n"));
+		return ret;
+	}
+	
+	return ret;
+}

Added: trunk/openchange/mapiproxy/modules/mpm_dummy.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_dummy.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_dummy.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,101 @@
+/*
+   MAPI Proxy - Dummy Module
+
+   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 "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/dcesrv_mapiproxy_proto.h"
+#include <util/debug.h>
+
+/**
+   \details Dummy init function which reads a parametric option from
+   smb.conf and display it on the log channel.
+ */
+static NTSTATUS dummy_init(struct dcesrv_context *dce_ctx)
+{
+	const char	*test;
+
+	test = lp_parm_string(dce_ctx->lp_ctx, NULL, "mpm_dummy", "test");
+	if (test) {
+		DEBUG(0, ("Sample dummy string: %s\n", test));
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS dummy_unbind(struct server_id server_id, uint32_t context_id)
+{
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS dummy_push(struct dcesrv_call_state *dce_call, 
+			   TALLOC_CTX *mem_ctx,  void *r)
+{
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dummy_ndr_pull(struct dcesrv_call_state *dce_call,
+			       TALLOC_CTX *mem_ctx, struct ndr_pull *ndr)
+{
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dummy_pull(struct dcesrv_call_state *dce_call,
+			   TALLOC_CTX *mem_ctx, void *r)
+{
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS dummy_dispatch(struct dcesrv_call_state *dce_call,
+			       TALLOC_CTX *mem_ctx, void *r,
+			       struct mapiproxy *mapiproxy)
+{
+	return NT_STATUS_OK;
+}
+
+
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	module;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	module.name = "dummy";
+	module.description = "dummy MAPIPROXY module";
+	module.endpoint = "exchange_emsmdb";
+
+	/* Fill in all the operations */
+	module.init = dummy_init;
+	module.unbind = dummy_unbind;
+	module.push = dummy_push;
+	module.ndr_pull = dummy_ndr_pull;
+	module.pull = dummy_pull;
+	module.dispatch = dummy_dispatch;
+
+	/* Register ourselves with the MAPIPROXY subsytem */
+	ret = mapiproxy_module_register(&module);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register 'dummy' mapiproxy module!\n"));
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/modules/mpm_pack.c
===================================================================
--- trunk/openchange/mapiproxy/modules/mpm_pack.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/modules/mpm_pack.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,368 @@
+/*
+   MAPI Proxy - Unpack/Pack Module
+
+   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/>.
+ */
+
+/**
+   \file mpm_pack.c
+
+   \brief Pack/Unpack specified MAPI calls into/from a custom MAPI call
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include <util/debug.h>
+
+#define	MPM_NAME	"mpm_pack"
+#define	MPM_PACK_ERROR	"[ERROR] mpm_pack:"
+
+NTSTATUS samba_init_module(void);
+
+static struct mpm_pack {
+	uint8_t		*mapi_calls;
+	bool		lasthop;
+} *mpm = NULL;
+
+
+static uint32_t proxypack(TALLOC_CTX *mem_ctx, struct EcDoRpc_MAPI_REQ *mapi_req, 
+			  struct ndr_push *ndr)
+{
+	struct proxypack_req	request;
+	uint32_t		size;
+
+	/* Fill in the proxypack operation */
+	size = 0;	
+	request.bin.cb = ndr->offset;
+	size += sizeof (uint16_t);
+	request.bin.lpb = talloc_memdup(mem_ctx, ndr->data, ndr->offset);
+	size += ndr->offset;
+
+	/* Fill the MAPI_REQ request */
+	mapi_req->opnum = op_MAPI_proxypack;
+	mapi_req->logon_id = 0;
+	mapi_req->handle_idx = 0;
+	mapi_req->u.mapi_proxypack = request;
+	size += 5;
+
+	return size;
+}
+
+/**
+   \details unpack proxypack contents and restore the original EcDoRpc
+   request
+ */
+static bool unpack(TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc)
+{
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct EcDoRpc_MAPI_REQ	*mapi_newreq;
+	struct ndr_pull		*ndr;
+	bool			found;
+	uint32_t		i;
+	uint8_t			pos;
+	uint32_t		count;
+	uint32_t		nopack_count = 0;
+	uint32_t		nopack_idx = 0;
+	uint32_t		pack_idx = 0;
+
+	mapi_req = EcDoRpc->in.mapi_request->mapi_req;
+
+	/* Seek the unpack call */
+	for (i = 0, found = false; mapi_req[i].opnum; i++) {
+		if (mapi_req[i].opnum == op_MAPI_proxypack) {
+			found = true;
+			break;
+		}
+	}
+	/* Nothing to unpack */
+	if (found == false) return false;
+
+	ndr = talloc_zero(mem_ctx, struct ndr_pull);
+	ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
+
+	ndr->data_size = mapi_req[i].u.mapi_proxypack.bin.cb;
+	ndr->data = mapi_req[i].u.mapi_proxypack.bin.lpb;
+
+	for (nopack_count = 0; mapi_req[nopack_count].opnum; nopack_count++);
+
+	/* Merge unpacked and non packed calls < last packed call position */
+	mapi_newreq = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+	for (count = 0; ndr->offset != ndr->data_size; count++) {
+		NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &pos));
+		if (pack_idx < pos) {
+			while (pack_idx < pos) {
+				if (nopack_idx >= nopack_count) break;
+				
+				mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2);
+				mapi_newreq[pack_idx] = mapi_req[nopack_idx];
+				nopack_idx++;
+				pack_idx++;
+			}
+		}
+		
+		if (pos > pack_idx) {
+			pack_idx = pos;
+		}
+		
+		mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2);
+		NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &mapi_newreq[pos]));
+		pack_idx++;
+	}
+
+	/* Append remaining non packed calls */
+	mapi_newreq[pack_idx].opnum = 0;
+	while (mapi_req[nopack_idx].opnum) {
+		if (nopack_idx > nopack_count) break;
+		
+		if (mapi_req[nopack_idx].opnum != op_MAPI_proxypack) {
+			mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, pack_idx + 2);
+			mapi_newreq[pack_idx] = mapi_req[nopack_idx];
+			pack_idx++;
+			mapi_newreq[pack_idx].opnum = 0;
+		}
+		nopack_idx++;
+	}
+
+	/* Update mapi_request length and mapi_req pointer */
+	EcDoRpc->in.mapi_request->mapi_len -= (5 + count);
+	EcDoRpc->in.mapi_request->length -= (5 + count);
+	EcDoRpc->in.mapi_request->mapi_req = mapi_newreq;
+
+	return true;
+}
+
+/**
+   \details pack EcDoRpc calls into proxypack
+ */
+static bool pack(TALLOC_CTX *mem_ctx, struct EcDoRpc *EcDoRpc)
+{
+	struct EcDoRpc_MAPI_REQ	*mapi_req;
+	struct EcDoRpc_MAPI_REQ	*mapi_newreq;
+	struct ndr_push		*ndr;
+	struct ndr_push		*nopack_ndr;
+	uint32_t		size;
+	uint32_t		handle_size;
+	uint32_t		i, j;
+	uint32_t		idx;
+	bool			found;
+
+	mapi_req = EcDoRpc->in.mapi_request->mapi_req;
+
+	ndr = talloc_zero(mem_ctx, struct ndr_push);
+	ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
+
+	nopack_ndr = talloc_zero(mem_ctx, struct ndr_push);
+	nopack_ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true);
+
+	mapi_newreq = talloc_array(mem_ctx, struct EcDoRpc_MAPI_REQ, 2);
+
+	for (i = 0, idx = 0; mapi_req[i].opnum; i++) {
+		found = false;
+		for (j = 0; mpm->mapi_calls[j]; j++) {
+			if (mapi_req[i].opnum == mpm->mapi_calls[j]) {
+				ndr_push_uint8(ndr, NDR_SCALARS, i);
+				ndr_push_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &mapi_req[i]);
+				found = true;
+				break;
+			}
+		}
+		if (found == false) {
+			mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, idx + 2);
+			ndr_push_EcDoRpc_MAPI_REQ(nopack_ndr, NDR_SCALARS, &mapi_req[i]);
+			mapi_newreq[idx] = mapi_req[i];
+			idx++;
+		}
+	}
+
+	if (ndr->offset == 0) {
+		talloc_free(mapi_newreq);
+		talloc_free(nopack_ndr);
+		talloc_free(ndr);
+		return false;
+	}
+
+	DEBUG(3, ("============ non packed =============\n"));
+	dump_data(3, nopack_ndr->data, nopack_ndr->offset);
+	DEBUG(3, ("=====================================\n"));
+
+	DEBUG(3, ("\n============ packed =============\n"));
+	dump_data(3, ndr->data, ndr->offset);
+	DEBUG(3, ("=================================\n"));
+
+
+	/* Fill in the proxypack operation */
+	mapi_newreq = talloc_realloc(mem_ctx, mapi_newreq, struct EcDoRpc_MAPI_REQ, idx + 2);
+	size = proxypack(mem_ctx, &mapi_newreq[idx], ndr);
+	talloc_free(ndr);
+
+	if (!size) return false;
+
+	idx++;
+	mapi_newreq[idx].opnum = 0;
+
+	/* Recalculate the EcDoRpc request size */
+	handle_size = EcDoRpc->in.mapi_request->mapi_len - EcDoRpc->in.mapi_request->length;
+	EcDoRpc->in.mapi_request->mapi_len = nopack_ndr->offset + size + handle_size;
+	EcDoRpc->in.mapi_request->length = nopack_ndr->offset + size;
+
+	/* Replace EcDoRpc_MAPI_REQ */
+	talloc_free(EcDoRpc->in.mapi_request->mapi_req);
+	EcDoRpc->in.mapi_request->mapi_req = mapi_newreq;
+
+	/* Free memory */
+	talloc_free(nopack_ndr);
+
+	return true;
+}
+
+static NTSTATUS pack_push(struct dcesrv_call_state *dce_call,
+			  TALLOC_CTX *mem_ctx, void *r)
+{
+	return NT_STATUS_OK;
+}
+
+
+static NTSTATUS pack_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct ndr_pull *pull)
+{
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details pack EcDoRpc MAPI requests
+
+   This function searches for MAPI opnums to pack in the requests,
+   add this opnums to the mapiproxy opnum DATA blob and refactor the
+   request to remove references to these calls in the original
+   request.
+ */
+static NTSTATUS pack_pull(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
+{
+	struct EcDoRpc		*EcDoRpc;
+	bool			ret = false;
+
+	if (dce_call->pkt.u.request.opnum != 0x2) {
+		return NT_STATUS_OK;
+	}
+
+	EcDoRpc = (struct EcDoRpc *) r;
+	if (!EcDoRpc->in.mapi_request->mapi_req) return NT_STATUS_OK;
+
+	/* If this is an idle request, do not go further */
+	if (EcDoRpc->in.mapi_request->length == 2) {
+		return NT_STATUS_OK;
+	}
+
+	/* If this is not a last-hop */
+	if (mpm->lasthop == false) return NT_STATUS_OK;
+
+	ret = unpack(mem_ctx, EcDoRpc);
+	if (ret == false) {
+		ret = pack(mem_ctx, EcDoRpc);
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize the pack module and retrieve configuration from
+   smb.conf.
+
+   Possible parameters:
+   * mpm_pack:opnums = 0x1, 0x2, 0x3
+   * mpm_pack:lasthop = true|false
+   
+ */
+static NTSTATUS pack_init(struct dcesrv_context *dce_ctx)
+{
+	char		**calls;
+	unsigned long		opnum;
+	int			i;
+	int			j;
+	struct loadparm_context	*lp_ctx;
+
+	/* Fetch the mapi call list from smb.conf */
+	calls = str_list_make(dce_ctx, lp_parm_string(dce_ctx->lp_ctx, NULL, MPM_NAME, "opnums"), NULL);
+
+	mpm = talloc_zero(dce_ctx, struct mpm_pack);
+	mpm->mapi_calls = talloc_zero(mpm, uint8_t);
+
+	for (i = 0; calls[i]; i++) {
+		opnum = strtol(calls[i], NULL, 16);
+		if (opnum <= 0 || opnum >= 0xFF) {
+			DEBUG(0, ("%s: invalid MAPI opnum 0x%.2x\n", MPM_PACK_ERROR, (uint32_t)opnum));
+			talloc_free(mpm);
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		/* avoid duplicated opnums */
+		for (j = 0; j < i; j++) {
+			if (opnum == mpm->mapi_calls[j]) {
+				DEBUG(0, ("%s: duplicated opnum: 0x%.2x\n", MPM_PACK_ERROR, (uint32_t)opnum));
+				talloc_free(mpm);
+				return NT_STATUS_INVALID_PARAMETER;
+			}
+		}
+		mpm->mapi_calls = talloc_realloc(mpm, mpm->mapi_calls, uint8_t, i + 2);
+		mpm->mapi_calls[i] = (uint8_t) opnum;
+	}
+	mpm->mapi_calls[i] = 0;
+
+	/* Fetch the lasthop parameter from smb.conf */
+	mpm->lasthop = lp_parm_bool(dce_ctx->lp_ctx, NULL, MPM_NAME, "lasthop", true);
+
+	lp_ctx = loadparm_init(dce_ctx);
+	lp_load_default(lp_ctx);
+	dcerpc_init(lp_ctx);
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Entry point for the pack mapiproxy module
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	module;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	module.name = "pack";
+	module.description = "Pack specified MAPI calls into a custom MAPI call";
+	module.endpoint = "exchange_emsmdb";
+
+	/* Fill in all the operations */
+	module.init = pack_init;
+	module.unbind = NULL;
+	module.push = pack_push;
+	module.ndr_pull = pack_ndr_pull;
+	module.pull = pack_pull;
+	module.dispatch = NULL;
+
+	/* Register ourselves with the MAPIPROXY subsystem */
+	ret = mapiproxy_module_register(&module);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'pack' mapiproxy module!\n"));;
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,627 @@
+/*
+   MAPI Proxy - Exchange EMSMDB Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file dcesrv_exchange_emsmdb.c
+
+   \brief OpenChange EMSMDB Server implementation
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+struct exchange_emsmdb_session		*emsmdb_session = NULL;
+void					*openchange_ldb_ctx = NULL;
+
+/**
+   \details exchange_emsmdb EcDoConnect (0x0) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDoConnect request data
+
+   \note Session linking is not supported at the moment
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcDoConnect(struct dcesrv_call_state *dce_call,
+					  TALLOC_CTX *mem_ctx,
+					  struct EcDoConnect *r)
+{
+	struct emsmdbp_context		*emsmdbp_ctx;
+	struct dcesrv_handle		*handle;
+	struct policy_handle		wire_handle;
+	struct exchange_emsmdb_session	*session;
+	struct ldb_message		*msg;
+	const char			*cn;
+	const char			*userDN;
+	char				*dnprefix;
+
+	DEBUG(3, ("exchange_emsmdb: EcDoConnect (0x0)\n"));
+
+	/* Step 0. Ensure incoming use is authenticated */
+	if (!NTLM_AUTH_IS_OK(dce_call)) {
+		DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
+	failure:
+		wire_handle.handle_type = EXCHANGE_HANDLE_EMSMDB;
+		wire_handle.uuid = GUID_zero();
+		*r->out.handle = wire_handle;
+		
+		r->out.pcmsPollsMax = talloc_zero(mem_ctx, uint32_t);
+		r->out.pcRetry = talloc_zero(mem_ctx, uint32_t);
+		r->out.pcmsRetryDelay = talloc_zero(mem_ctx, uint32_t);
+		r->out.picxr = talloc_zero(mem_ctx, uint32_t);
+		r->out.pullTimeStamp = talloc_zero(mem_ctx, uint32_t);
+
+		*r->out.pcmsPollsMax = 0;
+		*r->out.pcRetry = 0;
+		*r->out.pcmsRetryDelay = 0;
+		r->out.szDisplayName = NULL;
+		r->out.szDNPrefix = NULL;
+		r->out.rgwServerVersion[0] = 0;
+		r->out.rgwServerVersion[1] = 0;
+		r->out.rgwServerVersion[2] = 0;
+		r->out.rgwClientVersion[0] = 0;
+		r->out.rgwClientVersion[1] = 0;
+		r->out.rgwClientVersion[2] = 0;
+		*r->out.pullTimeStamp = 0;
+
+		r->out.result = MAPI_E_LOGON_FAILED;
+		return MAPI_E_LOGON_FAILED;
+	}
+
+	/* Step 1. Initialize the emsmdbp context */
+	emsmdbp_ctx = emsmdbp_init(dce_call->conn->dce_ctx->lp_ctx, openchange_ldb_ctx);
+	if (!emsmdbp_ctx) {
+		smb_panic("unable to initialize emsmdbp context");
+		OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_FAILONEPROVIDER, NULL);
+	}
+
+	/* Step 2. Check if incoming user belongs to the Exchange organization */
+	if (emsmdbp_verify_user(dce_call, emsmdbp_ctx) == false) {
+		talloc_free(emsmdbp_ctx);
+		goto failure;
+	}
+
+	/* Step 3. Check if input user DN belongs to the Exchange organization */
+	if (emsmdbp_verify_userdn(dce_call, emsmdbp_ctx, r->in.szUserDN, &msg) == false) {
+		talloc_free(emsmdbp_ctx);
+		goto failure;
+	}
+
+	emsmdbp_ctx->szUserDN = talloc_strdup(emsmdbp_ctx, r->in.szUserDN);
+
+	/* Step 4. Retrieve the display name of the user */
+	r->out.szDisplayName = ldb_msg_find_attr_as_string(msg, "displayName", NULL);
+	emsmdbp_ctx->szDisplayName = talloc_strdup(emsmdbp_ctx, r->out.szDisplayName);
+
+	/* Step 5. Retrieve the dinstinguished name of the server */
+	cn = ldb_msg_find_attr_as_string(msg, "cn", NULL);
+	userDN = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL);
+	dnprefix = strstr(userDN, cn);
+	if (!dnprefix) {
+		talloc_free(emsmdbp_ctx);
+		goto failure;
+	}
+
+	*dnprefix = '\0';
+	r->out.szDNPrefix = strupper_talloc(mem_ctx, userDN);
+
+	/* Step 6. Fill EcDoConnect reply */
+	handle = dcesrv_handle_new(dce_call->context, EXCHANGE_HANDLE_EMSMDB);
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx);
+	
+	handle->data = (void *) emsmdbp_ctx;
+	*r->out.handle = handle->wire_handle;
+
+	r->out.pcmsPollsMax = talloc_zero(mem_ctx, uint32_t);
+	*r->out.pcmsPollsMax = EMSMDB_PCMSPOLLMAX;
+
+	r->out.pcRetry = talloc_zero(mem_ctx, uint32_t);
+	*r->out.pcRetry = EMSMDB_PCRETRY;
+
+	r->out.pcmsRetryDelay = talloc_zero(mem_ctx, uint32_t);
+	*r->out.pcmsRetryDelay = EMSMDB_PCRETRYDELAY;
+
+	r->out.picxr = talloc_zero(mem_ctx, uint32_t);
+	*r->out.picxr = 0;
+
+	r->out.rgwServerVersion[0] = 0x6;
+	r->out.rgwServerVersion[1] = 0x1141;
+	r->out.rgwServerVersion[2] = 0x5;
+
+	r->out.rgwClientVersion[0] = r->in.rgwClientVersion[0];
+	r->out.rgwClientVersion[1] = r->in.rgwClientVersion[1];
+	r->out.rgwClientVersion[2] = r->in.rgwClientVersion[2];
+
+	r->out.pullTimeStamp = talloc_zero(mem_ctx, uint32_t);
+	*r->out.pullTimeStamp = time(NULL);
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	/* Step 7. Associate this emsmdbp context to the session */
+	session = talloc((TALLOC_CTX *)emsmdb_session, struct exchange_emsmdb_session);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx);
+
+	session->pullTimeStamp = *r->out.pullTimeStamp;
+	session->session = mpm_session_init((TALLOC_CTX *)emsmdb_session, dce_call);
+	OPENCHANGE_RETVAL_IF(!session->session, MAPI_E_NOT_ENOUGH_RESOURCES, emsmdbp_ctx);
+
+	mpm_session_set_private_data(session->session, (void *) emsmdbp_ctx);
+	mpm_session_set_destructor(session->session, emsmdbp_destructor);
+
+	DLIST_ADD_END(emsmdb_session, session, struct exchange_emsmdb_session *);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_emsmdb EcDoDisconnect (0x1) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDoDisconnect request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcDoDisconnect(struct dcesrv_call_state *dce_call,
+					     TALLOC_CTX *mem_ctx,
+					     struct EcDoDisconnect *r)
+{
+	struct dcesrv_handle		*h;
+	struct exchange_emsmdb_session	*session;
+
+	DEBUG(3, ("exchange_emsmdb: EcDoDisconnect (0x1)\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;
+	}
+
+	/* Step 1. Retrieve handle and free if emsmdbp context and session are available */
+	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (h) {
+		for (session = emsmdb_session; session; session = session->next) {
+			if ((mpm_session_cmp(session->session, dce_call) == true)) {
+				DLIST_REMOVE(emsmdb_session, session);
+				mpm_session_release(session->session);
+				DEBUG(6, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__));
+				break;
+			}
+		}
+	}
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_emsmdb EcDoRpc (0x2) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDoRpc request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcDoRpc(struct dcesrv_call_state *dce_call,
+				      TALLOC_CTX *mem_ctx,
+				      struct EcDoRpc *r)
+{
+	struct dcesrv_handle		*h;
+	struct emsmdbp_context		*emsmdbp_ctx;
+	struct mapi_request		*mapi_request;
+	struct mapi_response		*mapi_response;
+	enum MAPISTATUS			retval;
+	uint32_t			handles_length;
+	uint16_t			size = 0;
+	uint32_t			i;
+
+	DEBUG(3, ("exchange_emsmdb: EcDoRpc (0x2)\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);
+	emsmdbp_ctx = (struct emsmdbp_context *) h->data;
+
+	mapi_request = r->in.mapi_request;
+	mapi_response = talloc_zero(mem_ctx, struct mapi_response);
+	mapi_response->handles = mapi_request->handles;
+
+	/* Step 1. FIXME: Idle requests */
+	if (mapi_request->mapi_len <= 2) {
+		return MAPI_E_SUCCESS;
+	}
+
+	/* Step 2. Process serialized MAPI requests */
+	mapi_response->mapi_repl = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REPL);
+	for (i = 0; mapi_request->mapi_req[i].opnum != 0; i++) {
+		DEBUG(0, ("MAPI Rop: 0x%.2x\n", mapi_request->mapi_req[i].opnum));
+		mapi_response->mapi_repl = talloc_realloc(mem_ctx, mapi_response->mapi_repl,
+							  struct EcDoRpc_MAPI_REPL, i + 2);
+		switch (mapi_request->mapi_req[i].opnum) {
+		case op_MAPI_Release:
+			retval = EcDoRpc_RopRelease(mem_ctx, emsmdbp_ctx, 
+						    &(mapi_request->mapi_req[i]),
+						    mapi_request->handles, &size);
+			break;
+		case op_MAPI_OpenFolder:
+			retval = EcDoRpc_RopOpenFolder(mem_ctx, emsmdbp_ctx,
+						       &(mapi_request->mapi_req[i]),
+						       &(mapi_response->mapi_repl[i]),
+						       mapi_response->handles, &size);
+			break;
+		case op_MAPI_GetProps:
+			retval = EcDoRpc_RopGetPropertiesSpecific(mem_ctx, emsmdbp_ctx,
+								  &(mapi_request->mapi_req[i]),
+								  &(mapi_response->mapi_repl[i]),
+								  mapi_response->handles, &size);
+			break;
+		case op_MAPI_GetReceiveFolder:
+			retval = EcDoRpc_RopGetReceiveFolder(mem_ctx, emsmdbp_ctx,
+							     &(mapi_request->mapi_req[i]),
+							     &(mapi_response->mapi_repl[i]),
+							     mapi_response->handles, &size);
+			break;
+		case op_MAPI_RegisterNotification:
+			retval = EcDoRpc_RopRegisterNotification(mem_ctx, emsmdbp_ctx,
+								 &(mapi_request->mapi_req[i]),
+								 &(mapi_response->mapi_repl[i]),
+								 mapi_response->handles, &size);
+			break;
+		case op_MAPI_Logon:
+			retval = EcDoRpc_RopLogon(mem_ctx, emsmdbp_ctx,
+						  &(mapi_request->mapi_req[i]),
+						  &(mapi_response->mapi_repl[i]),
+						  mapi_response->handles, &size);
+			break;
+		default:
+			DEBUG(1, ("MAPI Rop: 0x%.2x not implemented!\n",
+				  mapi_request->mapi_req[i].opnum));
+		}
+	}
+
+	/* Step 3. Notifications/Pending calls should be processed here */
+	mapi_response->mapi_repl[i].opnum = 0;
+
+	/* Step 4. Fill mapi_response structure */
+	handles_length = mapi_request->mapi_len - mapi_request->length;
+	mapi_response->length = size + sizeof (mapi_response->length);
+	mapi_response->mapi_len = mapi_response->length + handles_length;
+
+	/* Step 5. Fill EcDoRpc reply */
+	r->out.handle = r->in.handle;
+	r->out.size = r->in.size;
+	r->out.offset = r->in.offset;
+	r->out.mapi_response = mapi_response;
+	r->out.length = talloc_zero(mem_ctx, uint16_t);
+	*r->out.length = mapi_response->mapi_len;
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_emsmdb EcGetMoreRpc (0x3) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcGetMoreRpc request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static void dcesrv_EcGetMoreRpc(struct dcesrv_call_state *dce_call,
+				TALLOC_CTX *mem_ctx,
+				struct EcGetMoreRpc *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcGetMoreRpc (0x3) not implemented\n"));
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcRRegisterPushNotification (0x4) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcRRegisterPushNotification request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcRRegisterPushNotification(struct dcesrv_call_state *dce_call,
+							  TALLOC_CTX *mem_ctx,
+							  struct EcRRegisterPushNotification *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcRRegisterPushNotification (0x4) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcRUnregisterPushNotification (0x5) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcRUnregisterPushNotification request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcRUnregisterPushNotification(struct dcesrv_call_state *dce_call,
+							    TALLOC_CTX *mem_ctx,
+							    struct EcRUnregisterPushNotification *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcRUnregisterPushNotification (0x5) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcDummyRpc (0x6) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDummyRpc request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static void dcesrv_EcDummyRpc(struct dcesrv_call_state *dce_call,
+			      TALLOC_CTX *mem_ctx,
+			      struct EcDummyRpc *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcDummyRpc (0x6) not implemented\n"));
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcRGetDCName (0x7) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcRGetDCName request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static void dcesrv_EcRGetDCName(struct dcesrv_call_state *dce_call,
+				TALLOC_CTX *mem_ctx,
+				struct EcRGetDCName *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcRGetDCName (0x7) not implemented\n"));
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcRNetGetDCName (0x8) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcRNetGetDCName request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static void dcesrv_EcRNetGetDCName(struct dcesrv_call_state *dce_call,
+				   TALLOC_CTX *mem_ctx,
+				   struct EcRNetGetDCName *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcRNetGetDCName (0x8) not implemented\n"));
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcDoRpcExt (0x9) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDoRpcExt request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static void dcesrv_EcDoRpcExt(struct dcesrv_call_state *dce_call,
+			      TALLOC_CTX *mem_ctx,
+			      struct EcDoRpcExt *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcDoRpcExt (0x9) not implemented\n"));
+	DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_emsmdb EcDoConnectEx (0xA) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the EcDoConnectEx request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_EcDoConnectEx(struct dcesrv_call_state *dce_call,
+					    TALLOC_CTX *mem_ctx,
+					    struct EcDoConnectEx *r)
+{
+	DEBUG(3, ("exchange_emsmdb: EcDoConnectEx (0xA) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details Dispatch incoming EMSMDB call to the correct OpenChange
+   server function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r generic pointer on EMSMDB data
+   \param mapiproxy pointer to the mapiproxy structure controlling
+   mapiproxy behavior
+
+   \return NT_STATUS_OK;
+ */
+static NTSTATUS dcesrv_exchange_emsmdb_dispatch(struct dcesrv_call_state *dce_call,
+						TALLOC_CTX *mem_ctx,
+						void *r, struct mapiproxy *mapiproxy)
+{
+	enum MAPISTATUS				retval;
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	/* Sanity checks */
+	if (!table) return NT_STATUS_UNSUCCESSFUL;
+	if (table->name && strcmp(table->name, NDR_EXCHANGE_EMSMDB_NAME)) return NT_STATUS_UNSUCCESSFUL;
+
+	switch (opnum) {
+	case NDR_ECDOCONNECT:
+		retval = dcesrv_EcDoConnect(dce_call, mem_ctx, (struct EcDoConnect *)r);
+		break;
+	case NDR_ECDODISCONNECT:
+		retval = dcesrv_EcDoDisconnect(dce_call, mem_ctx, (struct EcDoDisconnect *)r);
+		break;
+	case NDR_ECDORPC:
+		retval = dcesrv_EcDoRpc(dce_call, mem_ctx, (struct EcDoRpc *)r);
+		break;
+	case NDR_ECGETMORERPC:
+		dcesrv_EcGetMoreRpc(dce_call, mem_ctx, (struct EcGetMoreRpc *)r);
+		break;
+	case NDR_ECRREGISTERPUSHNOTIFICATION:
+		retval = dcesrv_EcRRegisterPushNotification(dce_call, mem_ctx, (struct EcRRegisterPushNotification *)r);
+		break;
+	case NDR_ECRUNREGISTERPUSHNOTIFICATION:
+		retval = dcesrv_EcRUnregisterPushNotification(dce_call, mem_ctx, (struct EcRUnregisterPushNotification *)r);
+		break;
+	case NDR_ECDUMMYRPC:
+		dcesrv_EcDummyRpc(dce_call, mem_ctx, (struct EcDummyRpc *)r);
+		break;
+	case NDR_ECRGETDCNAME:
+		dcesrv_EcRGetDCName(dce_call, mem_ctx, (struct EcRGetDCName *)r);
+		break;
+	case NDR_ECRNETGETDCNAME:
+		dcesrv_EcRNetGetDCName(dce_call, mem_ctx, (struct EcRNetGetDCName *)r);
+		break;
+	case NDR_ECDORPCEXT:
+		dcesrv_EcDoRpcExt(dce_call, mem_ctx, (struct EcDoRpcExt *)r);
+		break;
+	case NDR_ECDOCONNECTEX:
+		retval = dcesrv_EcDoConnectEx(dce_call, mem_ctx, (struct EcDoConnectEx *)r);
+		return NT_STATUS_NET_WRITE_FAULT;
+		break;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize the EMSMDB OpenChange server
+
+   \param dce_ctx pointer to the server context
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS dcesrv_exchange_emsmdb_init(struct dcesrv_context *dce_ctx)
+{
+	/* Initialize exchange_emsmdb session */
+	emsmdb_session = talloc_zero(dce_ctx, struct exchange_emsmdb_session);
+	if (!emsmdb_session) return NT_STATUS_NO_MEMORY;
+	emsmdb_session->session = NULL;
+
+	/* Open read/write context on OpenChange dispatcher database */
+	openchange_ldb_ctx = emsmdbp_openchange_ldb_init(dce_ctx->lp_ctx);
+	if (!openchange_ldb_ctx) {
+		smb_panic("unable to initialize 'openchange.ldb' context");
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Terminate the EMSMDB connection and release the associated
+   session and context if still available. This case occurs when the
+   client doesn't call EcDoDisconnect but quit unexpectedly.
+
+   \param server_id reference to the server identifier structure
+   \param context_id the connection context identifier
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS dcesrv_exchange_emsmdb_unbind(struct server_id server_id, uint32_t context_id)
+{
+	struct exchange_emsmdb_session	*session;
+
+	for (session = emsmdb_session; session; session = session->next) {
+		if ((mpm_session_cmp_sub(session->session, server_id, context_id) == true)) {
+			mpm_session_release(session->session);
+			DLIST_REMOVE(emsmdb_session, session);
+			DEBUG(6, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__));
+			return NT_STATUS_OK;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Entry point for the default OpenChange EMSMDB server
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	server;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	server.name = "exchange_emsmdb";
+	server.status = MAPIPROXY_DEFAULT;
+	server.description = "OpenChange EMSMDB server";
+	server.endpoint = "exchange_emsmdb";
+
+	/* Fill in all the operations */
+	server.init = dcesrv_exchange_emsmdb_init;
+	server.unbind = dcesrv_exchange_emsmdb_unbind;
+	server.dispatch = dcesrv_exchange_emsmdb_dispatch;
+	server.push = NULL;
+	server.pull = NULL;
+	server.ndr_pull = NULL;
+
+	/* Register ourselves with the MAPIPROXY server subsystem */
+	ret = mapiproxy_server_register(&server);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'exchange_emsmdb' default mapiproxy server!\n"));
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/dcesrv_exchange_emsmdb.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,148 @@
+/*
+   MAPI Proxy - Exchange EMSMDB Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__DCESRV_EXCHANGE_EMSMDB_H
+#define	__DCESRV_EXCHANGE_EMSMDB_H
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <mapiproxy/libmapiproxy/libmapiproxy.h>
+#include <mapiproxy/libmapistore/mapistore.h>
+#include <ldb.h>
+#include <ldb_errors.h>
+#include <util/debug.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 emsmdbp_context {
+	char				*szUserDN;
+	char				*szDisplayName;
+	struct loadparm_context		*lp_ctx;
+	void				*oc_ctx;
+	void				*conf_ctx;
+	void				*users_ctx;
+	struct mapistore_context	*mstore_ctx;
+	struct mapi_handles_context	*handles_ctx;
+};
+
+
+struct exchange_emsmdb_session {
+	uint32_t			pullTimeStamp;
+	struct mpm_session		*session;
+	struct exchange_emsmdb_session	*prev;
+	struct exchange_emsmdb_session	*next;
+};
+
+enum emsmdbp_object_type {
+	EMSMDBP_OBJECT_UNDEF		= 0x0,
+	EMSMDBP_OBJECT_MAILBOX		= 0x1,
+	EMSMDBP_OBJECT_FOLDER		= 0x2,
+	EMSMDBP_OBJECT_MESSAGE		= 0x3,
+	EMSMDBP_OBJECT_TABLE		= 0x4
+};
+
+struct emsmdbp_object_mailbox {
+	char				*owner_Name;
+	char				*owner_EssDN;
+	char				*szUserDN;
+};
+
+
+struct emsmdbp_object_folder {
+	uint64_t			folderID;
+	bool				IsSystemFolder;
+	int				systemfolder;
+	uint32_t			contextID;
+};
+
+union emsmdbp_objects {
+	struct emsmdbp_object_mailbox	*mailbox;
+	struct emsmdbp_object_folder	*folder;
+};
+
+struct emsmdbp_object {
+	enum emsmdbp_object_type	type;
+	union emsmdbp_objects		object;
+	struct mapistore_context	*mstore_ctx;
+	void				*private_data;
+};
+
+
+#define	EMSMDB_PCMSPOLLMAX		60000
+#define	EMSMDB_PCRETRY			6
+#define	EMSMDB_PCRETRYDELAY		10000
+
+#define	EMSMDBP_MAILBOX_ROOT		0x1
+#define	EMSMDBP_DEFERRED_ACTIONS	0x2
+#define	EMSMDBP_SPOOLER_QUEUE		0x3
+#define	EMSMDBP_TOP_INFORMATION_STORE	0x4
+#define	EMSMDBP_INBOX			0x5
+#define	EMSMDBP_OUTBOX			0x6
+#define	EMSMDBP_SENT_ITEMS		0x7
+#define	EMSMDBP_DELETED_ITEMS		0x8
+#define	EMSMDBP_COMMON_VIEWS		0x9
+#define	EMSMDBP_SCHEDULE		0xA
+#define	EMSMDBP_SEARCH			0xB
+#define	EMSMDBP_VIEWS			0xC
+#define	EMSMDBP_SHORTCUTS		0xD
+
+__BEGIN_DECLS
+
+NTSTATUS	samba_init_module(void);
+
+/* definitions from emsmdbp.c */
+struct emsmdbp_context	*emsmdbp_init(struct loadparm_context *, void *);
+void			*emsmdbp_openchange_ldb_init(struct loadparm_context *);
+bool			emsmdbp_destructor(void *);
+bool			emsmdbp_verify_user(struct dcesrv_call_state *, struct emsmdbp_context *);
+bool			emsmdbp_verify_userdn(struct dcesrv_call_state *, struct emsmdbp_context *, const char *, struct ldb_message **);
+
+/* definitions from emsmdbp_object.c */
+struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *, struct emsmdbp_context *);
+struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *);
+struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct mapi_handles *);
+
+/* definitions from oxcfold.c */
+enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
+/* definitions from oxcnotif.c */
+enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
+/* definitions from oxcprpt.c */
+enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
+/* definitions from oxcstor.c */
+enum MAPISTATUS	EcDoRpc_RopLogon(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+enum MAPISTATUS	EcDoRpc_RopRelease(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, uint32_t *, uint16_t *);
+enum MAPISTATUS	EcDoRpc_RopGetReceiveFolder(TALLOC_CTX *, struct emsmdbp_context *, struct EcDoRpc_MAPI_REQ *, struct EcDoRpc_MAPI_REPL *, uint32_t *, uint16_t *);
+
+__END_DECLS
+
+#endif	/* __DCESRV_EXCHANGE_EMSMDB_H */

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,293 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file emsmdbp.c
+
+   \brief EMSMDB Provider implementation
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+/**
+   \details Release the MAPISTORE context used by EMSMDB provider
+   context
+
+   \param data pointer on data to destroy
+
+   \return 0 on success, otherwise -1
+ */
+static int emsmdbp_mapi_store_destructor(void *data)
+{
+	struct mapistore_context *mstore_ctx = (struct mapistore_context *) data;
+
+	mapistore_release(mstore_ctx);
+	DEBUG(6, ("[%s:%d]: MAPISTORE context released\n", __FUNCTION__, __LINE__));
+	return true;
+}
+
+/**
+   \details Release the MAPI handles context used by EMSMDB provider
+   context
+
+   \param data pointer on data to destroy
+
+   \return 0 on success, otherwise -1
+ */
+static int emsmdbp_mapi_handles_destructor(void *data)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles_context	*handles_ctx = (struct mapi_handles_context *) data;
+
+	retval = mapi_handles_release(handles_ctx);
+	DEBUG(6, ("[%s:%d]: MAPI handles context released (%s)\n", __FUNCTION__, __LINE__,
+		  mapi_get_errstr(retval)));
+
+	return (retval == MAPI_E_SUCCESS) ? 0 : -1;
+}
+
+/**
+   \details Initialize the EMSMDBP context and open connections to
+   Samba databases.
+
+   \param lp_ctx pointer to the loadparm_context
+   \param ldb_ctx pointer to the openchange dispatcher ldb database
+   
+   \return Allocated emsmdbp_context pointer on success, otherwise
+   NULL
+ */
+_PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx,
+					      void *ldb_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);
+	if (!emsmdbp_ctx) {
+		return NULL;
+	}
+
+	ev = tevent_context_init(talloc_autofree_context());
+	if (!ev) {
+		talloc_free(emsmdbp_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 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);
+	if (!emsmdbp_ctx->mstore_ctx) {
+		DEBUG(0, ("[%s:%d]: MAPISTORE initialization failed\n", __FUNCTION__, __LINE__));
+
+		talloc_free(emsmdbp_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);
+	if (!emsmdbp_ctx->handles_ctx) {
+		DEBUG(0, ("[%s:%d]: MAPI handles context initialization failed\n", __FUNCTION__, __LINE__));
+		talloc_free(emsmdbp_ctx);
+		return NULL;
+	}
+	talloc_set_destructor((void *)emsmdbp_ctx->handles_ctx, (int (*)(void *))emsmdbp_mapi_handles_destructor);
+
+	return emsmdbp_ctx;
+}
+
+
+/**
+   \details Open openchange.ldb database
+
+   \param lp_ctx pointer on the loadparm_context
+
+   \note This function is just a wrapper over
+   mapiproxy_server_openchange_ldb_init
+
+   \return Allocated LDB context on success, otherwise NULL
+ */
+_PUBLIC_ void *emsmdbp_openchange_ldb_init(struct loadparm_context *lp_ctx)
+{
+	/* Sanity checks */
+	if (!lp_ctx) return NULL;
+
+	return mapiproxy_server_openchange_ldb_init(lp_ctx);
+}
+
+
+_PUBLIC_ bool emsmdbp_destructor(void *data)
+{
+	struct emsmdbp_context	*emsmdbp_ctx = (struct emsmdbp_context *)data;
+
+	if (!emsmdbp_ctx) return false;
+
+	talloc_free(emsmdbp_ctx);
+	DEBUG(0, ("[%s:%d]: emsmdbp_ctx found and released\n", __FUNCTION__, __LINE__));
+
+	return true;
+}
+
+
+/**
+   \details Check if the authenticated user belongs to the Exchange
+   organization and is enabled
+
+   \param dce_call pointer to the session context
+   \param emsmdbp_ctx pointer to the EMSMDBP context
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool emsmdbp_verify_user(struct dcesrv_call_state *dce_call,
+				  struct emsmdbp_context *emsmdbp_ctx)
+{
+	int			ret;
+	const char		*username = NULL;
+	int			msExchUserAccountControl;
+	struct ldb_result	*res = NULL;
+	char			*ldb_filter;
+	const char * const	recipient_attrs[] = { "msExchUserAccountControl", NULL };
+
+	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
+
+	ldb_filter = talloc_asprintf(emsmdbp_ctx, "CN=%s", username);
+	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	/* If the search failed */
+	if (ret != LDB_SUCCESS || !res->count) {
+		return false;
+	}
+
+	/* 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;
+}
+
+
+/**
+   \details Check if the user record which legacyExchangeDN points to
+   belongs to the Exchange organization and is enabled
+
+   \param dce_call pointer to the session context
+   \param emsmdbp_ctx pointer to the EMSMDBP context
+   \param legacyExchangeDN pointer to the userDN to lookup
+   \param msg pointer on pointer to the LDB message matching the record
+
+   \note Users can set msg to NULL if they do not intend to retrieve
+   the message
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool emsmdbp_verify_userdn(struct dcesrv_call_state *dce_call,
+				    struct emsmdbp_context *emsmdbp_ctx,
+				    const char *legacyExchangeDN,
+				    struct ldb_message **msg)
+{
+	int			ret;
+	int			msExchUserAccountControl;
+	struct ldb_result	*res = NULL;
+	char			*ldb_filter;
+	const char * const	recipient_attrs[] = { "*", NULL };
+
+	/* Sanity Checks */
+	if (!legacyExchangeDN) return false;
+
+	ldb_filter = talloc_asprintf(emsmdbp_ctx, "(legacyExchangeDN=%s)", legacyExchangeDN);
+	ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	/* If the search failed */
+	if (ret != LDB_SUCCESS || !res->count) {
+		return false;
+	}
+
+	/* Checks msExchUserAccountControl value */
+	msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2);
+	if (msExchUserAccountControl == 2) {
+		return false;
+	}
+
+	if (msg) {
+		*msg = res->msgs[0];
+	}
+
+	return true;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/emsmdbp_object.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,236 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file emsmdbp_object.c
+
+   \brief Server-side specific objects init/release routines
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+static const char *emsmdbp_getstr_type(struct emsmdbp_object *object)
+{
+	switch (object->type) {
+	case EMSMDBP_OBJECT_UNDEF:
+		return "undefined";
+	case EMSMDBP_OBJECT_MAILBOX:
+		return "mailbox";
+	case EMSMDBP_OBJECT_FOLDER:
+		return "folder";
+	case EMSMDBP_OBJECT_MESSAGE:
+		return "message";
+	case EMSMDBP_OBJECT_TABLE:
+		return "table";
+	default:
+		return "unknown";
+	}
+
+	return "unknown";
+}
+
+
+/**
+   \details talloc destructor fo emsmdbp_objects
+
+   \param data generic pointer on data
+
+   \return 0 on success, otherwise -1
+ */
+static int emsmdbp_object_destructor(void *data)
+{
+	struct emsmdbp_object	*object = (struct emsmdbp_object *) data;
+	int			ret;
+
+	if (!data) return -1;
+	
+	DEBUG(4, ("[%s:%d]: emsmdbp %s object released\n", __FUNCTION__, __LINE__,
+		  emsmdbp_getstr_type(object)));
+
+	switch (object->type) {
+	case EMSMDBP_OBJECT_FOLDER:
+		ret = mapistore_del_context(object->mstore_ctx, object->object.folder->contextID);
+		DEBUG(4, ("[%s:%d] mapistore folder context retval = %d\n", __FUNCTION__, __LINE__, ret));
+		break;
+	default:
+		break;
+	}
+
+	talloc_free(object);
+
+	return 0;
+}
+
+/**
+   \details Initialize an emsmdbp_object
+
+   \param mem_ctx pointer to the memory context
+
+   \return Allocated emsmdbp object on success, otherwise NULL
+ */
+_PUBLIC_ struct emsmdbp_object *emsmdbp_object_init(TALLOC_CTX *mem_ctx, struct emsmdbp_context *emsmdbp_ctx)
+{
+	struct emsmdbp_object	*object = NULL;
+
+	object = talloc_zero(mem_ctx, struct emsmdbp_object);
+	if (!object) return NULL;
+
+	talloc_set_destructor((void *)object, (int (*)(void *))emsmdbp_object_destructor);
+
+	object->type = EMSMDBP_OBJECT_UNDEF;
+	object->mstore_ctx = emsmdbp_ctx->mstore_ctx;
+	object->object.mailbox = NULL;
+	object->object.folder = NULL;
+	object->private_data = NULL;
+
+	return object;
+}
+
+
+/**
+   \details Initialize a mailbox object
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request pointer to the Logon MAPI request
+
+   \return Allocated emsmdbp object on success, otherwise NULL
+ */
+_PUBLIC_ struct emsmdbp_object *emsmdbp_object_mailbox_init(TALLOC_CTX *mem_ctx,
+							    struct emsmdbp_context *emsmdbp_ctx,
+							    struct EcDoRpc_MAPI_REQ *request)
+{
+	struct emsmdbp_object		*object;
+	const char			*displayName;
+	char				*ldb_filter;
+	const char * const		recipient_attrs[] = { "*", NULL };
+	int				ret;
+	struct ldb_result		*res = NULL;
+
+	/* Sanity checks */
+	if (!emsmdbp_ctx) return NULL;
+	if (!request) return NULL;
+
+	object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx);
+	if (!object) return NULL;
+
+	/* Initialize the mailbox object */
+	object->object.mailbox = talloc_zero(object, struct emsmdbp_object_mailbox);
+	if (!object->object.mailbox) {
+		talloc_free(object);
+		return NULL;
+	}
+
+	object->type = EMSMDBP_OBJECT_MAILBOX;
+	object->object.mailbox->owner_Name = NULL;
+	object->object.mailbox->owner_EssDN = NULL;
+	object->object.mailbox->szUserDN = NULL;
+
+	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);
+
+	ldb_filter = talloc_asprintf(mem_ctx, "(legacyExchangeDN=%s)", object->object.mailbox->owner_EssDN);
+	ret = ldb_search(emsmdbp_ctx->users_ctx, mem_ctx, &res,
+			 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
+			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	if (res->count == 1) {
+		displayName = ldb_msg_find_attr_as_string(res->msgs[0], "displayName", NULL);
+		if (displayName) {
+			object->object.mailbox->owner_Name = talloc_strdup(object->object.mailbox, displayName);
+		}
+	}
+
+	talloc_free(res);
+
+	return object;
+}
+
+
+/**
+   \details Initialize a folder object
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request pointer to the OpenFolder MAPI request
+   \param parent pointer to the parent MAPI handle
+
+   \return Allocated emsmdbp object on success, otherwise NULL
+ */
+_PUBLIC_ struct emsmdbp_object *emsmdbp_object_folder_init(TALLOC_CTX *mem_ctx,
+							   struct emsmdbp_context *emsmdbp_ctx,
+							   struct EcDoRpc_MAPI_REQ *request,
+							   struct mapi_handles *parent)
+{
+	enum MAPISTATUS			retval;
+	struct emsmdbp_object		*object;
+	int				mailboxfolder;
+	char				*mapistore_uri = NULL;
+	uint32_t			context_id;
+	int				ret;
+
+	/* Sanity checks */
+	if (!emsmdbp_ctx) return NULL;
+	if (!request) return NULL;
+
+	object = emsmdbp_object_init(mem_ctx, emsmdbp_ctx);
+	if (!object) return NULL;
+
+	object->object.folder = talloc_zero(object, struct emsmdbp_object_folder);
+	if (!object->object.folder) {
+		talloc_free(object);
+		return NULL;
+	}
+
+	object->type = EMSMDBP_OBJECT_FOLDER;
+	object->object.folder->contextID = -1;
+	object->object.folder->folderID = request->u.mapi_OpenFolder.folder_id;
+	
+	retval = mapi_handles_get_systemfolder(parent, &mailboxfolder);
+	object->object.folder->IsSystemFolder = (!mailboxfolder) ? true : false;
+
+	if (object->object.folder->IsSystemFolder == false) {
+		/* Retrieve the systemfolder value */
+		object->object.folder->systemfolder = -1;
+		/* assign mapistore context from parent */
+	} else {
+		object->object.folder->systemfolder = 1;
+		/* mapistore backend initialization goes here */
+		retval = openchangedb_get_mapistoreURI(mem_ctx, emsmdbp_ctx->oc_ctx,
+						       object->object.folder->folderID, &mapistore_uri);
+		if (retval == MAPI_E_SUCCESS) {
+			ret = mapistore_add_context(emsmdbp_ctx->mstore_ctx, mapistore_uri, &context_id);
+			if (ret != MAPISTORE_SUCCESS) {
+				talloc_free(object);
+				return NULL;
+			}
+			object->object.folder->contextID = context_id;
+		} else {
+			talloc_free(object);
+			return NULL;
+		}
+	}
+
+	return object;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcfold.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,136 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file oxcfold.c
+
+   \brief Folder object routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+
+/**
+   \details Open a System or Special folder object.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request OpenFolder request
+   \param response pointer to the OpenFolder response
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopOpenFolder_SystemSpecialFolder(TALLOC_CTX *mem_ctx, 
+							 struct emsmdbp_context *emsmdbp_ctx,
+							 struct OpenFolder_req request,
+							 struct OpenFolder_repl *response)
+{
+	/* Find parent record */
+	/* Set parent record as basedn */
+	/* Look for systemfolder given its FolderID */
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+   \details EcDoRpc OpenFolder (0x02) Rop. This operation opens an
+   existing folder.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the OpenFolder EcDoRpc_MAPI_REQ
+   structure
+   \param mapi_repl pointer to the OpenFolder EcDoRpc_MAPI_REPL
+   structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopOpenFolder(TALLOC_CTX *mem_ctx,
+					       struct emsmdbp_context *emsmdbp_ctx,
+					       struct EcDoRpc_MAPI_REQ *mapi_req,
+					       struct EcDoRpc_MAPI_REPL *mapi_repl,
+					       uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct OpenFolder_req		request;
+	struct OpenFolder_repl		response;
+	struct mapi_handles		*parent = NULL;
+	struct mapi_handles		*rec = NULL;
+	struct emsmdbp_object		*object;
+	uint32_t			handle;
+	int				parentfolder = -1;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCFOLD] OpenFolder (0x02)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	request = mapi_req->u.mapi_OpenFolder;
+	response = mapi_repl->u.mapi_OpenFolder;
+
+	mapi_repl->u.mapi_OpenFolder.HasRules = 0;
+	mapi_repl->u.mapi_OpenFolder.IsGhosted = 0;
+
+	/* Step 1. Retrieve parent handle in the hierarchy */
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	retval = mapi_handles_get_systemfolder(parent, &parentfolder);
+
+	switch (parentfolder) {
+	case 0x0:
+		/* system/special folder */
+		retval = RopOpenFolder_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, request, &response);
+		mapi_repl->error_code = retval;
+		break;
+	default:
+		/* handled by mapistore */
+		break;
+	}
+
+	*size += libmapiserver_RopOpenFolder_size(mapi_repl);
+
+	/* Fill EcDoRpc_MAPI_REPL reply */
+	if (!mapi_repl->error_code) {
+		retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+
+		object = emsmdbp_object_folder_init((TALLOC_CTX *)rec, emsmdbp_ctx, mapi_req, parent);
+		retval = mapi_handles_set_systemfolder(rec, object->object.folder->systemfolder);
+		retval = mapi_handles_set_private_data(rec, object);
+
+		mapi_repl->opnum = mapi_req->opnum;
+		mapi_repl->handle_idx = mapi_req->u.mapi_OpenFolder.handle_idx;
+
+		handles[mapi_repl->handle_idx] = rec->handle;
+	}
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcnotif.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,81 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file oxcnotif.c
+
+   \brief Core Notifications routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+
+/**
+   \details EcDoRpc RegisterNotification (0x29) Rop. This operation
+   subscribes for specified notifications on the server and returns a
+   handle of the subscription to the client.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the RegisterNotification
+   EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the RegisterNotification
+   EcDoRpc_MAPI_REPL structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRegisterNotification(TALLOC_CTX *mem_ctx,
+							 struct emsmdbp_context *emsmdbp_ctx,
+							 struct EcDoRpc_MAPI_REQ *mapi_req,
+							 struct EcDoRpc_MAPI_REPL *mapi_repl,
+							 uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_handles	*rec = NULL;
+	uint32_t		handle;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCNOTIF] RegisterNotification (0x29)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* FIXME: Handle this call properly */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->u.mapi_RegisterNotification.handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
+	handles[mapi_repl->handle_idx] = rec->handle;
+
+	*size += libmapiserver_RopRegisterNotification_size();
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,257 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file oxcprpt.c
+
+   \brief Property and Stream Object routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+
+/**
+   \details Retrieve properties on a mailbox object.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request GetProps request
+   \param response pointer to the GetProps reply
+   \param private_data pointer to the private data stored for this
+   object
+
+   \note Mailbox objects have a limited set of supported properties.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopGetPropertiesSpecific_Mailbox(TALLOC_CTX *mem_ctx,
+							struct emsmdbp_context *emsmdbp_ctx,
+							struct GetProps_req request,
+							struct GetProps_repl *response,
+							void *private_data)
+{
+	enum MAPISTATUS			retval;
+	struct emsmdbp_object		*object;
+	struct SBinary_short		bin;
+	uint32_t			i;
+	uint32_t			error = 0;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
+
+	object = (struct emsmdbp_object *) private_data;
+
+	/* Step 1. Check if we need a layout */
+	response->layout = 0;
+	for (i = 0; i < request.prop_count; i++) {
+		switch (request.properties[i]) {
+		case PR_MAPPING_SIGNATURE:
+		case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
+			response->layout = 0x1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Step 2. Fill the GetProps blob */
+	for (i = 0; i < request.prop_count; i++) {
+		switch (request.properties[i]) {
+		case PR_MAPPING_SIGNATURE:
+		case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
+			error = MAPI_E_NO_ACCESS;
+			request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    request.properties[i], (const void *)&error, 
+						    &response->prop_data, response->layout);
+			break;
+		case PR_USER_ENTRYID:
+			retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->szUserDN, &bin);
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    request.properties[i], (const void *)&bin,
+						    &response->prop_data, response->layout);
+			talloc_free(bin.lpb);
+			break;
+		case PR_MAILBOX_OWNER_ENTRYID:
+			retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->owner_EssDN, &bin);
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    request.properties[i], (const void *)&bin,
+						    &response->prop_data, response->layout);
+			talloc_free(bin.lpb);
+			break;
+		case PR_MAILBOX_OWNER_NAME:
+		case PR_MAILBOX_OWNER_NAME_UNICODE:
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    request.properties[i], (const void *)object->object.mailbox->owner_Name,
+						    &response->prop_data, response->layout);
+			break;
+		default:
+			error = MAPI_E_NOT_FOUND;
+			request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+			libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+						    request.properties[i], (const void *)&error, 
+						    &response->prop_data, response->layout);
+			break;
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve properties on a systemfolder object.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request GetProps request
+   \param response pointer to the private data stored for this
+   object
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopGetPropertiesSpecific_SystemSpecialFolder(TALLOC_CTX *mem_ctx,
+								    struct emsmdbp_context *emsmdbp_ctx,
+								    struct GetProps_req request,
+								    struct GetProps_repl *response,
+								    void *private_data)
+{
+	enum MAPISTATUS			retval;
+	struct emsmdbp_object		*object;
+	struct emsmdbp_object_folder	*folder;
+	void				*data;
+	int				i;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
+
+	object = (struct emsmdbp_object *) private_data;
+	folder = (struct emsmdbp_object_folder *) object->object.folder;
+
+	/* Step 1. Lookup properties and set layout */
+	response->layout = 0x0;
+	for (i = 0; i < request.prop_count; i++) {
+		if (openchangedb_lookup_folder_property(emsmdbp_ctx->oc_ctx, request.properties[i], 
+							folder->folderID)) {
+			response->layout = 0x1;
+			break;
+		}
+	}
+
+	/* Step 2. Fetch properties values */
+	for (i = 0; i < request.prop_count; i++) {
+		retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx, 
+							  emsmdbp_ctx->szDisplayName, request.properties[i],
+							  folder->folderID, (void **)&data);
+		if (retval) {
+			request.properties[i] = (request.properties[i] & 0xFFFF0000) + PT_ERROR;
+			data = (void *)&retval;
+		}
+		libmapiserver_push_property(mem_ctx, lp_iconv_convenience(emsmdbp_ctx->lp_ctx),
+					    request.properties[i], (const void *)data,
+					    &response->prop_data, response->layout);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc GetPropertiesSpecific (0x07) Rop. This operation
+   retrieves from properties data from specified object.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetPropertiesSpecific
+   EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the GetPropertiesSpecific
+   EcDoRpc_MAPI_REPL structure
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesSpecific(TALLOC_CTX *mem_ctx,
+							  struct emsmdbp_context *emsmdbp_ctx,
+							  struct EcDoRpc_MAPI_REQ *mapi_req,
+							  struct EcDoRpc_MAPI_REPL *mapi_repl,
+							  uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	struct GetProps_req	request;
+	struct GetProps_repl	response;
+	uint32_t		handle;
+	struct mapi_handles	*rec = NULL;
+	int			systemfolder = -1;
+	void			*private_data = NULL;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesSpecific (0x07)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	request = mapi_req->u.mapi_GetProps;
+	response = mapi_repl->u.mapi_GetProps;
+
+	/* Initialize GetProps response blob */
+	response.prop_data.length = 0;
+	response.prop_data.data = NULL;
+
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	retval = mapi_handles_get_systemfolder(rec, &systemfolder);
+	retval = mapi_handles_get_private_data(rec, &private_data);
+
+	DEBUG(0, ("GetProps: SystemFolder = %d\n", systemfolder));
+
+	switch (systemfolder) {
+	case -1:
+		/* handled by mapistore */
+		break;
+	case 0x0:
+		/* private mailbox */
+		retval = RopGetPropertiesSpecific_Mailbox(mem_ctx, emsmdbp_ctx, request, &response, private_data);
+		break;
+	case 0x1:
+		/* system or special folder */
+		retval = RopGetPropertiesSpecific_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, request, &response, private_data);
+		break;
+	}
+
+	/* Fill EcDoRpc_MAPI_REPL reply */
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = MAPI_E_SUCCESS;
+	mapi_repl->u.mapi_GetProps = response;
+
+	*size += libmapiserver_RopGetPropertiesSpecific_size(mapi_req, mapi_repl);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/emsmdb/oxcstor.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,333 @@
+/*
+   OpenChange Server implementation
+
+   EMSMDBP: EMSMDB Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file ocxstor.c
+
+   \brief Server-side store objects routines and Rops
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "mapiproxy/libmapiproxy/libmapiproxy.h"
+#include "mapiproxy/libmapiserver/libmapiserver.h"
+#include "dcesrv_exchange_emsmdb.h"
+
+#include <string.h>
+
+
+/**
+   \details Logs on a private mailbox
+
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the RopLogon EcDoRpc_MAPI_REQ structure
+   \param mapi_repl pointer to the RopLogon EcDoRpc_MAPI_REPL
+   structure the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopLogon_Mailbox(TALLOC_CTX *mem_ctx,
+					struct emsmdbp_context *emsmdbp_ctx,
+					struct EcDoRpc_MAPI_REQ *mapi_req,
+					struct EcDoRpc_MAPI_REPL *mapi_repl)
+{
+	enum MAPISTATUS		retval;
+	char			*recipient;
+	struct Logon_req	request;
+	struct Logon_repl	response;
+	struct tm		*LogonTime;
+	time_t			t;
+	NTTIME			nttime;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!mapi_req->u.mapi_Logon.EssDN, MAPI_E_INVALID_PARAMETER, NULL);
+
+	request = mapi_req->u.mapi_Logon;
+	response = mapi_repl->u.mapi_Logon;
+
+	OPENCHANGE_RETVAL_IF(strcmp(request.EssDN, emsmdbp_ctx->szUserDN), MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Step 0. Retrieve recipient name */
+	recipient = x500_get_dn_element(mem_ctx, request.EssDN, "/cn=Recipients/cn=");
+	OPENCHANGE_RETVAL_IF(!recipient, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Step 1. Check if mailbox pointed by recipient belongs to the Exchange organisation */
+
+	/* Step 2. Set LogonFlags */
+	response.LogonFlags = request.LogonFlags & LogonPrivate;
+
+	/* Step 3. Build FolderIds list */
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_MAILBOX_ROOT, &response.LogonType.store_mailbox.FolderIds[0]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_DEFERRED_ACTIONS, &response.LogonType.store_mailbox.FolderIds[1]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_SPOOLER_QUEUE, &response.LogonType.store_mailbox.FolderIds[2]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_TOP_INFORMATION_STORE, &response.LogonType.store_mailbox.FolderIds[3]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_INBOX, &response.LogonType.store_mailbox.FolderIds[4]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_OUTBOX, &response.LogonType.store_mailbox.FolderIds[5]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_SENT_ITEMS, &response.LogonType.store_mailbox.FolderIds[6]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_DELETED_ITEMS, &response.LogonType.store_mailbox.FolderIds[7]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_COMMON_VIEWS, &response.LogonType.store_mailbox.FolderIds[8]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_SCHEDULE, &response.LogonType.store_mailbox.FolderIds[9]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_SEARCH, &response.LogonType.store_mailbox.FolderIds[10]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_VIEWS, &response.LogonType.store_mailbox.FolderIds[11]);
+	retval = openchangedb_get_SystemFolderID(emsmdbp_ctx->oc_ctx, recipient, EMSMDBP_SHORTCUTS, &response.LogonType.store_mailbox.FolderIds[12]);
+
+	/* Step 4. Set ResponseFlags */
+	response.LogonType.store_mailbox.ResponseFlags = ResponseFlags_Reserved | ResponseFlags_OwnerRight | ResponseFlags_SendAsRight;
+
+	/* Step 5. Retrieve MailboxGuid */
+	retval = openchangedb_get_MailboxGuid(emsmdbp_ctx->oc_ctx, recipient, &response.LogonType.store_mailbox.MailboxGuid);
+
+	/* Step 6. Retrieve mailbox replication information */
+	retval = openchangedb_get_MailboxReplica(emsmdbp_ctx->oc_ctx, recipient,
+						 &response.LogonType.store_mailbox.ReplId,
+						 &response.LogonType.store_mailbox.ReplGUID);
+
+	/* Step 7. Set LogonTime both in openchange dispatcher database and reply */
+	t = time(NULL);
+	LogonTime = localtime(&t);
+	response.LogonType.store_mailbox.LogonTime.Seconds = LogonTime->tm_sec;
+	response.LogonType.store_mailbox.LogonTime.Minutes = LogonTime->tm_min;
+	response.LogonType.store_mailbox.LogonTime.Hour = LogonTime->tm_hour;
+	response.LogonType.store_mailbox.LogonTime.DayOfWeek = LogonTime->tm_wday;
+	response.LogonType.store_mailbox.LogonTime.Day = LogonTime->tm_mday;
+	response.LogonType.store_mailbox.LogonTime.Month = LogonTime->tm_mon + 1;
+	response.LogonType.store_mailbox.LogonTime.Year = LogonTime->tm_year + 1900;
+
+	/* Step 8. Retrieve GwartTime */
+	unix_to_nt_time(&nttime, t);
+	response.LogonType.store_mailbox.GwartTime = nttime - 1000000;
+
+	/* Step 9. Set StoreState */
+	response.LogonType.store_mailbox.StoreState = 0x0;
+
+	mapi_repl->u.mapi_Logon = response;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc Logon (0xFE) Rop. This operation logs on to a
+   private mailbox or public folder.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request pointer to the Logon EcDoRpc_MAPI_REQ structure
+   \param response pointer to the Logon EcDoRpc_MAPI_REPL structure
+   the function returns
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \note Users are only allowed to open their own mailbox at the
+   moment. This limitation will be removed when significant progress
+   have been made.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopLogon(TALLOC_CTX *mem_ctx,
+					  struct emsmdbp_context *emsmdbp_ctx,
+					  struct EcDoRpc_MAPI_REQ *request,
+					  struct EcDoRpc_MAPI_REPL *response,
+					  uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS			retval;
+	struct mapi_handles		*rec = NULL;
+	struct emsmdbp_object		*object;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCSTOR] Logon (0xFE)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!request, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!response, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Fill EcDoRpc_MAPI_REPL reply */
+	response->opnum = request->opnum;
+	response->handle_idx = request->handle_idx;
+
+	switch (request->u.mapi_Logon.LogonFlags) {
+	case LogonPrivate:
+		retval = RopLogon_Mailbox(mem_ctx, emsmdbp_ctx, request, response);
+		response->error_code = retval;
+		*size = libmapiserver_RopLogon_size(request, response);
+		break;
+	default:
+		DEBUG(4, ("exchange_emsmdb: [OXCSTOR] Logon on Public Folders not implemented\n"));
+		retval = MAPI_E_NO_SUPPORT;
+		response->error_code = retval;
+		*size = libmapiserver_RopLogon_size(request, NULL);
+		break;
+	}
+
+	if (!response->error_code) {
+		retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec);
+		retval = mapi_handles_set_systemfolder(rec, 0);
+
+		object = emsmdbp_object_mailbox_init((TALLOC_CTX *)rec, emsmdbp_ctx, request);
+		retval = mapi_handles_set_private_data(rec, object);
+
+		handles[response->handle_idx] = rec->handle;
+	}
+
+	return retval;
+}
+
+
+/**
+   \details EcDoRpc Release (0x01) Rop. This operation releases an
+   existing MAPI handle.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param request pointer to the Release EcDoRpc_MAPI_REQ
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopRelease(TALLOC_CTX *mem_ctx,
+					    struct emsmdbp_context *emsmdbp_ctx,
+					    struct EcDoRpc_MAPI_REQ *request,
+					    uint32_t *handles,
+					    uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+	uint32_t		handle;
+
+	*size = libmapiserver_RopRelease_size();
+
+	handle = handles[request->handle_idx];
+	retval = mapi_handles_delete(emsmdbp_ctx->handles_ctx, handle);
+	OPENCHANGE_RETVAL_IF(retval && retval != MAPI_E_NOT_FOUND, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc GetReceiveFolder (0x27) Rop Internals. This
+   routine performs the GetReceiveFolder internals.
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetReceiveFolder EcDoRpc_MAPI_REQ
+   \param mapi_repl pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL
+   \param handles pointer to the MAPI handles array
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+static enum MAPISTATUS RopGetReceiveFolder(TALLOC_CTX *mem_ctx,
+					   struct emsmdbp_context *emsmdbp_ctx,
+					   struct EcDoRpc_MAPI_REQ *mapi_req,
+					   struct EcDoRpc_MAPI_REPL *mapi_repl,
+					   uint32_t *handles)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_handles	*rec = NULL;
+	struct emsmdbp_object	*object = NULL;
+	const char		*MessageClass = NULL;
+	void			*private_data = NULL;
+	uint32_t		handle;
+	int			i;
+
+	/* Step 1. Ensure the referring MAPI handle is mailbox one */
+	handle = handles[mapi_req->handle_idx];
+	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+	retval = mapi_handles_get_private_data(rec, (void **)&private_data);
+	object = (struct emsmdbp_object *) private_data;
+	OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+	OPENCHANGE_RETVAL_IF(object->type != EMSMDBP_OBJECT_MAILBOX, MAPI_E_NO_SUPPORT, NULL);
+	
+	/* Step 2. Test Message class string according to [MS-OXCSTOR] section 2.2.1.2.1.1 */
+	MessageClass = mapi_req->u.mapi_GetReceiveFolder.MessageClass;
+	if (!MessageClass || !strcmp(MessageClass, "")) {
+		MessageClass="All";
+	}
+
+	OPENCHANGE_RETVAL_IF(strlen(MessageClass) + 1 > 255, MAPI_E_INVALID_PARAMETER, NULL);
+	for (i = 0; MessageClass[i]; i++) {
+		OPENCHANGE_RETVAL_IF((MessageClass[i] < 32) || (MessageClass[i] > 126), 
+				     MAPI_E_INVALID_PARAMETER, NULL);
+
+		OPENCHANGE_RETVAL_IF(MessageClass[i] == '.' && MessageClass[i + 1] && MessageClass[i + 1] == '.',
+				     MAPI_E_INVALID_PARAMETER, NULL);
+	}
+	OPENCHANGE_RETVAL_IF(MessageClass[0] && MessageClass[0] == '.', MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(MessageClass[0] && MessageClass[strlen(MessageClass)] == '.', MAPI_E_INVALID_PARAMETER, NULL);
+
+	
+	/* Step 3. Search for the specified MessageClass substring within user mailbox */
+	retval = openchangedb_get_ReceiveFolder(mem_ctx, emsmdbp_ctx->oc_ctx, object->object.mailbox->owner_Name,
+						MessageClass, &mapi_repl->u.mapi_GetReceiveFolder.folder_id,
+						&mapi_repl->u.mapi_GetReceiveFolder.MessageClass);
+	OPENCHANGE_RETVAL_IF(retval, ecNoReceiveFolder, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details EcDoRpc GetReceiveFolder (0x27) Rop. This operation gets
+   the receive folder for incoming messages of a particular message
+   class
+
+   \param mem_ctx pointer to the memory context
+   \param emsmdbp_ctx pointer to the emsmdb provider context
+   \param mapi_req pointer to the GetReceiveFolder EcDoRpc_MAPI_REQ
+   \param mapi_repl pointer to the GetReceiveFolder EcDoRpc_MAPI_REPL
+   \param handles pointer to the MAPI handles array
+   \param size pointer to the mapi_response size to update
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetReceiveFolder(TALLOC_CTX *mem_ctx,
+						     struct emsmdbp_context *emsmdbp_ctx,
+						     struct EcDoRpc_MAPI_REQ *mapi_req,
+						     struct EcDoRpc_MAPI_REPL *mapi_repl,
+						     uint32_t *handles, uint16_t *size)
+{
+	enum MAPISTATUS		retval;
+
+	DEBUG(4, ("exchange_emsmdb: [OXCSTOR] GetReceiveFolder (0x27)\n"));
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
+	
+	/* Call effective code */
+	retval = RopGetReceiveFolder(mem_ctx, emsmdbp_ctx, mapi_req, mapi_repl, handles);
+
+	mapi_repl->opnum = mapi_req->opnum;
+	mapi_repl->handle_idx = mapi_req->handle_idx;
+	mapi_repl->error_code = retval;
+
+	*size = libmapiserver_RopGetReceiveFolder_size(mapi_repl);
+	
+	handles[mapi_repl->handle_idx] = handles[mapi_req->handle_idx];
+
+	return retval;
+}

Added: trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,959 @@
+/*
+   MAPI Proxy - Exchange NSPI Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file dcesrv_exchange_nsp.c
+
+   \brief OpenChange NSPI Server implementation
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_nsp.h"
+
+struct exchange_nsp_session	*nsp_session = NULL;
+TDB_CONTEXT			*emsabp_tdb_ctx = NULL;
+
+/**
+   \details exchange_nsp NspiBind (0x0) function, Initiates a NSPI
+   session with the client.
+
+   This function checks if the user is an Exchange user and input
+   parameters like codepage are valid. If it passes the tests, the
+   function initializes an emsabp context and returns to the client a
+   valid policy_handle and expected reply parameters.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiBind call structure
+
+   \return MAPI_E_SUCCESS on success, otherwise a MAPI error
+ */
+static enum MAPISTATUS dcesrv_NspiBind(struct dcesrv_call_state *dce_call,
+				       TALLOC_CTX *mem_ctx,
+				       struct NspiBind *r)
+{
+	struct GUID			*guid = (struct GUID *) NULL;
+	struct emsabp_context		*emsabp_ctx;
+	struct dcesrv_handle		*handle;
+	struct policy_handle		wire_handle;
+	struct exchange_nsp_session	*session;
+
+	DEBUG(5, ("exchange_nsp: NspiBind (0x0)\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"));
+
+		wire_handle.handle_type = EXCHANGE_HANDLE_NSP;
+		wire_handle.uuid = GUID_zero();
+		*r->out.handle = wire_handle;
+
+		r->out.mapiuid = r->in.mapiuid;
+		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) {
+		smb_panic("unable to initialize emsabp context");
+		OPENCHANGE_RETVAL_IF(!emsabp_ctx, MAPI_E_FAILONEPROVIDER, NULL);
+	}
+
+	/* Step 2. Check if incoming user belongs to the Exchange organization */
+	if (emsabp_verify_user(dce_call, emsabp_ctx) == false) {
+		talloc_free(emsabp_ctx);
+
+		wire_handle.handle_type = EXCHANGE_HANDLE_NSP;
+		wire_handle.uuid = GUID_zero();
+		*r->out.handle = wire_handle;
+
+		r->out.mapiuid = r->in.mapiuid;
+		r->out.result = MAPI_E_LOGON_FAILED;
+		return MAPI_E_LOGON_FAILED;
+	}
+
+	/* Step 3. Check if valid cpID has been supplied */
+	if (emsabp_verify_codepage(emsabp_ctx, r->in.pStat->CodePage) == false) {
+		talloc_free(emsabp_ctx);
+
+		wire_handle.handle_type = EXCHANGE_HANDLE_NSP;
+		wire_handle.uuid = GUID_zero();
+		*r->out.handle = wire_handle;
+
+		r->out.mapiuid = r->in.mapiuid;
+		r->out.result = MAPI_E_UNKNOWN_CPID;
+		return MAPI_E_UNKNOWN_CPID;
+	}
+
+	/* Step 4. Retrieve OpenChange server GUID */
+	guid = emsabp_get_server_GUID(emsabp_ctx);
+	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_FAILONEPROVIDER, emsabp_ctx);
+
+	/* Step 5. Fill NspiBind reply */
+	handle = dcesrv_handle_new(dce_call->context, EXCHANGE_HANDLE_NSP);
+	OPENCHANGE_RETVAL_IF(!handle, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx);
+
+	handle->data = (void *) emsabp_ctx;
+	*r->out.handle = handle->wire_handle;
+	r->out.mapiuid = guid;
+	r->out.result = MAPI_E_SUCCESS;
+
+	/* Step 6. Associate this emsabp context to the session */
+	session = talloc((TALLOC_CTX *)nsp_session, struct exchange_nsp_session);
+	OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx);
+
+	session->session = mpm_session_init((TALLOC_CTX *)nsp_session, dce_call);
+	OPENCHANGE_RETVAL_IF(!session->session, MAPI_E_NOT_ENOUGH_RESOURCES, emsabp_ctx);
+
+	mpm_session_set_private_data(session->session, (void *) emsabp_ctx);
+	mpm_session_set_destructor(session->session, emsabp_destructor);
+
+	DLIST_ADD_END(nsp_session, session, struct exchange_nsp_session *);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiUnbind (0x1) function, Terminates a NSPI
+   session with the client
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiUnbind call structure
+ */
+static enum MAPISTATUS dcesrv_NspiUnbind(struct dcesrv_call_state *dce_call,
+					 TALLOC_CTX *mem_ctx,
+					 struct NspiUnbind *r)
+{
+	struct dcesrv_handle		*h;
+	struct exchange_nsp_session	*session;
+
+	DEBUG(5, ("exchange_nsp: NspiUnbind (0x1)\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;
+	}
+
+	/* Step 1. Retrieve handle and free if emsabp context and session are available */
+	h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY);
+	if (h) {
+		for (session = nsp_session; session; session = session->next) {
+			if ((mpm_session_cmp(session->session, dce_call) == true)) {
+				mpm_session_release(session->session);
+				DLIST_REMOVE(nsp_session, session);
+				DEBUG(6, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__));
+			}
+		}
+	}
+
+	r->out.result = 1;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiUpdateStat (0x2) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiUpdateStat request data
+
+   \return MAPI_E_SUCCESS on success
+*/
+static enum MAPISTATUS dcesrv_NspiUpdateStat(struct dcesrv_call_state *dce_call, 
+					     TALLOC_CTX *mem_ctx,
+					     struct NspiUpdateStat *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiUpdateStat (0x2) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiQueryRows (0x3) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiQueryRows request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiQueryRows(struct dcesrv_call_state *dce_call,
+					    TALLOC_CTX *mem_ctx,
+					    struct NspiQueryRows *r)
+{
+	enum MAPISTATUS			retval = MAPI_E_SUCCESS;
+	struct dcesrv_handle		*h;
+	struct emsabp_context		*emsabp_ctx;
+	struct SPropTagArray		*pPropTags;
+	uint32_t			i;
+
+	DEBUG(3, ("exchange_nsp: NspiQueryRows (0x3)\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);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+
+	/* 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;
+	}
+
+	if (r->in.pPropTags == NULL) {
+		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;
+	}
+
+	if (r->in.lpETable == NULL) {
+		/* FIXME */
+		return MAPI_E_INVALID_BOOKMARK;
+	}
+
+	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) {
+			goto failure;
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiSeekEntries (0x4) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiSeekEntries request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiSeekEntries(struct dcesrv_call_state *dce_call,
+					      TALLOC_CTX *mem_ctx,
+					      struct NspiSeekEntries *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiSeekEntries (0x4) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiGetMatches (0x5) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetMatches request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *dce_call,
+					     TALLOC_CTX *mem_ctx,
+					     struct NspiGetMatches *r)
+{
+	enum MAPISTATUS			retval;
+	struct dcesrv_handle		*h;
+	struct emsabp_context		*emsabp_ctx;
+	struct SPropTagArray		*ppOutMIds = NULL;
+	uint32_t			i;
+	
+
+	DEBUG(3, ("exchange_nsp: NspiGetMatches (0x5)\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);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+
+	/* Step 1. Retrieve MIds array given search criterias */
+	ppOutMIds = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = emsabp_search(mem_ctx, emsabp_ctx, ppOutMIds, r->in.Filter, r->in.pStat, r->in.ulRequested);
+	if (retval != MAPI_E_SUCCESS) {
+	failure:
+		r->out.pStat = r->in.pStat;
+		ppOutMIds = NULL;
+		r->out.ppOutMIds = &ppOutMIds;		
+		r->out.ppRows = talloc(mem_ctx, struct SRowSet *);
+		r->out.ppRows[0] = NULL;
+		r->out.result = retval;
+		
+		return retval;
+	}
+
+	*r->out.ppOutMIds = ppOutMIds;
+
+	/* Step 2. Retrieve requested properties for these MIds */
+	r->out.ppRows = talloc_zero(mem_ctx, struct SRowSet *);
+	r->out.ppRows[0] = talloc_zero(mem_ctx, struct SRowSet);
+	r->out.ppRows[0]->cRows = ppOutMIds->cValues;
+	r->out.ppRows[0]->aRow = talloc_array(mem_ctx, struct SRow, ppOutMIds->cValues);
+	
+
+	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);
+		if (retval) goto failure;
+	}
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiResortRestriction (0x6) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiResortRestriction request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiResortRestriction(struct dcesrv_call_state *dce_call,
+						    TALLOC_CTX *mem_ctx,
+						    struct NspiResortRestriction *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiResortRestriction (0x6) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiDNToMId (0x7) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiDNToMId request data
+
+   \note Only searches within configuration.ldb are supported at the
+   moment.
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiDNToMId(struct dcesrv_call_state *dce_call,
+					  TALLOC_CTX *mem_ctx,
+					  struct NspiDNToMId *r)
+{
+	enum MAPISTATUS		retval;
+	struct dcesrv_handle	*h;
+	struct emsabp_context	*emsabp_ctx;
+	struct ldb_message	*msg;
+	uint32_t		i;
+	uint32_t		MId;
+	const char		*dn;
+
+	DEBUG(3, ("exchange_nsp: NspiDNToMId (0x7)\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);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+	
+	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);
+
+	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);
+		if (retval != MAPI_E_SUCCESS) {
+			r->out.ppMIds[0]->aulPropTag[i] = 0;
+		} else {
+			dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL);
+			retval = emsabp_tdb_fetch_MId(emsabp_ctx->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);
+			}
+			r->out.ppMIds[0]->aulPropTag[i] = MId;
+		}
+	}
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiGetPropList (0x8) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetPropList request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiGetPropList(struct dcesrv_call_state *dce_call,
+					      TALLOC_CTX *mem_ctx,
+					      struct NspiGetPropList *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiGetPropList (0x8) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiGetProps (0x9) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetProps request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *dce_call,
+					   TALLOC_CTX *mem_ctx,
+					   struct NspiGetProps *r)
+{
+	enum MAPISTATUS		retval;
+	struct dcesrv_handle	*h;
+	struct emsabp_context	*emsabp_ctx;
+	uint32_t		MId;
+	char			*dn;
+
+	DEBUG(3, ("exchange_nsp: NspiGetProps (0x9)\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);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+
+	MId = r->in.pStat->CurrentRec;
+	
+	/* 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;
+	}
+
+	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(mem_ctx, struct SRow);
+	r->out.ppRows[0]->ulAdrEntryPad = 0;
+	r->out.ppRows[0]->cValues = r->in.pPropTags->cValues;
+	r->out.ppRows[0]->lpProps = talloc_array(mem_ctx, struct SPropValue, r->in.pPropTags->cValues);
+
+	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.pPropTags);
+	if (retval != MAPI_E_SUCCESS) {
+		talloc_free(r->out.ppRows[0]->lpProps);
+		talloc_free(r->out.ppRows[0]);
+		talloc_free(r->out.ppRows[0]);
+		r->out.result = MAPI_W_ERRORS_RETURNED;
+		goto failure;
+	}
+
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_nsp NspiCompareMIds (0xA) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiCompareMIds request data
+
+   \return MAPI_E_SUCCESS on success
+*/
+static enum MAPISTATUS dcesrv_NspiCompareMIds(struct dcesrv_call_state *dce_call,
+					      TALLOC_CTX *mem_ctx,
+					      struct NspiCompareMIds *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiCompareMIds (0xA) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiModProps (0xB) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiModProps request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiModProps(struct dcesrv_call_state *dce_call,
+					   TALLOC_CTX *mem_ctx,
+					   struct NspiModProps *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiModProps (0xB) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiGetSpecialTable (0xC) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetSpecialTable request data
+
+   \note MS-NSPI specifies lpVersion "holds the value of the version
+   number of the hierarchy table that the client has." We will ignore
+   this for the moment.
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiGetSpecialTable(struct dcesrv_call_state *dce_call,
+						  TALLOC_CTX *mem_ctx,
+						  struct NspiGetSpecialTable *r)
+{
+	struct dcesrv_handle		*h;
+	struct emsabp_context		*emsabp_ctx;
+
+	DEBUG(3, ("exchange_nsp: NspiGetSpecialTable (0xC)\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);
+	emsabp_ctx = (struct emsabp_context *) h->data;
+
+	/* Step 1. (FIXME) We arbitrary set lpVersion to 0x1 */
+	r->out.lpVersion = talloc_zero(mem_ctx, uint32_t);
+	*r->out.lpVersion = 0x1;
+
+	/* Step 2. Allocate output SRowSet and call associated emsabp function */
+	r->out.ppRows = talloc_zero(mem_ctx, struct SRowSet *);
+	OPENCHANGE_RETVAL_IF(!r->out.ppRows, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+	r->out.ppRows[0] = talloc_zero(mem_ctx, struct SRowSet);
+	OPENCHANGE_RETVAL_IF(!r->out.ppRows[0], MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
+	switch (r->in.dwFlags) {
+	case NspiAddressCreationTemplates:
+	case NspiAddressCreationTemplates|NspiUnicodeStrings:
+		DEBUG(0, ("CreationTemplates Table requested\n"));
+		r->out.result = emsabp_get_CreationTemplatesTable(mem_ctx, emsabp_ctx, r->in.dwFlags, r->out.ppRows);
+		break;
+	case NspiUnicodeStrings:
+	case 0x0:
+		DEBUG(0, ("Hierarchy Table requested\n"));
+		r->out.result = emsabp_get_HierarchyTable(mem_ctx, emsabp_ctx, r->in.dwFlags, r->out.ppRows);
+		break;
+	default:
+		talloc_free(r->out.ppRows);
+		talloc_free(r->out.ppRows[0]);
+		return MAPI_E_NO_SUPPORT;
+	}
+
+	return r->out.result;
+}
+
+
+/**
+   \details exchange_nsp NspiGetTemplateInfo (0xD) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetTemplateInfo request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiGetTemplateInfo(struct dcesrv_call_state *dce_call,
+						  TALLOC_CTX *mem_ctx,
+						  struct NspiGetTemplateInfo *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiGetTemplateInfo (0xD) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiModLinkAtt (0xE) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiModLinkAtt request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiModLinkAtt(struct dcesrv_call_state *dce_call,
+					     TALLOC_CTX *mem_ctx,
+					     struct NspiModLinkAtt *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiModLinkAtt (0xE) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiDeleteEntries (0xF) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiDeleteEntries request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiDeleteEntries(struct dcesrv_call_state *dce_call,
+						TALLOC_CTX *mem_ctx,
+						struct NspiDeleteEntries *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiDeleteEntries (0xF) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiQueryColumns (0x10) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiQueryColumns request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiQueryColumns(struct dcesrv_call_state *dce_call,
+					       TALLOC_CTX *mem_ctx,
+					       struct NspiQueryColumns *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiQueryColumns (0x10) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiGetNamesFromIDs (0x11) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetNamesFromIDs request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiGetNamesFromIDs(struct dcesrv_call_state *dce_call,
+						  TALLOC_CTX *mem_ctx,
+						  struct NspiGetNamesFromIDs *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiGetNamesFromIDs (0x11) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiGetIDsFromNames (0x12) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiGetIDsFromNames request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiGetIDsFromNames(struct dcesrv_call_state *dce_call,
+						  TALLOC_CTX *mem_ctx,
+						  struct NspiGetIDsFromNames *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiGetIDsFromNames (0x12) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiResolveNames (0x13) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiResolveNames request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiResolveNames(struct dcesrv_call_state *dce_call,
+					       TALLOC_CTX *mem_ctx,
+					       struct NspiResolveNames *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiResolveNames (0x13) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details exchange_nsp NspiResolveNamesW (0x14) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the NspiResolveNamesW request data
+
+   \return MAPI_E_SUCCESS on success
+
+ */
+static enum MAPISTATUS dcesrv_NspiResolveNamesW(struct dcesrv_call_state *dce_call,
+						TALLOC_CTX *mem_ctx,
+						struct NspiResolveNamesW *r)
+{
+	DEBUG(3, ("exchange_nsp: NspiResolveNamesW (0x14) not implemented\n"));
+	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+}
+
+
+/**
+   \details Dispatch incoming NSPI call to the correct OpenChange
+   server function.
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r generic pointer on NSPI data
+   \param mapiproxy pointer to the mapiproxy structure controlling 
+   mapiproxy behavior
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS dcesrv_exchange_nsp_dispatch(struct dcesrv_call_state *dce_call,
+					     TALLOC_CTX *mem_ctx,
+					     void *r, struct mapiproxy *mapiproxy)
+{
+	enum MAPISTATUS				retval;
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	/* Sanity checks */
+	if (!table) return NT_STATUS_UNSUCCESSFUL;
+	if (table->name && strcmp(table->name, NDR_EXCHANGE_NSP_NAME)) return NT_STATUS_UNSUCCESSFUL;
+
+	switch (opnum) {
+	case NDR_NSPIBIND:
+		retval = dcesrv_NspiBind(dce_call, mem_ctx, (struct NspiBind *)r);
+		break;
+	case NDR_NSPIUNBIND:
+		retval = dcesrv_NspiUnbind(dce_call, mem_ctx, (struct NspiUnbind *)r);
+		break;
+	case NDR_NSPIUPDATESTAT:
+		retval = dcesrv_NspiUpdateStat(dce_call, mem_ctx, (struct NspiUpdateStat *)r);
+		break;
+	case NDR_NSPIQUERYROWS:
+		retval = dcesrv_NspiQueryRows(dce_call, mem_ctx, (struct NspiQueryRows *)r);
+		break;
+	case NDR_NSPISEEKENTRIES:
+		retval = dcesrv_NspiSeekEntries(dce_call, mem_ctx, (struct NspiSeekEntries *)r);
+		break;
+	case NDR_NSPIGETMATCHES:
+		retval = dcesrv_NspiGetMatches(dce_call, mem_ctx, (struct NspiGetMatches *)r);
+		break;
+	case NDR_NSPIRESORTRESTRICTION:
+		retval = dcesrv_NspiResortRestriction(dce_call, mem_ctx, (struct NspiResortRestriction *)r);
+		break;
+	case NDR_NSPIDNTOMID:
+		retval = dcesrv_NspiDNToMId(dce_call, mem_ctx, (struct NspiDNToMId *)r);
+		break;
+	case NDR_NSPIGETPROPLIST:
+		retval = dcesrv_NspiGetPropList(dce_call, mem_ctx, (struct NspiGetPropList *)r);
+		break;
+	case NDR_NSPIGETPROPS:
+		retval = dcesrv_NspiGetProps(dce_call, mem_ctx, (struct NspiGetProps *)r);
+		break;
+	case NDR_NSPICOMPAREMIDS:
+		retval = dcesrv_NspiCompareMIds(dce_call, mem_ctx, (struct NspiCompareMIds *)r);
+		break;
+	case NDR_NSPIMODPROPS:
+		retval = dcesrv_NspiModProps(dce_call, mem_ctx, (struct NspiModProps *)r);
+		break;
+	case NDR_NSPIGETSPECIALTABLE:
+		retval = dcesrv_NspiGetSpecialTable(dce_call, mem_ctx, (struct NspiGetSpecialTable *)r);
+		break;
+	case NDR_NSPIGETTEMPLATEINFO:
+		retval = dcesrv_NspiGetTemplateInfo(dce_call, mem_ctx, (struct NspiGetTemplateInfo *)r);
+		break;
+	case NDR_NSPIMODLINKATT:
+		retval = dcesrv_NspiModLinkAtt(dce_call, mem_ctx, (struct NspiModLinkAtt *)r);
+		break;
+	case NDR_NSPIDELETEENTRIES:
+		retval = dcesrv_NspiDeleteEntries(dce_call, mem_ctx, (struct NspiDeleteEntries *)r);
+		break;
+	case NDR_NSPIQUERYCOLUMNS:
+		retval = dcesrv_NspiQueryColumns(dce_call, mem_ctx, (struct NspiQueryColumns *)r);
+		break;
+	case NDR_NSPIGETNAMESFROMIDS:
+		retval = dcesrv_NspiGetNamesFromIDs(dce_call, mem_ctx, (struct NspiGetNamesFromIDs *)r);
+		break;
+	case NDR_NSPIGETIDSFROMNAMES:
+		retval = dcesrv_NspiGetIDsFromNames(dce_call, mem_ctx, (struct NspiGetIDsFromNames *)r);
+		break;
+	case NDR_NSPIRESOLVENAMES:
+		retval = dcesrv_NspiResolveNames(dce_call, mem_ctx, (struct NspiResolveNames *)r);
+		break;
+	case NDR_NSPIRESOLVENAMESW:
+		retval = dcesrv_NspiResolveNamesW(dce_call, mem_ctx, (struct NspiResolveNamesW *)r);
+		break;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize the NSPI OpenChange server
+
+   \param dce_ctx pointer to the server context
+
+   \return NT_STATUS_OK on success, otherwise NT_STATUS_NO_MEMORY
+ */
+static NTSTATUS dcesrv_exchange_nsp_init(struct dcesrv_context *dce_ctx)
+{
+	/* Initialize exchange_nsp session */
+	nsp_session = talloc_zero(dce_ctx, struct exchange_nsp_session);
+	if (!nsp_session) return NT_STATUS_NO_MEMORY;
+	nsp_session->session = NULL;
+
+	/* Open a read-write pointer on the EMSABP TDB database */
+	emsabp_tdb_ctx = emsabp_tdb_init((TALLOC_CTX *)dce_ctx, dce_ctx->lp_ctx);
+	if (!emsabp_tdb_ctx) {
+		smb_panic("unable to initialize EMSABP context");
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Terminates the NSPI connection and release the associated
+   session and context if still available. This case occurs when the
+   client doesn't call NspiUnbind but quit unexpectedly.
+
+   \param server_id reference to the server identifier structure
+   \param context_id the connection context identifier
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS dcesrv_exchange_nsp_unbind(struct server_id server_id, uint32_t context_id)
+{
+	struct exchange_nsp_session	*session;
+
+	for (session = nsp_session; session; session = session->next) {
+		if ((mpm_session_cmp_sub(session->session, server_id, context_id) == true)) {
+			mpm_session_release(session->session);
+			DLIST_REMOVE(nsp_session, session);
+			DEBUG(6, ("[%s:%d]: Session found and released\n", __FUNCTION__, __LINE__));
+			return NT_STATUS_OK;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Entry point for the default OpenChange NSPI server
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	server;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	server.name = "exchange_nsp";
+	server.status = MAPIPROXY_DEFAULT;
+	server.description = "OpenChange NSPI server";
+	server.endpoint = "exchange_nsp";
+
+	/* Fill in all the operations */
+	server.init = dcesrv_exchange_nsp_init;
+	server.unbind = dcesrv_exchange_nsp_unbind;
+	server.dispatch = dcesrv_exchange_nsp_dispatch;
+	server.push = NULL;
+	server.pull = NULL;
+	server.ndr_pull = NULL;
+
+	/* Register ourselves with the MAPIPROXY server subsystem */
+	ret = mapiproxy_server_register(&server);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'exchange_nsp' default mapiproxy server!\n"));
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,153 @@
+/*
+   MAPI Proxy - Exchange NSPI Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__DCESRV_EXCHANGE_NSP_H
+#define	__DCESRV_EXCHANGE_NSP_H
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto_private.h>
+#include <mapiproxy/libmapiproxy/libmapiproxy.h>
+#include <ldb.h>
+#include <ldb_errors.h>
+#include <fcntl.h>
+#include <util/debug.h>
+
+#ifndef	__BEGIN_DECLS
+#ifdef	__cplusplus
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+#endif
+
+struct emsabp_context {
+	struct loadparm_context	*lp_ctx;
+	void			*conf_ctx;
+	void			*users_ctx;
+	void			*ldb_ctx;
+	TDB_CONTEXT		*tdb_ctx;
+	TDB_CONTEXT		*ttdb_ctx;
+	TALLOC_CTX		*mem_ctx;
+};
+
+
+struct exchange_nsp_session {
+	struct mpm_session		*session;
+	struct exchange_nsp_session	*prev;
+	struct exchange_nsp_session	*next;
+};
+
+
+struct emsabp_MId {
+	uint32_t	MId;
+	char		*dn;
+};
+
+/**
+   PermanentEntryID structure 
+ */
+struct PermanentEntryID {
+	uint8_t			ID_type;	/* constant: 0x0	*/
+	uint8_t			R1;		/* reserved: 0x0	*/
+	uint8_t			R2;		/* reserved: 0x0	*/
+	uint8_t			R3;		/* reserved: 0x0	*/
+	struct FlatUID_r      	ProviderUID;	/* constant: GUID_NSPI	*/
+	uint32_t		R4;		/* constant: 0x1	*/
+	uint32_t		DisplayType;	/* must match one of the existing Display Type value */
+	char			*dn;		/* DN string representing the object GUID */
+};
+
+
+/**
+   EphemeralEntryID structure
+ */
+struct EphemeralEntryID {
+	uint8_t			ID_type;	/* constant: 0x87	*/
+	uint8_t			R1;		/* reserved: 0x0	*/
+	uint8_t			R2;		/* reserved: 0x0	*/
+	uint8_t			R3;		/* reserved: 0x0	*/
+	struct FlatUID_r	ProviderUID;	/* NSPI server GUID	*/
+	uint32_t		R4;		/* constant: 0x1	*/
+	uint32_t		DisplayType;	/* must match one of the existing Display Type value */
+	uint32_t		MId;		/* MId of this object	*/
+};
+
+#define	EMSABP_DN	"/guid=%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X"
+#define	EMSABP_ADDRTYPE	"EX"
+
+/**
+   NSPI PR_CONTAINER_FLAGS values
+ */
+#define	AB_RECIPIENTS		0x1
+#define	AB_SUBCONTAINERS	0x2
+#define	AB_UNMODIFIABLE		0x8
+
+#define	EMSABP_TDB_MID_START		0x1b28
+#define	EMSABP_TDB_TMP_MID_START	0x5000
+#define	EMSABP_TDB_DATA_REC		"MId_index"
+
+__BEGIN_DECLS
+
+NTSTATUS	samba_init_module(void);
+
+/* definitions from emsabp.c */
+struct emsabp_context	*emsabp_init(struct loadparm_context *, TDB_CONTEXT *);
+bool			emsabp_destructor(void *);
+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 *);
+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 **);
+
+/* definitions from emsabp_tdb.c */
+TDB_CONTEXT		*emsabp_tdb_init(TALLOC_CTX *, struct loadparm_context *);
+enum MAPISTATUS		emsabp_tdb_close(TDB_CONTEXT *);
+enum MAPISTATUS		emsabp_tdb_fetch(TDB_CONTEXT *, const char *, TDB_DATA *);
+enum MAPISTATUS		emsabp_tdb_insert(TDB_CONTEXT *, const char *);
+enum MAPISTATUS		emsabp_tdb_fetch_MId(TDB_CONTEXT *, const char *, uint32_t *);
+bool			emsabp_tdb_lookup_MId(TDB_CONTEXT *, uint32_t);
+enum MAPISTATUS		emsabp_tdb_fetch_dn_from_MId(TALLOC_CTX *, TDB_CONTEXT *, uint32_t, char **);
+
+TDB_CONTEXT		*emsabp_tdb_init_tmp(TALLOC_CTX *);
+
+/* definitions from emsabp_property.c */
+const char		*emsabp_property_get_attribute(uint32_t);
+uint32_t		emsabp_property_get_ulPropTag(const char *);
+int			emsabp_property_is_ref(uint32_t);
+const char		*emsabp_property_get_ref_attr(uint32_t);
+
+__END_DECLS
+
+#endif /* __DCESRV_EXCHANGE_NSP_H */

Added: trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1124 @@
+/*
+   OpenChange Server implementation.
+
+   EMSABP: Address Book Provider implementation
+
+   Copyright (C) Julien Kerihuel 2006-2009.
+   Copyright (C) Pauline Khun 2006.
+
+   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/>.
+ */
+
+/**
+   \file emsabp.c
+
+   \brief Address Book Provider implementation
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_nsp.h"
+
+/**
+   \details Initialize the EMSABP context and open connections to
+   Samba databases.
+
+   \param lp_ctx pointer to the loadparm context
+   \param tdb_ctx pointer to the EMSABP TDB context
+
+   \return Allocated emsabp_context on success, otherwise NULL
+ */
+_PUBLIC_ struct emsabp_context *emsabp_init(struct loadparm_context *lp_ctx,
+					    TDB_CONTEXT *tdb_ctx)
+{
+	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;
+
+	mem_ctx = talloc_named(NULL, 0, "emsabp_init");
+	
+	emsabp_ctx = talloc_zero(mem_ctx, struct emsabp_context);
+	if (!emsabp_ctx) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	emsabp_ctx->mem_ctx = mem_ctx;
+
+	ev = tevent_context_init(mem_ctx);
+	if (!ev) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	/* 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);
+		talloc_free(mem_ctx);
+		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;
+
+	/* Initialize a temporary (on-memory) TDB database to store
+	 * temporary MId used within EMSABP */
+	emsabp_ctx->ttdb_ctx = emsabp_tdb_init_tmp(emsabp_ctx->mem_ctx);
+	if (!emsabp_ctx->ttdb_ctx) {
+		smb_panic("unable to create on-memory TDB database");
+	}
+
+	return emsabp_ctx;
+}
+
+
+_PUBLIC_ bool emsabp_destructor(void *data)
+{
+	struct emsabp_context	*emsabp_ctx = (struct emsabp_context *)data;
+
+	if (emsabp_ctx) {
+		if (emsabp_ctx->ttdb_ctx) {
+			tdb_close(emsabp_ctx->ttdb_ctx);
+		}
+
+		talloc_free(emsabp_ctx->mem_ctx);
+		return true;
+	}
+
+	return false;
+}
+
+
+/**
+   \details Check if the authenticated user belongs to the Exchange
+   organization
+
+   \param dce_call pointer to the session context
+   \param emsabp_ctx pointer to the EMSABP context
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool emsabp_verify_user(struct dcesrv_call_state *dce_call,
+				 struct emsabp_context *emsabp_ctx)
+{
+	int			ret;
+	const char		*username = NULL;
+	int			msExchUserAccountControl;
+	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	struct ldb_result	*res = NULL;
+	char			*ldb_filter;
+	const char * const	recipient_attrs[] = { "msExchUserAccountControl", NULL };
+
+	username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
+
+	ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "CN=%s", username);
+	ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res, 
+			 ldb_get_default_basedn(emsabp_ctx->users_ctx),
+			 scope, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	/* If the search failed */
+	if (ret != LDB_SUCCESS || !res->count) {
+		return false;
+	}
+
+	/* 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;
+}
+
+
+/**
+   \details Check if the provided codepage is correct
+
+   \param emsabp_ctx pointer to the EMSABP context
+   \param CodePage the codepage identifier
+
+   \note The prototype is currently incorrect, but we are looking for
+   a better way to check codepage, maybe within AD. At the moment this
+   function is just a wrapper over libmapi valid_codepage function.
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool emsabp_verify_codepage(struct emsabp_context *emsabp_ctx,
+				     uint32_t CodePage)
+{
+	return valid_codepage(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			*ldb_filter;
+	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 */
+	ldb_filter = talloc_strdup(emsabp_ctx->mem_ctx, "(objectClass=msExchOrganizationContainer)");
+	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
+			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
+			 scope, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	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
+   \param DisplayType the AB object display type
+   \param MId the MId value
+   \param ephEntryID pointer to the EphemeralEntryID returned by the
+   function
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_set_EphemeralEntryID(struct emsabp_context *emsabp_ctx,
+						     uint32_t DisplayType, uint32_t MId,
+						     struct EphemeralEntryID *ephEntryID)
+{
+	struct GUID	*guid = (struct GUID *) NULL;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
+	guid = emsabp_get_server_GUID(emsabp_ctx);
+	OPENCHANGE_RETVAL_IF(!guid, MAPI_E_CORRUPT_STORE, NULL);
+
+	ephEntryID->ID_type = 0x87;
+	ephEntryID->R1 = 0x0;
+	ephEntryID->R2 = 0x0;
+	ephEntryID->R3 = 0x0;
+	ephEntryID->ProviderUID.ab[0] = (guid->time_low & 0xFF);
+	ephEntryID->ProviderUID.ab[1] = ((guid->time_low >> 8)  & 0xFF);
+	ephEntryID->ProviderUID.ab[2] = ((guid->time_low >> 16) & 0xFF);
+	ephEntryID->ProviderUID.ab[3] = ((guid->time_low >> 24) & 0xFF);
+	ephEntryID->ProviderUID.ab[4] = (guid->time_mid & 0xFF);
+	ephEntryID->ProviderUID.ab[5] = ((guid->time_mid >> 8)  & 0xFF);
+	ephEntryID->ProviderUID.ab[6] = (guid->time_hi_and_version & 0xFF);
+	ephEntryID->ProviderUID.ab[7] = ((guid->time_hi_and_version >> 8) & 0xFF);
+	memcpy(ephEntryID->ProviderUID.ab + 8,  guid->clock_seq, sizeof (uint8_t) * 2);
+	memcpy(ephEntryID->ProviderUID.ab + 10, guid->node, sizeof (uint8_t) * 6);
+	ephEntryID->R4 = 0x1;
+	ephEntryID->DisplayType = DisplayType;
+	ephEntryID->MId = MId;
+
+	talloc_free(guid);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Map an EphemeralEntryID structure into a Binary_r structure
+
+   \param mem_ctx pointer to the memory context
+   \param ephEntryID pointer to the Ephemeral EntryID structure
+   \param bin pointer to the Binary_r structure the server will return
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_EphemeralEntryID_to_Binary_r(TALLOC_CTX *mem_ctx,
+							     struct EphemeralEntryID *ephEntryID,
+							     struct Binary_r *bin)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!ephEntryID, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL);
+
+	bin->cb = sizeof (*ephEntryID);
+	bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);
+
+	/* Copy EphemeralEntryID into bin->lpb */
+	memset(bin->lpb, 0, bin->cb);
+	bin->lpb[0] = ephEntryID->ID_type;
+	bin->lpb[1] = ephEntryID->R1;
+	bin->lpb[2] = ephEntryID->R2;
+	bin->lpb[3] = ephEntryID->R3;
+	memcpy(bin->lpb + 4, ephEntryID->ProviderUID.ab, 16);
+	bin->lpb[20] = (ephEntryID->R4 & 0xFF);
+	bin->lpb[21] = ((ephEntryID->R4 >> 8)  & 0xFF);
+	bin->lpb[22] = ((ephEntryID->R4 >> 16) & 0xFF);
+	bin->lpb[23] = ((ephEntryID->R4 >> 24) & 0xFF);
+	bin->lpb[24] = (ephEntryID->DisplayType & 0xFF);
+	bin->lpb[25] = ((ephEntryID->DisplayType >> 8)  & 0xFF);
+	bin->lpb[26] = ((ephEntryID->DisplayType >> 16) & 0xFF);
+	bin->lpb[27] = ((ephEntryID->DisplayType >> 24) & 0xFF);
+	bin->lpb[28] = (ephEntryID->MId & 0xFF);
+	bin->lpb[29] = ((ephEntryID->MId >> 8)  & 0xFF);
+	bin->lpb[30] = ((ephEntryID->MId >> 16) & 0xFF);
+	bin->lpb[31] = ((ephEntryID->MId >> 24) & 0xFF);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Build a PermanentEntryID structure
+
+   \param emsabp_ctx pointer to the EMSABP context
+   \param DisplayType the AB object display type
+   \param ldb_recipient pointer on the LDB message
+   \param permEntryID pointer to the PermanentEntryID returned by the
+   function
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_NOT_ENOUGH_RESOURCES or MAPI_E_CORRUPT_STORE
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_set_PermanentEntryID(struct emsabp_context *emsabp_ctx, 
+						     uint32_t DisplayType, struct ldb_message *msg, 
+						     struct PermanentEntryID *permEntryID)
+{
+	struct GUID	*guid = (struct GUID *) NULL;
+	const char	*guid_str;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+	
+
+	permEntryID->ID_type = 0x0;
+	permEntryID->R1 = 0x0;
+	permEntryID->R2 = 0x0;
+	permEntryID->R3 = 0x0;
+	memcpy(permEntryID->ProviderUID.ab, GUID_NSPI, 16);
+	permEntryID->R4 = 0x1;
+	permEntryID->DisplayType = DisplayType;
+
+	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);
+		guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID);
+		GUID_from_string(guid_str, guid);
+		permEntryID->dn = talloc_asprintf(emsabp_ctx->mem_ctx, EMSABP_DN, 
+						  guid->time_low, guid->time_mid,
+						  guid->time_hi_and_version,
+						  guid->clock_seq[0],
+						  guid->clock_seq[1],
+						  guid->node[0], guid->node[1],
+						  guid->node[2], guid->node[3],
+						  guid->node[4], guid->node[5]);
+		talloc_free(guid);
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Map a PermanentEntryID structure into a Binary_r
+   structure (for PR_ENTRYID and PR_EMS_AB_PARENT_ENTRYID properties)
+
+   \param mem_ctx pointer to the memory context
+   \param permEntryID pointer to the Permanent EntryID structure
+   \param bin pointer to the Binary_r structure the server will return
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_PermanentEntryID_to_Binary_r(TALLOC_CTX *mem_ctx,
+							     struct PermanentEntryID *permEntryID,
+							     struct Binary_r *bin)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!bin, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* Remove const char * size and replace it with effective dn string length */
+	bin->cb = sizeof (*permEntryID) - 4 + strlen(permEntryID->dn) + 1;
+	bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);
+
+	/* Copy PermanantEntryID intro bin->lpb */
+	memset(bin->lpb, 0, bin->cb);
+	bin->lpb[0] = permEntryID->ID_type;
+	bin->lpb[1] = permEntryID->R1;
+	bin->lpb[2] = permEntryID->R2;
+	bin->lpb[3] = permEntryID->R3;
+	memcpy(bin->lpb + 4, permEntryID->ProviderUID.ab, 16);
+	bin->lpb[20] = (permEntryID->R4 & 0xFF);
+	bin->lpb[21] = ((permEntryID->R4 >> 8)  & 0xFF);
+	bin->lpb[22] = ((permEntryID->R4 >> 16) & 0xFF);
+	bin->lpb[23] = ((permEntryID->R4 >> 24) & 0xFF);
+	bin->lpb[24] = (permEntryID->DisplayType & 0xFF);
+	bin->lpb[25] = ((permEntryID->DisplayType >> 8)  & 0xFF);
+	bin->lpb[26] = ((permEntryID->DisplayType >> 16) & 0xFF);
+	bin->lpb[27] = ((permEntryID->DisplayType >> 24) & 0xFF);
+	memcpy(bin->lpb + 28, permEntryID->dn, strlen(permEntryID->dn) + 1);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Find the attribute matching the specified property tag and
+   return the associated data.
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param msg pointer to the LDB message
+   \param ulPropTag the property tag to lookup
+   \param MId Minimal Entry ID associated to the current message
+
+   \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.
+
+   \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)
+{
+	enum MAPISTATUS			retval;
+	void				*data = (void *) NULL;
+	const char			*attribute;
+	const char			*ref_attribute;
+	const char			*ldb_string = NULL;
+	struct Binary_r			*bin;
+	struct StringArray_r		*mvszA;
+	struct EphemeralEntryID		ephEntryID;
+	struct ldb_message		*msg2 = NULL;
+	struct ldb_message_element	*ldb_element;
+	int				ret;
+	const char			*dn = NULL;
+	uint32_t			i;
+
+	/* Step 1. Fill attributes not in AD but created using EMSABP databases */
+	switch (ulPropTag) {
+	case PR_ADDRTYPE:
+		data = (void *) talloc_strdup(mem_ctx, EMSABP_ADDRTYPE);
+		return data;
+	case PR_OBJECT_TYPE:
+		data = talloc_zero(mem_ctx, uint32_t);
+		*((uint32_t *)data) = MAPI_MAILUSER;
+		return data;
+	case PR_DISPLAY_TYPE:
+		data = talloc_zero(mem_ctx, uint32_t);
+		*((uint32_t *)data) = DT_MAILUSER;
+		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);
+		return bin;
+	case PR_INSTANCE_KEY:
+		bin = talloc_zero(mem_ctx, struct Binary_r);
+		bin->cb = 4;
+		bin->lpb = talloc_array(mem_ctx, uint8_t, bin->cb);
+		memset(bin->lpb, 0, bin->cb);
+		bin->lpb[0] = MId & 0xFF;
+		bin->lpb[1] = (MId >> 8)  & 0xFF;
+		bin->lpb[2] = (MId >> 16) & 0xFF;
+		bin->lpb[3] = (MId >> 24) & 0xFF;
+		return bin;
+	default:
+		break;
+	}
+
+	/* Step 2. Retrieve the attribute name associated to ulPropTag and handle the ref case */
+	attribute = emsabp_property_get_attribute(ulPropTag);
+	if (!attribute) return NULL;
+
+	ret = emsabp_property_is_ref(ulPropTag);
+	if (ret == 1) {
+		ref_attribute = emsabp_property_get_ref_attr(ulPropTag);
+		if (ref_attribute) {
+			dn = ldb_msg_find_attr_as_string(msg, attribute, NULL);
+			retval = emsabp_search_dn(emsabp_ctx, dn, &msg2);
+			if (retval != MAPI_E_SUCCESS) {
+				return NULL;
+			}
+			attribute = ref_attribute;
+		}
+	} else {
+		msg2 = msg;
+	}
+
+	/* Step 3. Retrieve data associated to the attribute/tag */
+	switch (ulPropTag & 0xFFFF) {
+	case PT_STRING8:
+	case PT_UNICODE:
+		ldb_string = ldb_msg_find_attr_as_string(msg2, attribute, NULL);
+		if (!ldb_string) return NULL;
+		data = talloc_strdup(mem_ctx, ldb_string);
+		break;
+	case PT_MV_STRING8:
+		ldb_element = ldb_msg_find_element(msg2, attribute);
+		if (!ldb_element) return NULL;
+
+		mvszA = talloc(mem_ctx, struct StringArray_r);
+		mvszA->cValues = ldb_element[0].num_values & 0xFFFFFFFF;
+		mvszA->lppszA = talloc_array(mem_ctx, const char *, mvszA->cValues);
+		for (i = 0; i < mvszA->cValues; i++) {
+			mvszA->lppszA[i] = talloc_strdup(mem_ctx, (char *)ldb_element->values[i].data);
+		}
+		data = (void *) mvszA;
+		break;
+	default:
+		DEBUG(3, ("[%s:%d]: Unsupported property type: 0x%x\n", __FUNCTION__, __LINE__,
+			  (ulPropTag & 0xFFFF)));
+		break;
+	}
+
+	return data;
+}
+
+
+/**
+   \details Builds the SRow array entry for the specified MId.
+
+   The function retrieves the DN associated to the specified MId
+   within its on-memory TDB database. It next fetches the LDB record
+   matching the DN and finally retrieve the requested properties for
+   this record.
+
+   \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 MId MId to fetch properties for
+   \param pPropTags pointer to the property tags array
+
+   \note We currently assume records are users.ldb
+
+   \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 SPropTagArray *pPropTags)
+{
+	enum MAPISTATUS		retval;
+	void			*ldb_ctx;
+	char			*dn;
+	const char * const	recipient_attrs[] = { "*", NULL };
+	struct ldb_result	*res = NULL;
+	struct ldb_dn		*ldb_dn = NULL;
+	int			ret;
+	uint32_t		ulPropTag;
+	void			*data;
+	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 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);
+
+	/* Step 1. Fetch the LDB record */
+	ldb_dn = ldb_dn_new(mem_ctx, ldb_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,
+			 recipient_attrs, NULL);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL);
+
+	/* Step 2. 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, res->msgs[0], ulPropTag, MId);
+		if (!data) {
+			ulPropTag &= 0xFFFF0000;
+			ulPropTag += 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 table
+   record.
+
+   \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 dwFlags flags controlling whether strings should be unicode
+   encoded or not
+   \param permEntryID pointer to the current record Permanent
+   EntryID
+   \param parentPermEntryID pointer to the parent record Permanent
+   EntryID
+   \param msg pointer to the LDB message for current record
+   \param child boolean value specifying whether current record is
+   root or child within containers hierarchy
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_table_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
+						  struct SRow *aRow, uint32_t dwFlags,
+						  struct PermanentEntryID *permEntryID,
+						  struct PermanentEntryID *parentPermEntryID,
+						  struct ldb_message *msg, bool child)
+{
+	enum MAPISTATUS			retval;
+	struct SPropTagArray		*SPropTagArray;
+	struct SPropValue		lpProps;
+	uint32_t			i;
+	uint32_t			containerID = 0;
+	const char			*dn = NULL;
+
+	/* Step 1. Build the array of properties to fetch and map */
+	if (child == false) {
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+						  PR_ENTRYID,
+						  PR_CONTAINER_FLAGS,
+						  PR_DEPTH,
+						  PR_EMS_AB_CONTAINERID,
+						  ((dwFlags & NspiUnicodeStrings) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME),
+						  PR_EMS_AB_IS_MASTER);
+	} else {
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x7,
+						  PR_ENTRYID,
+						  PR_CONTAINER_FLAGS,
+						  PR_DEPTH,
+						  PR_EMS_AB_CONTAINERID,
+						  ((dwFlags & NspiUnicodeStrings) ? PR_DISPLAY_NAME_UNICODE : PR_DISPLAY_NAME),
+						  PR_EMS_AB_IS_MASTER,
+						  PR_EMS_AB_PARENT_ENTRYID);
+	}
+
+	/* Step 2. Allocate SPropValue array and update SRow cValues field */
+	aRow->ulAdrEntryPad = 0x0;
+	aRow->cValues = 0x0;
+	aRow->lpProps = talloc_zero(mem_ctx, struct SPropValue);
+
+	/* Step 3. Global Address List or real container */
+	if (!msg) {
+		/* Global Address List record is constant */
+		for (i = 0; i < SPropTagArray->cValues; i++) {
+			lpProps.ulPropTag = SPropTagArray->aulPropTag[i];
+			lpProps.dwAlignPad = 0x0;
+
+			switch (SPropTagArray->aulPropTag[i]) {
+			case PR_ENTRYID:
+				emsabp_PermanentEntryID_to_Binary_r(mem_ctx, permEntryID, &(lpProps.value.bin));
+				break;
+			case PR_CONTAINER_FLAGS:
+				lpProps.value.l =  AB_RECIPIENTS | AB_UNMODIFIABLE;
+				break;
+			case PR_DEPTH:
+				lpProps.value.l = 0x0;
+				break;
+			case PR_EMS_AB_CONTAINERID:
+				lpProps.value.l = 0x0;
+				break;
+			case PR_DISPLAY_NAME:
+				lpProps.value.lpszA = NULL;
+				break;
+			case PR_DISPLAY_NAME_UNICODE:
+				lpProps.value.lpszW = NULL;
+				break;
+			case PR_EMS_AB_IS_MASTER:
+				lpProps.value.b = false;
+				break;
+			default:
+				break;
+			}
+			SRow_addprop(aRow, lpProps);
+			/* SRow_addprop internals overwrite with MAPI_E_NOT_FOUND when data is NULL */
+			if (SPropTagArray->aulPropTag[i] == PR_DISPLAY_NAME || 
+			    SPropTagArray->aulPropTag[i] == PR_DISPLAY_NAME_UNICODE) {
+				aRow->lpProps[aRow->cValues - 1].value.lpszA = NULL;
+				aRow->lpProps[aRow->cValues - 1].value.lpszW = NULL;
+			}
+		}
+	} else {
+		for (i = 0; i < SPropTagArray->cValues; i++) {
+			lpProps.ulPropTag = SPropTagArray->aulPropTag[i];
+			lpProps.dwAlignPad = 0x0;
+
+			switch (SPropTagArray->aulPropTag[i]) {
+			case PR_ENTRYID:
+				emsabp_PermanentEntryID_to_Binary_r(mem_ctx, permEntryID, &(lpProps.value.bin));
+				break;
+			case PR_CONTAINER_FLAGS:
+				switch (child) {
+				case true:
+					lpProps.value.l = AB_RECIPIENTS | AB_SUBCONTAINERS | AB_UNMODIFIABLE;
+					break;
+				case false:
+					lpProps.value.l = AB_RECIPIENTS | AB_UNMODIFIABLE;
+				}
+				break;
+			case PR_DEPTH:
+				switch (child) {
+				case true:
+					lpProps.value.l = 0x1;
+					break;
+				case false:
+					lpProps.value.l = 0x0;
+					break;
+				}
+				break;
+			case PR_EMS_AB_CONTAINERID:
+				dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL);
+				retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &containerID);
+				if (retval) {
+					retval = emsabp_tdb_insert(emsabp_ctx->tdb_ctx, dn);
+					OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+					retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &containerID);
+					OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+				}
+				lpProps.value.l = containerID;
+				break;
+			case PR_DISPLAY_NAME:
+				lpProps.value.lpszA = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "displayName", NULL));
+				if (!lpProps.value.lpszA) {
+					lpProps.ulPropTag &= 0xFFFF0000;
+					lpProps.ulPropTag += PT_ERROR;
+				}
+				break;
+			case PR_DISPLAY_NAME_UNICODE:
+				lpProps.value.lpszW = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "displayName", NULL));
+				if (!lpProps.value.lpszW) {
+					lpProps.ulPropTag &= 0xFFFF0000;
+					lpProps.ulPropTag += PT_ERROR;
+				}
+				break;
+			case PR_EMS_AB_IS_MASTER:
+				/* FIXME: harcoded value - no load balancing */
+				lpProps.value.l = 0x0;
+				break;
+			case PR_EMS_AB_PARENT_ENTRYID:
+				emsabp_PermanentEntryID_to_Binary_r(mem_ctx, parentPermEntryID, &lpProps.value.bin);
+				break;
+			default:
+				break;
+			}
+			SRow_addprop(aRow, lpProps);
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve and build the HierarchyTable requested by
+   GetSpecialTable NSPI call
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param dwFlags flags controlling whether strings should be UNICODE
+   or not
+   \param SRowSet pointer on pointer to the output SRowSet array
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_get_HierarchyTable(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
+						   uint32_t dwFlags, struct SRowSet **SRowSet)
+{
+	enum MAPISTATUS			retval;
+	struct SRow			*aRow;
+	struct PermanentEntryID		gal;
+	struct PermanentEntryID		parentPermEntryID;
+	struct PermanentEntryID		permEntryID;
+	enum ldb_scope			scope = LDB_SCOPE_SUBTREE;
+	struct ldb_request		*req;
+	struct ldb_result		*res = NULL;
+	char				*ldb_filter;
+	struct ldb_dn			*ldb_dn = NULL;
+	struct ldb_control		**controls;
+	const char * const		recipient_attrs[] = { "*", NULL };
+	const char			*control_strings[2] = { "server_sort:0:0:displayName", NULL };
+	const char			*addressBookRoots;
+	int				ret;
+	uint32_t			aRow_idx;
+	uint32_t			i;
+
+	/* Step 1. Build the 'Global Address List' object using PermanentEntryID */
+	aRow = talloc_zero(mem_ctx, struct SRow);
+	OPENCHANGE_RETVAL_IF(!aRow, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+	aRow_idx = 0;
+
+	retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, NULL, &gal);
+	OPENCHANGE_RETVAL_IF(retval, retval, aRow);
+
+	retval = emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &gal, NULL, NULL, false);
+	aRow_idx++;
+
+	/* Step 2. Retrieve the object pointed by addressBookRoots attribute: 'All Address Lists' */
+	ldb_filter = talloc_strdup(emsabp_ctx->mem_ctx, "(addressBookRoots=*)");
+	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
+			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
+			 scope, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+	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);
+	talloc_free(res);
+
+	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, addressBookRoots);
+	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, 
+			 scope, recipient_attrs, NULL);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, aRow);
+
+	aRow = talloc_realloc(mem_ctx, aRow, struct SRow, aRow_idx + 1);
+	retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, res->msgs[0], &parentPermEntryID);
+	emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &parentPermEntryID, NULL, res->msgs[0], false);
+	aRow_idx++;
+	talloc_free(res);
+
+	/* Step 3. Retrieve 'All Address Lists' subcontainers */
+	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,
+				   ldb_dn, LDB_SCOPE_SUBTREE, "(purportedSearch=*)",
+				   recipient_attrs, controls, res, ldb_search_default_callback, NULL);
+
+	if (ret != LDB_SUCCESS) {
+		talloc_free(res);
+		OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_CORRUPT_STORE, aRow);
+	}
+
+	ret = ldb_request(emsabp_ctx->conf_ctx, req);
+	if (ret == LDB_SUCCESS) {
+		ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+	}
+	talloc_free(req);
+	
+	if (ret != LDB_SUCCESS || !res->count) {
+		talloc_free(res);
+		OPENCHANGE_RETVAL_IF(1, MAPI_E_CORRUPT_STORE, aRow);
+	}
+
+	aRow = talloc_realloc(mem_ctx, aRow, struct SRow, aRow_idx + res->count + 1);
+
+	for (i = 0; res->msgs[i]; i++) {
+		retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_CONTAINER, res->msgs[i], &permEntryID);
+		emsabp_table_fetch_attrs(mem_ctx, emsabp_ctx, &aRow[aRow_idx], dwFlags, &permEntryID, &parentPermEntryID, res->msgs[i], true);
+		talloc_free(permEntryID.dn);
+		memset(&permEntryID, 0, sizeof (permEntryID));
+		aRow_idx++;
+	}
+	talloc_free(res);
+	talloc_free(parentPermEntryID.dn);
+
+	/* Step 4. Build output SRowSet */
+	SRowSet[0]->cRows = aRow_idx;
+	SRowSet[0]->aRow = aRow;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve and build the CreationTemplates Table requested
+   by GetSpecialTable NSPI call
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param dwFlags flags controlling whether strings should be UNICODE
+   or not
+   \param SRowSet pointer on pointer to the output SRowSet array
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_CORRUPT_STORE 
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_get_CreationTemplatesTable(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
+							   uint32_t dwFlags, struct SRowSet **SRowSet)
+{
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Search Active Directory given input search criterias. The
+   function associates for each records returned by the search a
+   unique session Minimal Entry ID and a LDB message.
+
+   \param mem_ctx pointer to the memory context
+   \param emsabp_ctx pointer to the EMSABP context
+   \param MIds pointer to the list of MIds the function returns
+   \param Restriction pointer to restriction rules to apply to the
+   search
+   \param pStat pointer the STAT structure associated to the search
+   param limit the limit number of results the function can return
+
+   \note SortTypePhoneticDisplayName sort type is currently not supported.
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_search(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
+				       struct SPropTagArray *MIds, struct Restriction_r *restriction,
+				       struct STAT *pStat, uint32_t limit)
+{
+	enum MAPISTATUS			retval;
+	struct ldb_result		*res = NULL;
+	struct PropertyRestriction_r	*res_prop = NULL;
+	const char			*recipient = NULL;
+	const char * const		recipient_attrs[] = { "*", NULL };
+	char				*ldb_filter;
+	int				ret;
+	uint32_t			i;
+	const char			*dn;
+
+	/* Step 0. Sanity Checks (MS-NSPI Server Processing Rules) */
+	if (pStat->SortType == SortTypePhoneticDisplayName) {
+		return MAPI_E_CALL_FAILED;
+	}
+
+	if (((pStat->SortType == SortTypeDisplayName) || (pStat->SortType == SortTypePhoneticDisplayName)) &&
+	    (pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, pStat->ContainerID) == false))) {
+		return MAPI_E_INVALID_BOOKMARK;
+	}
+
+	if (restriction && (pStat->SortType != SortTypeDisplayName) && 
+	    (pStat->SortType != SortTypePhoneticDisplayName)) {
+		return MAPI_E_CALL_FAILED;
+	}
+
+	/* Step 1. Apply restriction and retrieve results from AD */
+	if (restriction) {
+		/* FIXME: We only support RES_PROPERTY restriction */
+		if ((uint32_t)restriction->rt != RES_PROPERTY) {
+			return MAPI_E_TOO_COMPLEX;
+		}
+
+		/* FIXME: We only support PR_ANR */
+		res_prop = (struct PropertyRestriction_r *)&(restriction->res.resProperty);
+		if ((res_prop->ulPropTag != PR_ANR) && (res_prop->ulPropTag != PR_ANR_UNICODE)) {
+			return MAPI_E_NO_SUPPORT;
+		}
+		
+		recipient = (res_prop->ulPropTag == PR_ANR) ?
+			res_prop->lpProp->value.lpszA :
+			res_prop->lpProp->value.lpszW;
+
+		ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "(&(objectClass=user)(sAMAccountName=*%s*)(!(objectClass=computer)))", recipient);
+		ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res,
+				 ldb_get_default_basedn(emsabp_ctx->users_ctx),
+				 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
+		talloc_free(ldb_filter);
+
+		if (ret != LDB_SUCCESS || !res->count) {
+			return MAPI_E_NOT_FOUND;
+		}
+	} else {
+		/* FIXME Check restriction == NULL */
+	}
+
+	if (limit && res->count > limit) {
+		return MAPI_E_TABLE_TOO_BIG;
+	}
+
+	MIds->aulPropTag = 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]);
+		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]));
+			OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+		}
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Search for a given DN within AD and return the associated
+   LDB message.
+
+   \param emsabp_ctx pointer to the EMSABP context
+   \param dn pointer to the DN string to search for
+   \param ldb_res pointer on pointer to the LDB message returned by
+   the function
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_search_dn(struct emsabp_context *emsabp_ctx, const char *dn, 
+					  struct ldb_message **ldb_res)
+{
+	struct ldb_dn		*ldb_dn = NULL;
+	struct ldb_result	*res = NULL;
+	const char * const	recipient_attrs[] = { "*", NULL };
+	int			ret;
+
+	/* Sanity Checks */
+	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);
+	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,
+			 LDB_SCOPE_BASE, recipient_attrs, NULL);
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL);
+
+	*ldb_res = res->msgs[0];
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Search for a given AD record given its legacyDN parameter
+   and return the associated LDB message.
+
+   \param emsabp_ctx pointer to the EMSABP context
+   \param legacyDN pointer to the legacyDN attribute value to lookup
+   \param ldb_res pointer on pointer to the LDB message returned by 
+   the function
+
+   \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)
+{
+	char			*ldb_filter;
+	const char * const	recipient_attrs[] = { "*", NULL };
+	int			ret;
+	struct ldb_result	*res = NULL;
+
+	/* Sanity Checks */
+	OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL);
+
+	ldb_filter = talloc_asprintf(emsabp_ctx->mem_ctx, "(legacyExchangeDN=%s)", legacyDN);
+	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
+			 ldb_get_default_basedn(emsabp_ctx->conf_ctx), 
+			 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
+	talloc_free(ldb_filter);
+
+	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, NULL);
+
+	*ldb_res = res->msgs[0];
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp_property.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,147 @@
+/*
+   OpenChange Server implementation.
+
+   EMSABP: Address Book Provider implementation
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file emsabp_property.c
+
+   \brief Property Tag to AD attributes mapping
+ */
+
+#include "dcesrv_exchange_nsp.h"
+
+struct emsabp_property {
+	uint32_t	ulPropTag;
+	const char	*attribute;
+	bool		ref;
+	const char	*ref_attr;
+};
+
+static const struct emsabp_property emsabp_property[] = {
+	{ PR_ACCOUNT,				"sAMAccountName",	false,	NULL			},
+	{ PR_COMPANY_NAME,			"company",		false,	NULL			},
+	{ PR_DISPLAY_NAME,			"displayName",		false,	NULL			},
+	{ 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_NETWORK_ADDRESS,		"networkAddress",	false,	NULL			},
+	{ PR_TITLE,				"personalTitle",	false,	NULL			},
+	{ 0,					NULL,			false,	NULL			}
+};
+
+
+/**
+   \details Return the AD attribute name associated to a property tag
+
+   \param ulPropTag the property tag to lookup
+
+   \return valid pointer to the attribute name on success, otherwise
+   NULL
+ */
+_PUBLIC_ const char *emsabp_property_get_attribute(uint32_t ulPropTag)
+{
+	int		i;
+
+	/* if ulPropTag type is PT_UNICODE, turn it to PT_STRING8 */
+	if ((ulPropTag & 0xFFFF) == PT_UNICODE) {
+		ulPropTag &= 0xFFFF0000;
+		ulPropTag += PT_STRING8;
+	}
+
+	for (i = 0; emsabp_property[i].attribute; i++) {
+		if (ulPropTag == emsabp_property[i].ulPropTag) {
+			return emsabp_property[i].attribute;
+		}
+	}
+
+	return NULL;
+}
+
+
+/**
+   \details Return the property tag associated to AD attribute name
+
+   \param attribute the AD attribute name to lookup
+
+   \return property tag value on success, otherwise PT_ERROR
+ */
+_PUBLIC_ uint32_t emsabp_property_get_ulPropTag(const char *attribute)
+{
+	int		i;
+
+	if (!attribute) return PT_ERROR;
+
+	for (i = 0; emsabp_property[i].attribute; i++) {
+		if (!strcmp(attribute, emsabp_property[i].attribute)) {
+			return emsabp_property[i].ulPropTag;
+		}
+	}
+
+	return PT_ERROR;
+}
+
+
+/**
+   \details Returns whether the given attribute's value references
+   another AD record
+
+   \param ulPropTag the property tag to lookup
+
+   \return 1 if the attribute is a reference, 0 if not and -1 if an
+   error occurred.
+ */
+_PUBLIC_ int emsabp_property_is_ref(uint32_t ulPropTag)
+{
+	int		i;
+
+	if (!ulPropTag) return -1;
+
+	for (i = 0; emsabp_property[i].attribute; i++) {
+		if (ulPropTag == emsabp_property[i].ulPropTag) {
+			return (emsabp_property[i].ref == true) ? 1 : 0;
+		}
+	}
+
+	return -1;
+}
+
+
+/**
+   \details Returns the reference attr for a given attribute
+
+   \param ulPropTag property tag to lookup
+
+   \return pointer to a valid reference attribute on success,
+   otherwise NULL
+ */
+_PUBLIC_ const char *emsabp_property_get_ref_attr(uint32_t ulPropTag)
+{
+	int		i;
+
+	if (!ulPropTag) return NULL;
+
+	for (i = 0; emsabp_property[i].attribute; i++) {
+		if (ulPropTag == emsabp_property[i].ulPropTag) {
+			return emsabp_property[i].ref_attr;
+		}
+	}
+
+	return NULL;
+}

Added: trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/nspi/emsabp_tdb.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,367 @@
+/*
+   OpenChange Server implementation.
+
+   EMSABP: Address Book Provider implementation
+
+   Copyright (C) Julien Kerihuel 2006-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/>.
+*/
+
+/**
+   \file emsabp_tdb.c
+
+   \brief EMSABP TDB database API
+*/
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_nsp.h"
+#include <util/debug.h>
+
+/**
+   \details Open EMSABP TDB database
+
+   \param mem_ctx pointer to the memory context
+   \param lp_ctx pointer to the loadparm context
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ TDB_CONTEXT *emsabp_tdb_init(TALLOC_CTX *mem_ctx, 
+				      struct loadparm_context *lp_ctx)
+{
+	enum MAPISTATUS			retval;
+	TDB_CONTEXT			*tdb_ctx;
+	TDB_DATA			key;
+	TDB_DATA			dbuf;
+	int				ret;
+
+	/* Sanity checks */
+	if (!lp_ctx) return NULL;
+
+	/* Step 0. Retrieve a TDB context pointer on the emsabp_tdb database */
+	tdb_ctx = mapiproxy_server_emsabp_tdb_init(lp_ctx);
+	if (!tdb_ctx) return NULL;
+
+	/* Step 1. If EMSABP_TDB_DATA_REC doesn't exist, create it */
+	retval = emsabp_tdb_fetch(tdb_ctx, EMSABP_TDB_DATA_REC, &dbuf);
+	if (retval == MAPI_E_NOT_FOUND) {
+		key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC;
+		key.dsize = strlen(EMSABP_TDB_DATA_REC);
+
+		dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", EMSABP_TDB_MID_START);
+		dbuf.dsize = strlen((const char *)dbuf.dptr);
+
+		ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT);
+		if (ret == -1) {
+			DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__,
+				  EMSABP_TDB_DATA_REC, tdb_errorstr(tdb_ctx)));
+			tdb_close(tdb_ctx);
+			return NULL;
+		}
+	} else {
+		free (dbuf.dptr);
+	}
+
+	return tdb_ctx;
+}
+
+
+/**
+   \details Initialize a temporary (on-memory) TDB database. This
+   database is used to store temporary MId used within a session
+   lifetime.
+
+   \param mem_ctx pointer to the memory context
+
+   \return Allocated TDB context on success, otherwise NULL
+ */
+_PUBLIC_ TDB_CONTEXT *emsabp_tdb_init_tmp(TALLOC_CTX *mem_ctx)
+{
+	TDB_CONTEXT	*tdb_ctx;
+	TDB_DATA       	key;
+	TDB_DATA       	dbuf;
+	int	       	ret;
+
+	/* Step 0. Initialize the temporary TDB database */
+	tdb_ctx = tdb_open(NULL, 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0600);
+	
+	/* Step 1. Create EMSABP_TMP_TDB_DATA_REC record */
+	key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC;
+	key.dsize = strlen(EMSABP_TDB_DATA_REC);
+
+	dbuf.dptr = (unsigned char *) talloc_asprintf(mem_ctx, "0x%x", EMSABP_TDB_TMP_MID_START);
+	dbuf.dsize = strlen((const char *)dbuf.dptr);
+	
+	ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT);
+	if (ret == -1) {
+		DEBUG(3, ("[%s:%d]: Unable to create %s record: %s\n", __FUNCTION__, __LINE__,
+			  EMSABP_TDB_DATA_REC, tdb_errorstr(tdb_ctx)));
+		tdb_close(tdb_ctx);
+		return NULL;
+	} 
+	
+	return tdb_ctx;
+}
+
+
+/**
+   \details Close EMSABP TDB database
+
+   \return MAPI_E_SUCCESS on success, otherwise
+   MAPI_E_INVALID_PARAMETER
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_tdb_close(TDB_CONTEXT *tdb_ctx)
+{
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_INVALID_PARAMETER, NULL);
+
+	tdb_close(tdb_ctx);
+	DEBUG(0, ("TDB database closed\n"));
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Fetch an element within a TDB database given its key
+
+   \param keyname pointer to the TDB key to fetch
+   \param result pointer on TDB results
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_FOUND
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch(TDB_CONTEXT *tdb_ctx,
+					  const char *keyname,
+					  TDB_DATA *result)
+{
+	TDB_DATA	key;
+	TDB_DATA	dbuf;
+	size_t		keylen;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL);
+
+	keylen = strlen(keyname);
+	OPENCHANGE_RETVAL_IF(!keylen, MAPI_E_INVALID_PARAMETER, NULL);
+
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = keylen;
+
+	dbuf = tdb_fetch(tdb_ctx, key);
+	OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, NULL);
+
+	if (!result) {
+		free (dbuf.dptr);
+	} else {
+		*result = dbuf;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Retrieve the Minimal EntryID associated to a given DN
+
+   \param tdb_ctx pointer to the EMSABP TDB context
+   \param keyname pointer to the TDB key to search for
+   \param MId pointer on the integer the function returns
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_MId(TDB_CONTEXT *tdb_ctx,
+					      const char *keyname,
+					      uint32_t *MId)
+{
+	TDB_DATA	key;
+	TDB_DATA	dbuf;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!MId, MAPI_E_INVALID_PARAMETER, NULL);
+
+	key.dptr = (unsigned char *) keyname;
+	key.dsize = strlen(keyname);
+
+	dbuf = tdb_fetch(tdb_ctx, key);
+	OPENCHANGE_RETVAL_IF(!dbuf.dptr, MAPI_E_NOT_FOUND, NULL);
+	OPENCHANGE_RETVAL_IF(!dbuf.dsize, MAPI_E_NOT_FOUND, NULL);
+
+	*MId = strtol((const char *)dbuf.dptr, NULL, 16);
+	free(dbuf.dptr);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+static int emsabp_tdb_traverse_MId(TDB_CONTEXT *tdb_ctx, 
+				   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;
+
+	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;
+
+	return 0;
+}
+
+
+/**
+   \details Traverse the EMSABP TDB database and look for the input
+   MId
+
+   \param tdb_ctx pointer to the EMSABP TDB context
+   \param MId MID to lookup
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool emsabp_tdb_lookup_MId(TDB_CONTEXT *tdb_ctx,
+				    uint32_t MId)
+{
+	int	ret;
+
+	ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId, (void *)&MId);
+
+	return (ret == 1) ? true : false;
+}
+
+
+static int emsabp_tdb_traverse_MId_DN(TDB_CONTEXT *tdb_ctx,
+				      TDB_DATA key, TDB_DATA dbuf,
+				      void *state)
+{
+	char			*MId;
+	uint32_t		value;
+	struct emsabp_MId	*emsabp_MId = (struct emsabp_MId *) state;
+
+	if (key.dptr && strcmp((const char *)key.dptr, EMSABP_TDB_DATA_REC)) {
+		MId = talloc_strndup(emsabp_MId, (char *)dbuf.dptr, dbuf.dsize);
+		value = strtol((const char *)MId, NULL, 16);
+		talloc_free(MId);
+		if (value == emsabp_MId->MId) {
+			emsabp_MId->dn = talloc_strndup(emsabp_MId, (char *)key.dptr, key.dsize);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+/**
+   \details Traverse the EMSABP TDB and fetch the DN associated with
+   the MId
+
+   \param mem_ctx pointer to the memory context
+   \param tdb_ctx pointer to the EMSABP TDB context
+   \param MId MID to search
+   \param dn pointer on pointer to the dn to return
+
+   \return MAPI_E_SUCCESS on success, otherwise false
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId(TALLOC_CTX *mem_ctx,
+						      TDB_CONTEXT *tdb_ctx,
+						      uint32_t MId,
+						      char **dn)
+{
+	int			ret;
+	struct emsabp_MId	*emsabp_MId;
+	
+	emsabp_MId = talloc_zero(mem_ctx, struct emsabp_MId);
+	emsabp_MId->dn = NULL;
+	emsabp_MId->MId = MId;
+	
+	ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId_DN, (void *)emsabp_MId);
+	if (ret > -1 && emsabp_MId->dn) {
+		*dn = talloc_strdup(mem_ctx, emsabp_MId->dn);
+		talloc_free(emsabp_MId);
+		return MAPI_E_SUCCESS;
+	}
+
+	*dn = NULL;
+	talloc_free(emsabp_MId);
+
+	return MAPI_E_NOT_FOUND;
+}
+
+
+/**
+   \details Insert an element into TDB database
+
+   \param tdb_ctx pointer to the EMSABP TDB context
+   \param keyname pointer to the TDB key name string
+
+   \return MAPI_E_SUCCESS on success, otherwise MAPI error
+ */
+_PUBLIC_ enum MAPISTATUS emsabp_tdb_insert(TDB_CONTEXT *tdb_ctx,
+					   const char *keyname)
+{
+	enum MAPISTATUS	retval;
+	TALLOC_CTX	*mem_ctx;
+	TDB_DATA	key;
+	TDB_DATA	dbuf;
+	int		index;
+	int		ret;
+
+	/* Sanity checks */
+	OPENCHANGE_RETVAL_IF(!tdb_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+	OPENCHANGE_RETVAL_IF(!keyname, MAPI_E_INVALID_PARAMETER, NULL);
+
+	mem_ctx = talloc_named(NULL, 0, "emsabp_tdb_insert");
+	OPENCHANGE_RETVAL_IF(!mem_ctx, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
+
+	/* Step 1. Check if the record already exists */
+	retval = emsabp_tdb_fetch(tdb_ctx, keyname, &dbuf);
+	OPENCHANGE_RETVAL_IF(!retval, ecExiting, mem_ctx);
+
+	/* Step 2. Retrieve the latest TDB data value inserted */
+	retval = emsabp_tdb_fetch(tdb_ctx, EMSABP_TDB_DATA_REC, &dbuf);
+	OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+	index = strtol((const char *)dbuf.dptr, NULL, 16);
+	index += 1;
+
+	free(dbuf.dptr);
+
+	dbuf.dptr = (unsigned char *)talloc_asprintf(mem_ctx, "0x%x", index);
+	dbuf.dsize = strlen((const char *)dbuf.dptr);
+
+	/* Step 3. Insert the new record */
+	key.dptr = (unsigned char *)keyname;
+	key.dsize = strlen(keyname);
+	
+	ret = tdb_store(tdb_ctx, key, dbuf, TDB_INSERT);
+	OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	/* Step 4. Update Data record */
+	key.dptr = (unsigned char *) EMSABP_TDB_DATA_REC;
+	key.dsize = strlen((const char *)key.dptr);
+
+	ret = tdb_store(tdb_ctx, key, dbuf, TDB_MODIFY);
+	OPENCHANGE_RETVAL_IF(ret == -1, MAPI_E_CORRUPT_STORE, mem_ctx);
+
+	talloc_free(mem_ctx);
+
+	return MAPI_E_SUCCESS;
+}

Added: trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c
===================================================================
--- trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,229 @@
+/*
+   MAPI Proxy - Exchange RFR Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+/**
+   \file dcesrv_exchange_rfr.c
+
+   \brief OpenChange RFR Server implementation
+ */
+
+#include "mapiproxy/dcesrv_mapiproxy.h"
+#include "dcesrv_exchange_ds_rfr.h"
+
+/**
+   \details exchange_ds_rfr RfrGetNewDSA (0x0) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the RfrGetNewDSA request data
+
+   \note We incorrectly assume input pUserDN is correct and available,
+   but it is OK for now.
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call,
+					   TALLOC_CTX *mem_ctx,
+					   struct RfrGetNewDSA *r)
+{
+	const char		*netbiosname = NULL;
+	const char		*realm = NULL;
+	char			*fqdn = NULL;
+
+	DEBUG(5, ("exchange_ds_rfr: RfrGetNewDSA (0x0)\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"));
+
+		r->out.ppszUnused = NULL;
+		r->out.ppszServer = NULL;
+		r->out.result = MAPI_E_LOGON_FAILED;
+		return MAPI_E_LOGON_FAILED;
+	}
+
+	/* Step 1. We don't have load-balancing support yet, just return Samba FQDN name */
+	netbiosname = lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
+	realm = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+	if (!netbiosname || !realm) {
+		r->out.ppszUnused = NULL;
+		r->out.ppszServer = NULL;
+		r->out.result = MAPI_E_NO_SUPPORT;
+		return MAPI_E_NO_SUPPORT;			
+	}
+
+	fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm);
+	r->out.ppszUnused = NULL;
+	r->out.ppszServer = talloc_array(mem_ctx, const char *, 2);
+	r->out.ppszServer[0] = strlower_talloc(mem_ctx, fqdn);
+	r->out.ppszServer[1] = NULL;
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r pointer to the RfrGetFQDNFromLegacyDN request data
+
+   \return MAPI_E_SUCCESS on success
+ */
+static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call,
+						     TALLOC_CTX *mem_ctx,
+						     struct RfrGetFQDNFromLegacyDN *r)
+{
+	char		*fqdn;
+	const char	*netbiosname;
+	const char	*realm;
+
+	DEBUG(3, ("exchange_ds_rfr: RfrGetFQDNFromLegacyDN (0x1)\n"));
+
+	if (!NTLM_AUTH_IS_OK(dce_call)) {
+		DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
+
+	failure:
+		r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2);
+		r->out.ppszServerFQDN[0] = NULL;
+		r->out.result = MAPI_E_LOGON_FAILED;
+		return MAPI_E_LOGON_FAILED;
+	}
+
+	netbiosname = lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
+	realm = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+	if (!netbiosname || !realm) {
+		goto failure;
+	}
+
+	fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm);
+	r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2);
+	r->out.ppszServerFQDN[0] = strlower_talloc(mem_ctx, fqdn);
+	talloc_free(fqdn);
+	r->out.result = MAPI_E_SUCCESS;
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+   \details Dispatch incoming RFR call to the correct OpenChange server function
+
+   \param dce_call pointer to the session context
+   \param mem_ctx pointer to the memory context
+   \param r generic pointer on RFR data
+   \param mapiproxy pointer to the mapiproxy structure controlling
+   mapiproxy behavior
+
+   \return NT_STATUS_OK
+ */
+static NTSTATUS dcesrv_exchange_ds_rfr_dispatch(struct dcesrv_call_state *dce_call,
+						TALLOC_CTX *mem_ctx,
+						void *r, struct mapiproxy *mapiproxy)
+{
+	enum MAPISTATUS				retval;
+	const struct ndr_interface_table	*table;
+	uint16_t				opnum;
+
+	table = (const struct ndr_interface_table *) dce_call->context->iface->private;
+	opnum = dce_call->pkt.u.request.opnum;
+
+	/* Sanity checks */
+	if (!table) return NT_STATUS_UNSUCCESSFUL;
+	if (table->name && strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) return NT_STATUS_UNSUCCESSFUL;
+
+	switch (opnum) {
+	case NDR_RFRGETNEWDSA:
+		retval = dcesrv_RfrGetNewDSA(dce_call, mem_ctx, (struct RfrGetNewDSA *)r);
+		break;
+	case NDR_RFRGETFQDNFROMLEGACYDN:
+		retval = dcesrv_RfrGetFQDNFromLegacyDN(dce_call, mem_ctx, (struct RfrGetFQDNFromLegacyDN *)r);
+		break;
+	}
+
+
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Initialize the RFR OpenChange server
+
+   \param dce_ctx pointer to the server context
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS dcesrv_exchange_ds_rfr_init(struct dcesrv_context *dce_ctx)
+{
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Terminate the RFR connection
+
+   \param server_id reference to the server identifier structure
+   \param context_id the connection context identifier
+
+   \return NT_STATUS_OK on success
+ */
+static NTSTATUS dcesrv_exchange_ds_rfr_unbind(struct server_id server_id, 
+					      uint32_t context_id)
+{
+	return NT_STATUS_OK;
+}
+
+
+/**
+   \details Entry point for the default OpenChange RFR server
+
+   \return NT_STATUS_OK on success, otherwise NTSTATUS error
+ */
+NTSTATUS samba_init_module(void)
+{
+	struct mapiproxy_module	server;
+	NTSTATUS		ret;
+
+	/* Fill in our name */
+	server.name = "exchange_ds_rfr";
+	server.status = MAPIPROXY_DEFAULT;
+	server.description = "OpenChange RFR server";
+	server.endpoint = "exchange_ds_rfr";
+
+	/* Fill in all the operations */
+	server.init = dcesrv_exchange_ds_rfr_init;
+	server.unbind = dcesrv_exchange_ds_rfr_unbind;
+	server.dispatch = dcesrv_exchange_ds_rfr_dispatch;
+	server.push = NULL;
+	server.pull = NULL;
+	server.ndr_pull = NULL;
+
+	/* Register ourselves with the MAPIPROXY server subsystem */
+	ret = mapiproxy_server_register(&server);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0, ("Failed to register the 'exchange_ds_rfr' default mapiproxy server!\n"));
+		return ret;
+	}
+
+	return ret;
+}

Added: trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.h
===================================================================
--- trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.h	                        (rev 0)
+++ trunk/openchange/mapiproxy/servers/default/rfr/dcesrv_exchange_ds_rfr.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,44 @@
+/*
+   MAPI Proxy - Exchange RFR Server
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 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/>.
+ */
+
+#ifndef	__DCESRV_EXCHANGE_DS_RFR_H
+#define	__DCESRV_EXCHANGE_DS_RFR_H
+
+#include <mapiproxy/libmapiproxy/libmapiproxy.h>
+#include <util/debug.h>
+
+#ifndef	__BEGIN_DECLS
+#ifdef	__cplusplus
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+
+NTSTATUS	samba_init_module(void);
+
+__END_DECLS
+
+#endif	/* __DCESRV_EXCHANGE_DS_RFR_H */

Added: trunk/openchange/missing
===================================================================
--- trunk/openchange/missing	                        (rev 0)
+++ trunk/openchange/missing	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# 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 2, 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:


Property changes on: trunk/openchange/missing
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/ndr_mapi.c
===================================================================
--- trunk/openchange/ndr_mapi.c	                        (rev 0)
+++ trunk/openchange/ndr_mapi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,657 @@
+/* 
+   OpenChange implementation.
+
+   libndr mapi support
+
+   Copyright (C) Julien Kerihuel 2005-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/libmapi.h>
+#include <ndr.h>
+#include <gen_ndr/ndr_exchange.h>
+
+
+static void obfuscate_data(uint8_t *data, uint32_t size, uint8_t salt)
+{
+	uint32_t i;
+
+	for (i=0; i<size; i++) {
+		data[i] ^= salt;
+	}
+}
+
+/*
+  print mapi_request / mapi_response structures
+ */
+
+void ndr_print_mapi_request(struct ndr_print *ndr, const char *name, const struct mapi_request *r)
+{
+	uint32_t	rlength;
+
+	rlength = r->mapi_len - r->length;
+
+	ndr_print_uint32(ndr, "mapi_len", r->mapi_len);
+	if (r->length && r->length > sizeof(uint16_t)) {
+		uint32_t cntr_mapi_req_0;
+
+		ndr_print_uint16(ndr, "length", r->length);
+		ndr->depth++;
+		for (cntr_mapi_req_0=0; r->mapi_req[cntr_mapi_req_0].opnum; cntr_mapi_req_0++) {
+			char	*idx_0 = NULL;
+			int	ret;
+
+			ret = asprintf(&idx_0, "[%u]", cntr_mapi_req_0);
+			if (ret != -1 && idx_0) {
+				ndr_print_EcDoRpc_MAPI_REQ(ndr, "mapi_request", &r->mapi_req[cntr_mapi_req_0]);
+				free(idx_0);
+			} 
+		}
+		ndr->depth--;
+	}
+
+	if (rlength) {
+		uint32_t i;
+
+		ndr->depth++;
+		ndr->print(ndr, "%-25s: (handles) number=%u", name, rlength / 4);
+		ndr->depth++;
+		for (i = 0; i < (rlength / 4); i++) {
+			ndr_print_uint32(ndr, "handle", r->handles[i]);
+		}
+		ndr->depth--;
+	}
+}
+
+void ndr_print_mapi_response(struct ndr_print *ndr, const char *name, const struct mapi_response *r)
+{
+	uint32_t	rlength;
+
+	rlength = r->mapi_len - r->length;
+
+	ndr->print(ndr, "%-25s: length=%u", name, r->length);
+	if (r->length && r->length > sizeof(uint16_t)) {
+		uint32_t cntr_mapi_repl_0;
+
+		ndr->print(ndr, "%s: ARRAY(%d)", name, r->length - 2);
+		ndr->depth++;
+		for (cntr_mapi_repl_0=0; r->mapi_repl[cntr_mapi_repl_0].opnum; cntr_mapi_repl_0++) {
+			ndr_print_EcDoRpc_MAPI_REPL(ndr, "mapi_repl", &r->mapi_repl[cntr_mapi_repl_0]);
+		}
+		ndr->depth--;
+	}
+
+	ndr->print(ndr, "%-25s: (handles) number=%u", name, rlength / 4);
+	
+	if (rlength) {
+		uint32_t i;
+
+		ndr->depth++;
+
+		for (i = 0; i < (rlength / 4); i++) {
+			ndr_print_uint32(ndr, "handle id", r->handles[i]);
+		}
+		ndr->depth--;
+	}
+}
+
+
+/*
+  push mapi_request / mapi_response onto the wire.  
+
+  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
+*/
+
+enum ndr_err_code ndr_push_mapi_request(struct ndr_push *ndr, int ndr_flags, const struct mapi_request *r)
+{
+	uint32_t		cntr_mapi_req_0;
+	uint32_t		count;
+
+	ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+	NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->length));
+
+	for (count = 0; ndr->offset < r->length - 2; count++) {
+		NDR_CHECK(ndr_push_EcDoRpc_MAPI_REQ(ndr, NDR_SCALARS, &r->mapi_req[count]));
+	}
+
+	count = (r->mapi_len - r->length) / sizeof(uint32_t);
+	for (cntr_mapi_req_0=0; cntr_mapi_req_0 < count; cntr_mapi_req_0++) {
+		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->handles[cntr_mapi_req_0]));
+	}
+
+	obfuscate_data(ndr->data, ndr->offset, 0xA5);
+
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_push_mapi_response(struct ndr_push *ndr, int ndr_flags, const struct mapi_response *r)
+{
+	uint32_t	cntr_mapi_repl_0;
+	uint32_t	count;
+
+	ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
+	NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->length));
+
+	if (r->length > sizeof (uint16_t)) {
+		for (count = 0; ndr->offset < r->length - 2; count++) {
+			NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL(ndr, NDR_SCALARS, &r->mapi_repl[count]));
+		}
+	}
+
+	count = (r->mapi_len - r->length) / sizeof (uint32_t);
+	for (cntr_mapi_repl_0 = 0; cntr_mapi_repl_0 <count; cntr_mapi_repl_0++) {
+		NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->handles[cntr_mapi_repl_0]));
+	}
+
+	obfuscate_data(ndr->data, ndr->alloc_size, 0xA5);
+
+	return NDR_ERR_SUCCESS;
+}
+
+/*
+  pull mapi_request / mapi_response from the wire
+*/
+
+enum ndr_err_code ndr_pull_mapi_request(struct ndr_pull *ndr, int ndr_flags, struct mapi_request *r)
+{
+	uint32_t length,count;
+	uint32_t cntr_mapi_req_0;
+	TALLOC_CTX *_mem_save_mapi_req_0;
+	TALLOC_CTX *_mem_save_handles_0;
+	struct ndr_pull *_ndr_mapi_req;
+
+	obfuscate_data(ndr->data, ndr->data_size, 0xA5);
+
+	if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+		length = ndr->data_size - ndr->offset;
+	} else {
+		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
+	}
+	r->mapi_len = length;
+
+	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length));
+
+	/* If length equals length field then skipping subcontext */
+	if (r->length > sizeof (uint16_t)) {
+		NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_req, 0, r->length - 2));
+		_mem_save_mapi_req_0 = NDR_PULL_GET_MEM_CTX(_ndr_mapi_req);
+		r->mapi_req = talloc_zero(_mem_save_mapi_req_0, struct EcDoRpc_MAPI_REQ);
+		for (cntr_mapi_req_0 = 0; _ndr_mapi_req->offset < _ndr_mapi_req->data_size - 2; cntr_mapi_req_0++) {
+			NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REQ(_ndr_mapi_req, NDR_SCALARS, &r->mapi_req[cntr_mapi_req_0]));
+			r->mapi_req = talloc_realloc(_mem_save_mapi_req_0, r->mapi_req, struct EcDoRpc_MAPI_REQ, cntr_mapi_req_0 + 2);
+		}
+		r->mapi_req = talloc_realloc(_mem_save_mapi_req_0, r->mapi_req, struct EcDoRpc_MAPI_REQ, cntr_mapi_req_0 + 2);
+		r->mapi_req[cntr_mapi_req_0].opnum = 0;
+		
+		if (_ndr_mapi_req->offset != r->length - 2) {
+			return NDR_ERR_BUFSIZE;
+		}
+		NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_req, 4, -1));
+	
+		_mem_save_handles_0 = NDR_PULL_GET_MEM_CTX(ndr);
+		count = (r->mapi_len - r->length) / sizeof(uint32_t);
+		r->handles = talloc_array(_mem_save_handles_0, uint32_t, count + 1);
+		for (cntr_mapi_req_0=0; cntr_mapi_req_0 < count; cntr_mapi_req_0++) {
+			NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->handles[cntr_mapi_req_0]));
+		}
+	} else {
+		r->handles = NULL;
+	}
+
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_mapi_response(struct ndr_pull *ndr, int ndr_flags, struct mapi_response *r)
+{
+	uint32_t length,count;
+	uint32_t cntr_mapi_repl_0;
+	TALLOC_CTX *_mem_save_mapi_repl_0;
+	TALLOC_CTX *_mem_save_handles_0;
+	struct ndr_pull *_ndr_mapi_repl;
+
+	obfuscate_data(ndr->data, ndr->data_size, 0xA5);
+
+	if (ndr->flags & LIBNDR_FLAG_REMAINING) {
+		length = ndr->data_size - ndr->offset;
+	} else {
+		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
+	}
+	r->mapi_len = length;
+
+	NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length));
+	
+	/* If length equals length field then skipping subcontext */
+	if (r->length > sizeof (uint16_t)) {
+		_mem_save_mapi_repl_0 = NDR_PULL_GET_MEM_CTX(ndr);
+		r->mapi_repl = talloc_array(_mem_save_mapi_repl_0, struct EcDoRpc_MAPI_REPL, 2);
+		NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_mapi_repl, 0, r->length - 2));
+		for (cntr_mapi_repl_0 = 0; _ndr_mapi_repl->offset < _ndr_mapi_repl->data_size - 2; cntr_mapi_repl_0++) {
+			NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL(_ndr_mapi_repl, NDR_SCALARS, &r->mapi_repl[cntr_mapi_repl_0]));
+			r->mapi_repl = talloc_realloc(_ndr_mapi_repl, r->mapi_repl, struct EcDoRpc_MAPI_REPL, cntr_mapi_repl_0 + 2);
+		}
+		r->mapi_repl[cntr_mapi_repl_0].opnum = 0;
+		NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_mapi_repl, 4, -1));
+		talloc_free(_ndr_mapi_repl);
+	}
+
+	_mem_save_handles_0 = NDR_PULL_GET_MEM_CTX(ndr);
+	count = (r->mapi_len - r->length) / sizeof(uint32_t);
+	NDR_PULL_ALLOC_N(ndr, r->handles, count + 1);
+
+	for (cntr_mapi_repl_0=0; cntr_mapi_repl_0 < count; cntr_mapi_repl_0++) {
+		NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->handles[cntr_mapi_repl_0]));
+	}
+	NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handles_0, LIBNDR_FLAG_REF_ALLOC);
+
+	return NDR_ERR_SUCCESS;
+}
+
+/*
+  We stop processing the IDL if MAPISTATUS is different from MAPI_E_SUCCESS
+ */
+
+_PUBLIC_ enum ndr_err_code ndr_push_EcDoRpc_MAPI_REPL(struct ndr_push *ndr, int ndr_flags, const struct EcDoRpc_MAPI_REPL *r)
+{
+	if (r->opnum != op_MAPI_Release)
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			NDR_CHECK(ndr_push_align(ndr, 8));
+			NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->opnum));
+			if ((r->opnum == op_MAPI_Notify) || (r->opnum == op_MAPI_Pending)) {
+				NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum));
+				NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));				
+			} else {
+				NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->handle_idx));
+				NDR_CHECK(ndr_push_MAPISTATUS(ndr, NDR_SCALARS, r->error_code));
+				if (r->error_code == MAPI_E_SUCCESS) {
+					NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->opnum));
+					NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));
+				}
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+			NDR_CHECK(ndr_push_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_BUFFERS, &r->u));
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_EcDoRpc_MAPI_REPL(struct ndr_pull *ndr, int ndr_flags, struct EcDoRpc_MAPI_REPL *r)
+{
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			NDR_CHECK(ndr_pull_align(ndr, 8));
+			NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->opnum));
+			if ((r->opnum == op_MAPI_Notify) || (r->opnum == op_MAPI_Pending)) {
+				NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum));
+				NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));
+			} else {
+				NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->handle_idx));
+				NDR_CHECK(ndr_pull_MAPISTATUS(ndr, NDR_SCALARS, &r->error_code));
+				if ( r->error_code == MAPI_E_SUCCESS) {
+					NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->opnum));
+					NDR_CHECK(ndr_pull_EcDoRpc_MAPI_REPL_UNION(ndr, NDR_SCALARS, &r->u));
+				}
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+			ndr->flags = _flags_save_STRUCT;
+		}
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+void ndr_print_EcDoRpc_MAPI_REPL(struct ndr_print *ndr, const char *name, const struct EcDoRpc_MAPI_REPL *r)
+{
+	ndr_print_struct(ndr, name, "EcDoRpc_MAPI_REPL");
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		ndr->depth++;
+		ndr_print_uint8(ndr, "opnum", r->opnum);
+		if ((r->opnum != op_MAPI_Notify) && (r->opnum != op_MAPI_Pending)) {
+			ndr_print_uint8(ndr, "handle_idx", r->handle_idx);
+			ndr_print_MAPISTATUS(ndr, "error_code", r->error_code);
+			if (r->error_code == MAPI_E_SUCCESS) {
+				ndr_print_set_switch_value(ndr, &r->u, r->opnum);
+				ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u);
+			}
+		} else {
+			ndr_print_set_switch_value(ndr, &r->u, r->opnum);
+			ndr_print_EcDoRpc_MAPI_REPL_UNION(ndr, "u", &r->u);
+		}
+		ndr->depth--;
+		ndr->flags = _flags_save_STRUCT;
+	}
+}
+
+/*
+  We need to pull QueryRows replies on our own:
+  If we have no results, do not push/pull the DATA_BLOB
+*/
+
+enum ndr_err_code ndr_push_QueryRows_repl(struct ndr_push *ndr, int ndr_flags, const struct QueryRows_repl *r)
+{
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			NDR_CHECK(ndr_push_align(ndr, 4));
+			NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->Origin));
+			NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->RowCount));
+
+			if (r->RowCount) {
+				uint32_t _flags_save_DATA_BLOB = ndr->flags;
+				ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
+				NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->RowData));
+				ndr->flags = _flags_save_DATA_BLOB;
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_QueryRows_repl(struct ndr_pull *ndr, int ndr_flags, struct QueryRows_repl *r)
+{
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			NDR_CHECK(ndr_pull_align(ndr, 4));
+			NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->Origin));
+			NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->RowCount));
+
+			if (r->RowCount)
+			{
+				uint32_t _flags_save_DATA_BLOB = ndr->flags;
+
+				ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING);
+				NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->RowData));
+				ndr->flags = _flags_save_DATA_BLOB;
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+
+enum ndr_err_code ndr_push_Logon_req(struct ndr_push *ndr, int ndr_flags, const struct Logon_req *r)
+{
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			NDR_CHECK(ndr_push_align(ndr, 4));
+			NDR_CHECK(ndr_push_LogonFlags(ndr, NDR_SCALARS, r->LogonFlags));
+			NDR_CHECK(ndr_push_OpenFlags(ndr, NDR_SCALARS, r->OpenFlags));
+			NDR_CHECK(ndr_push_StoreState(ndr, NDR_SCALARS, r->StoreState));
+			if (r->EssDN && r->EssDN[0] != '\0') {
+				uint32_t _flags_save_string = ndr->flags;
+				ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE2);
+				NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->EssDN));
+				ndr->flags = _flags_save_string;
+			} else {
+				NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0));
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+
+_PUBLIC_ void ndr_print_SBinary_short(struct ndr_print *ndr, const char *name, const struct SBinary_short *r)
+{
+	ndr->print(ndr, "%-25s: SBinary_short cb=%u", name, (unsigned)r->cb);
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		ndr->depth++;
+		dump_data(0, r->lpb, r->cb);
+		ndr->depth--;
+		ndr->flags = _flags_save_STRUCT;
+	}
+}
+
+
+_PUBLIC_ void ndr_print_fuzzyLevel(struct ndr_print *ndr, const char *name, uint32_t r)
+{
+	ndr_print_uint32(ndr, name, r);
+	ndr->depth++;
+	switch ((r & 0x0000FFFF)) {
+	case FL_FULLSTRING:
+		ndr->print(ndr, "%-25s: FL_FULLSTRING", "lower  16 bits");
+		break;
+	case FL_SUBSTRING:
+		ndr->print(ndr, "%-25s: FL_SUBSTRING", "lower  16 bits");
+		break;
+	case FL_PREFIX:
+		ndr->print(ndr, "%-25s: FL_PREFIX", "lower  16 bits");
+		break;
+	}
+	ndr->print(ndr, "%-25s", "higher 16 bits");
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_IGNORECASE", FL_IGNORECASE, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_IGNORENONSPACE", FL_IGNORENONSPACE, r);
+	ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "FL_LOOSE", FL_LOOSE, r);
+	ndr->depth--;
+}
+
+/*
+ * Fake wrapper over mapi_SRestriction. Workaround the no-pointer deep
+ * recursion problem in pidl
+ */
+enum ndr_err_code ndr_push_mapi_SRestriction_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SRestriction_wrap *r)
+{
+	return ndr_push_mapi_SRestriction(ndr, NDR_SCALARS, (const struct mapi_SRestriction *)r);
+}
+
+
+enum ndr_err_code ndr_pull_mapi_SRestriction_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SRestriction_wrap *r)
+{
+	return ndr_pull_mapi_SRestriction(ndr, NDR_SCALARS|NDR_BUFFERS, (struct mapi_SRestriction *)r);
+}
+
+void ndr_print_mapi_SRestriction_wrap(struct ndr_print *ndr, const char *name, const struct mapi_SRestriction_wrap *r)
+{
+	ndr_print_mapi_SRestriction(ndr, name, (const struct mapi_SRestriction *)r);
+}
+
+/*
+ * Fake wrapper over mapi_SPropValue. Workaround the no-pointer deep
+ * recursion problem in pidl
+ */
+enum ndr_err_code ndr_push_mapi_SPropValue_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SPropValue_wrap *r)
+{
+	NDR_CHECK(ndr_push_align(ndr, 8));
+	return ndr_push_mapi_SPropValue(ndr, NDR_SCALARS, (const struct mapi_SPropValue *)r);
+}
+
+enum ndr_err_code ndr_pull_mapi_SPropValue_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SPropValue_wrap *r)
+{
+	return ndr_pull_mapi_SPropValue(ndr, NDR_SCALARS, (struct mapi_SPropValue *)r);
+}
+
+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);
+}
+
+
+/*
+ * Fake wrapper over mapi_SPropValue_array. Workaround the no-pointer deep
+ * recursion problem in pidl
+ */
+enum ndr_err_code ndr_push_mapi_SPropValue_array_wrap(struct ndr_push *ndr, int ndr_flags, const struct mapi_SPropValue_array_wrap *r)
+{
+	NDR_CHECK(ndr_push_align(ndr, 8));
+	return ndr_push_mapi_SPropValue_array(ndr, NDR_SCALARS, (const struct mapi_SPropValue_array *)r);
+}
+
+enum ndr_err_code ndr_pull_mapi_SPropValue_array_wrap(struct ndr_pull *ndr, int ndr_flags, struct mapi_SPropValue_array_wrap *r)
+{
+	return ndr_pull_mapi_SPropValue_array(ndr, NDR_SCALARS, (struct mapi_SPropValue_array *)r);
+}
+
+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);
+}
+
+enum ndr_err_code ndr_push_RestrictionVariable(struct ndr_push *ndr, int ndr_flags, const union RestrictionVariable *r)
+{
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+		if (ndr_flags & NDR_SCALARS) {
+			int level = ndr_push_get_switch_value(ndr, r);
+			switch (level) {
+				case 0x0: {
+					break; }
+
+				case 0x1: {
+					NDR_CHECK(ndr_push_mapi_SRestriction_comment(ndr, NDR_SCALARS, &r->res[0]));
+				break; }
+
+				default:
+					return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+			int level = ndr_push_get_switch_value(ndr, r);
+			switch (level) {
+				case 0x0:
+				break;
+
+				case 0x1:
+					if (r->res) {
+						NDR_CHECK(ndr_push_mapi_SRestriction_comment(ndr, NDR_BUFFERS, &r->res[0]));
+					}
+				break;
+
+				default:
+					return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+			}
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code  ndr_pull_RestrictionVariable(struct ndr_pull *ndr, int ndr_flags, union RestrictionVariable *r)
+{
+	int level;
+	TALLOC_CTX *_mem_save_res_0;
+	level = ndr_pull_get_switch_value(ndr, r);
+	{
+		uint32_t _flags_save_STRUCT = ndr->flags;
+		ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+
+		if (ndr_flags & NDR_SCALARS) {
+			switch (level) {
+				case 0x0: {
+				break; }
+
+				case 0x1: {
+					NDR_CHECK(ndr_pull_align(ndr, 4));
+					NDR_PULL_ALLOC_N(ndr, r->res, 1);
+					_mem_save_res_0 = NDR_PULL_GET_MEM_CTX(ndr);
+					NDR_PULL_SET_MEM_CTX(ndr, r->res, 0);
+					NDR_CHECK(ndr_pull_mapi_SRestriction_comment(ndr, NDR_SCALARS, &r->res[0]));
+					NDR_PULL_SET_MEM_CTX(ndr, _mem_save_res_0, 0);
+				break; }
+
+				default:
+					return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+			}
+		}
+		if (ndr_flags & NDR_BUFFERS) {
+			switch (level) {
+				case 0x0:
+				break;
+
+				case 0x1:
+					if (r->res) {
+						_mem_save_res_0 = NDR_PULL_GET_MEM_CTX(ndr);
+						NDR_PULL_SET_MEM_CTX(ndr, r->res, 0);
+						NDR_CHECK(ndr_pull_mapi_SRestriction_comment(ndr, NDR_BUFFERS, &r->res[0]));
+						NDR_PULL_SET_MEM_CTX(ndr, _mem_save_res_0, 0);
+				break; }
+
+				default:
+					return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level);
+			}
+		}
+		ndr->flags = _flags_save_STRUCT;
+	}
+	return NDR_ERR_SUCCESS;
+}
+
+
+_PUBLIC_ void ndr_print_RestrictionVariable(struct ndr_print *ndr, const char *name, const union RestrictionVariable *r)
+{
+	int level;
+	level = ndr_print_get_switch_value(ndr, r);
+	ndr_print_union(ndr, name, level, "RestrictionVariable");
+	switch (level) {
+		case 0x0:
+		break;
+
+		case 0x1:
+			ndr_print_ptr(ndr, "res", r->res);
+			ndr->depth++;
+			if (r->res) {
+				ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
+				ndr_print_mapi_SRestriction_comment(ndr, "res", &r->res[0]);
+			}
+			ndr->depth--;
+		break;
+	}
+}
+
+enum ndr_err_code ndr_push_Release_req(struct ndr_push *ndr, int ndr_flags, const struct Release_req *r)
+{
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_Release_req(struct ndr_pull *ndr, int ndr_flags, struct Release_req *r)
+{
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_push_Release_repl(struct ndr_push *ndr, int ndr_flags, const struct Release_repl *r)
+{
+	return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_Release_repl(struct ndr_pull *ndr, int ndr_flags, struct Release_repl *r)
+{
+	return NDR_ERR_SUCCESS;
+}

Added: trunk/openchange/property.idl
===================================================================
--- trunk/openchange/property.idl	                        (rev 0)
+++ trunk/openchange/property.idl	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,158 @@
+#include "idl_types.h"
+
+cpp_quote("#include <gen_ndr/ndr_misc.h>")
+
+import "exchange.idl";
+
+[
+	pointer_default(unique)
+]
+interface property
+{
+	typedef [enum16bit] enum {
+		RecurFrequency_Daily	= 0x200A,
+		RecurFrequency_Weekly	= 0x200B,
+		RecurFrequency_Monthly	= 0x200C,
+		RecurFrequency_Yearly	= 0x200D
+	} RecurFrequency;
+	
+	typedef [enum16bit] enum {
+		PatternType_Day		= 0x0,
+		PatternType_Week	= 0x1,
+		PatternType_Month	= 0x2,
+		PatternType_MonthNth	= 0x3,
+		PatternType_MonthEnd	= 0x4,
+		PatternType_HjMonth	= 0xA,
+		PatternType_HjMonthNth	= 0xB,
+		PatternType_HjMonthEnd	= 0xC
+	} PatternType;
+
+	typedef [enum16bit] enum {
+		CAL_DEFAULT			= 0x0,
+		CAL_GREGORIAN			= 0x1,
+		CAL_GREGORIAN_US		= 0x2,
+		CAL_JAPAN			= 0x3,
+		CAL_TAIWAN			= 0x4,
+		CAL_KOREA			= 0x5,
+		CAL_HIJRI			= 0x6,
+		CAL_THAI			= 0x7,
+		CAL_HEBREW			= 0x8,
+		CAL_GREGORIAN_ME_FRENCH		= 0x9,
+		CAL_GREGORIAN_ARABIC		= 0xA,
+		CAL_GREGORIAN_XLIT_ENGLISH	= 0xB,
+		CAL_GREGORIAN_XLIT_FRENCH	= 0xC,
+		CAL_LUNAR_JAPANESE		= 0xE,
+		CAL_CHINESE_LUNAR		= 0xF,
+		CAL_SAKA			= 0x10,
+		CAL_LUNAR_KOREAN		= 0x14
+	} CalendarType;
+
+	typedef [bitmap32bit] bitmap {
+		Su		= 0x00000001,
+		M		= 0x00000002,
+		Tu		= 0x00000004,
+		W		= 0x00000008,
+		Th		= 0x00000010,
+		F		= 0x00000020,
+		Sa		= 0x00000040
+	} WeekRecurrencePattern;
+
+	typedef [v1_enum] enum {
+		RecurrenceN_First	=	0x1,
+		RecurrenceN_Second	=	0x2,
+		RecurrenceN_Third	=	0x3,
+		RecurrenceN_Fourth	=	0x4,
+		RecurrenceN_Last	=	0x5
+	} RecurrenceN;
+
+	typedef [flag(NDR_NOALIGN)] struct {
+		WeekRecurrencePattern	WeekRecurrencePattern;
+		RecurrenceN		N;
+	} MonthRecurrencePattern;
+
+	typedef [nodiscriminant,flag(NDR_NOALIGN)] union {
+		[case(0x1)] WeekRecurrencePattern     		WeekRecurrencePattern;
+		[case(0x2)] uint32				Day;
+		[case(0x3)] MonthRecurrencePattern		MonthRecurrencePattern;
+		[case(0x4)] uint32				Day;
+		[case(0xA)] uint32				Day;
+		[case(0xB)] MonthRecurrencePattern		MonthRecurrencePattern;
+		[case(0xC)] uint32				Day;
+		[case(0x0)];
+		[default];
+	} PatternTypeSpecific;
+
+	typedef [v1_enum] enum {
+		END_AFTER_DATE		= 0x00002021,
+		END_AFTER_N_OCCURRENCES	= 0x00002022,
+		END_NEVER_END		= 0x00002023,
+		NEVER_END		= 0xFFFFFFFF
+	} EndType;
+
+	typedef [v1_enum] enum {
+		FirstDOW_Sunday		= 0x0,
+		FirstDOW_Monday		= 0x1,
+		FirstDOW_Tuesday	= 0x2,
+		FirstDOW_Wednesday	= 0x3,
+		FirstDOW_Thursday	= 0x4,
+		FirstDOW_Friday		= 0x5,
+		FirstDOW_Saturday	= 0x6
+	} FirstDOW;
+
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint16						ReaderVersion;
+		uint16						WriterVersion;
+		RecurFrequency					RecurFrequency;
+		PatternType					PatternType;
+		CalendarType					CalendarType;
+		uint32						FirstDateTime;
+		uint32						Period;
+		uint32						SlidingFlag;
+		[switch_is(PatternType)] PatternTypeSpecific   	PatternTypeSpecific;
+		EndType						EndType;
+		uint32						OccurrenceCount;
+		FirstDOW       					FirstDOW;
+		uint32						DeletedInstanceCount;
+		uint32						DeletedInstanceDates[DeletedInstanceCount];
+		uint32						ModifiedInstanceCount;
+		uint32						ModifiedInstanceDates[ModifiedInstanceCount];
+		uint32						StartDate;
+		uint32						EndDate;
+	} RecurrencePattern;
+
+	/* [MS-DIF].pdf Section 2.3.6 */
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint16	wYear;
+		uint16	wMonth;
+		uint16	wDayOfWeek;
+		uint16	wDay;
+		uint16	wHour;
+		uint16	wMinute;
+		uint16	wSecond;
+		uint16	wMilliseconds;
+	} SYSTEMTIME;
+
+	/* pidLidTimeZoneStruct */
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint32			lBias;
+		uint32			lStandardBias;
+		uint32			lDaylightBias;
+		uint16			wStandardYear;
+		SYSTEMTIME     		stStandardDate;
+		uint16			wDaylightYear;
+		SYSTEMTIME		stDaylightDate;
+	} TimeZoneStruct;
+
+	/* pidLidGlobalObjectId */
+	typedef [public,flag(NDR_NOALIGN)] struct {
+		uint8			ByteArrayID[16];
+		uint8			YH;
+		uint8			YL;
+ 		uint8			Month;
+ 		uint8			D;
+		FILETIME		CreationTime;
+		uint8			X[8];
+		uint32			Size;
+		uint8			Data[Size];
+	} GlobalObjectId;
+}

Added: trunk/openchange/pymapi/msg_store.c
===================================================================
--- trunk/openchange/pymapi/msg_store.c	                        (rev 0)
+++ trunk/openchange/pymapi/msg_store.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,62 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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 "pymapi/pymapi.h"
+
+static PyObject *py_is_mailbox_folder(PyMapiObjectObject *self, PyObject *args)
+{
+	uint64_t fid;
+	uint32_t olFolder;
+
+	if (!PyArg_ParseTuple(args, "L", &fid))
+		return NULL;
+
+	if (!IsMailboxFolder(self->object, fid, &olFolder))
+		return Py_None;
+
+	return PyInt_FromLong(olFolder);
+}
+
+static PyMethodDef msg_store_methods[] = {
+	{ "is_mailbox_folder", (PyCFunction)py_is_mailbox_folder, METH_VARARGS, NULL },
+	{ NULL },
+};
+
+static PyGetSetDef msg_store_getsetters[] = {
+	{ NULL }
+};
+
+static PyObject *msg_store_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+	PyErr_SetString(PyExc_NotImplementedError, "Message Stores can only be obtained from a MAPI Session");
+	return NULL;
+}
+
+PyTypeObject PyMapiMsgStoreType = {
+	PyObject_HEAD_INIT(NULL) 0,
+	.tp_name = "MessageStore",
+	.tp_basicsize = sizeof(PyMapiObjectObject),
+	.tp_methods = msg_store_methods,
+	.tp_getset = msg_store_getsetters,
+	.tp_doc = "MAPI Message Store",
+	.tp_new = msg_store_new,
+	.tp_base = &PyMapiObjectType,
+	.tp_flags = Py_TPFLAGS_DEFAULT,
+};
+

Added: trunk/openchange/pymapi/object.c
===================================================================
--- trunk/openchange/pymapi/object.c	                        (rev 0)
+++ trunk/openchange/pymapi/object.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,344 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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 "pymapi/pymapi.h"
+
+static PyObject *PyMapiObject_FromMapiObject(mapi_object_t *obj)
+{
+	return NULL; /* FIXME */
+}	
+
+static PyObject *object_create(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+	/* FIXME */
+	return (PyObject *)PyObject_New(PyMapiObjectObject, type);
+}
+
+static void object_dealloc(PyObject *_self)
+{
+	PyMapiObjectObject *self = (PyMapiObjectObject *)_self;
+	mapi_object_release(self->object);
+	PyObject_Del(_self);
+}
+
+mapi_object_t *PyMapiObject_GetMapiObject(PyObject *obj)
+{
+	PyMapiObjectObject *self = (PyMapiObjectObject *)obj;
+	if (!PyMapiObject_Check(obj))
+		return NULL;
+
+	return self->object;
+}
+
+static PyObject *py_folder_get_items_count(PyMapiObjectObject *self)
+{
+	enum MAPISTATUS status;
+	uint32_t unread, total;
+
+	status = GetFolderItemsCount(self->object, &unread, &total);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_BuildValue("(ii)", unread, total);
+}
+
+static PyObject *py_folder_remove_user_permissions(PyMapiObjectObject *self, PyObject *args)
+{
+	char *username;
+	enum MAPISTATUS status;
+	if (!PyArg_ParseTuple(args, "s", &username))
+		return NULL;
+
+	status = RemoveUserPermission(self->object, username);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyObject *py_folder_create(PyMapiObjectObject *self, PyObject *args)
+{
+	int foldertype;
+	char *name, *comment;
+	uint32_t flags;
+	enum MAPISTATUS status;
+	mapi_object_t child;
+
+	if (!PyArg_ParseTuple(args, "issI", &foldertype, &name, &comment, &flags))
+		return NULL;
+
+	status = CreateFolder(self->object, foldertype, name, comment, flags, &child);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyMapiObject_FromMapiObject(&child);
+}
+
+static PyObject *py_folder_delete(PyMapiObjectObject *self, PyObject *args)
+{
+	mapi_id_t folderid; 
+	int flags;
+	enum MAPISTATUS status;
+	bool partial;
+	if (!PyArg_ParseTuple(args, "ii", &folderid, &flags))
+		return NULL;
+
+	status = DeleteFolder(self->object, folderid, flags, &partial);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyBool_FromLong(partial);
+}
+
+static PyObject *py_folder_empty(PyMapiObjectObject *self)
+{
+	enum MAPISTATUS status = EmptyFolder(self->object);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+	return Py_None;
+}
+
+static PyObject *py_folder_create_message(PyMapiObjectObject *self)
+{
+	mapi_object_t msg;
+	enum MAPISTATUS status = CreateMessage(self->object, &msg);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+	return PyMapiObject_FromMapiObject(&msg);
+}
+
+static PyObject *py_folder_delete_messages(PyMapiObjectObject *self, PyObject *args)
+{
+	PyObject *py_ids;
+	uint32_t cn_messages;
+	mapi_id_t *ids;
+	enum MAPISTATUS status;
+	int i;
+
+	if (!PyArg_ParseTuple(args, "O", &py_ids))
+		return NULL;
+
+	if (!PySequence_Check(py_ids)) {
+		PyErr_SetString(PyExc_TypeError, "ids should be a list of ids");
+		return NULL;
+	}
+
+	cn_messages = PySequence_Size(py_ids);
+	ids = talloc_array(NULL, mapi_id_t, cn_messages);
+	if (ids == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	for (i = 0; i < cn_messages; i++) {
+		PyObject *item;
+		item = PySequence_GetItem(py_ids, i);
+		ids[i] = PyInt_AsLong(item);
+	}
+
+	status = DeleteMessage(self->object, ids, cn_messages);
+	talloc_free(ids);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyObject *py_folder_set_read_flags(PyMapiObjectObject *self, PyObject *args)
+{
+	int flags;
+	PyObject *py_ids;
+	enum MAPISTATUS status;
+	uint16_t cn_ids;
+    uint64_t *ids;
+	int i;
+	if (!PyArg_ParseTuple(args, "iO", &flags, &py_ids))
+		return NULL;
+
+	if (!PySequence_Check(py_ids)) {
+		PyErr_SetString(PyExc_TypeError, "ids should be a list of ids");
+		return NULL;
+	}
+
+	cn_ids = PySequence_Size(py_ids);
+	ids = talloc_array(NULL, uint64_t, cn_ids);
+	if (ids == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	for (i = 0; i < cn_ids; i++) {
+		PyObject *item;
+		item = PySequence_GetItem(py_ids, i);
+		ids[i] = PyInt_AsLong(item);
+	}
+
+	status = SetReadFlags(self->object, flags, cn_ids, ids);
+	talloc_free(ids);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyObject *py_folder_get_message_status(PyMapiObjectObject *self, PyObject *args)
+{
+	mapi_id_t msgid;
+	uint32_t lstatus;
+	enum MAPISTATUS status;
+	if (!PyArg_ParseTuple(args, "i", &msgid))
+		return NULL;
+	
+	status = GetMessageStatus(self->object, msgid, &lstatus);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyInt_FromLong(lstatus);
+}
+
+static PyObject *py_message_get_best_body(PyMapiObjectObject *self)
+{
+	enum MAPISTATUS status;
+	uint8_t format;
+	
+	status = GetBestBody(self->object, &format);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyInt_FromLong(status);
+}
+
+static PyObject *py_get_default_folder(PyMapiObjectObject *self, PyObject *args)
+{
+	enum MAPISTATUS status;
+	uint32_t type;
+	uint64_t folder;
+
+	if (!PyArg_ParseTuple(args, "i", &type))
+		return NULL;
+
+	status = GetDefaultFolder(self->object, &folder, type);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyLong_FromLong(folder);
+}
+
+static PyObject *py_get_default_public_folder(PyMapiObjectObject *self, PyObject *args)
+{
+	enum MAPISTATUS status;
+	uint32_t type;
+	uint64_t folder;
+
+	if (!PyArg_ParseTuple(args, "i", &type))
+		return NULL;
+
+	status = GetDefaultPublicFolder(self->object, &folder, type);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return PyLong_FromLong(folder);
+}
+
+static PyObject *py_folder_add_user_permission(PyMapiObjectObject *self, PyObject *args)
+{
+	char *name;
+	int rights;
+	enum MAPISTATUS status;
+	if (!PyArg_ParseTuple(args, "si", &name, &rights))
+		return NULL;
+
+	status = AddUserPermission(self->object, name, rights);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyObject *py_folder_modify_user_permission(PyMapiObjectObject *self, PyObject *args)
+{
+	char *name;
+	int rights;
+	enum MAPISTATUS status;
+	if (!PyArg_ParseTuple(args, "si", &name, &rights))
+		return NULL;
+
+	status = ModifyUserPermission(self->object, name, rights);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyMethodDef object_methods[] = {
+	{ "get_folder_items_count", (PyCFunction)py_folder_get_items_count, METH_NOARGS, 
+		"S.get_folder_items_count() -> (unread, total)" },
+	{ "remove_user_permission", (PyCFunction)py_folder_remove_user_permissions, METH_VARARGS,
+		"S.remove_user_permissions(user) -> None" },
+	{ "add_user_permission", (PyCFunction)py_folder_add_user_permission, METH_VARARGS,
+		"S.add_user_permission(user, perm) -> None" },
+	{ "modify_user_permission", (PyCFunction)py_folder_modify_user_permission, METH_VARARGS,
+		"S.modify_user_permission(user, perm) -> None" },
+	{ "create_folder", (PyCFunction)py_folder_create, METH_VARARGS,
+		"S.create_folder(type, name, comment, flags) -> None" },
+	{ "empty_folder", (PyCFunction)py_folder_empty, METH_NOARGS, 
+		"S.empty_folder() -> None" },
+	{ "delete_folder", (PyCFunction)py_folder_delete, METH_VARARGS,
+		"S.delete_folder(folderid, flags) -> None" },
+	{ "create_message", (PyCFunction)py_folder_create_message, METH_NOARGS,
+		"S.create_message() -> message" },
+	{ "delete_messages", (PyCFunction)py_folder_delete_messages, METH_VARARGS,
+		"S.delete_messages([ids]) -> None" },
+	{ "get_message_status", (PyCFunction)py_folder_get_message_status, METH_VARARGS,
+		"S.get_message_status(id) -> status" },
+	{ "set_read_flags", (PyCFunction)py_folder_set_read_flags, METH_VARARGS,
+		"S.set_read_flags(flags, [ids]) -> None" },
+	{ "get_best_body", (PyCFunction)py_message_get_best_body, METH_NOARGS,
+		"S.get_best_body() -> format" },
+	{ "get_default_folder", (PyCFunction)py_get_default_folder, METH_VARARGS,
+		"S.get_default_folder(type) -> id" },
+	{ "get_default_public_folder", (PyCFunction)py_get_default_public_folder, METH_VARARGS,
+		"S.get_default_public_folder(type) -> id" },
+	{ NULL },
+};
+
+static PyObject *object_get_session(PyObject *_self, void *closure)
+{
+	PyMapiObjectObject *self = (PyMapiObjectObject *)_self;
+	struct mapi_session *session;
+
+	session = mapi_object_get_session(self->object);
+
+	return PyMapiSession_FromMapiSession(session);
+}
+
+static PyObject *object_get_id(PyObject *_self, void *closure)
+{
+	PyMapiObjectObject *self = (PyMapiObjectObject *)_self;
+	mapi_id_t id;
+
+	id = mapi_object_get_id(self->object);
+
+	return PyLong_FromLong(id);
+}
+
+static PyGetSetDef object_getsetters[] = {
+	{ "session", object_get_session, NULL, "The MAPI session" },
+	{ "id", object_get_id, NULL, "MAPI ID" },
+	{ NULL }
+};
+
+PyTypeObject PyMapiObjectType = {
+	PyObject_HEAD_INIT(NULL) 0,
+	.tp_name = "Object",
+	.tp_basicsize = sizeof(PyMapiObjectObject),
+	.tp_methods = object_methods,
+	.tp_getset = object_getsetters,
+	.tp_doc = "MAPI Object",
+	.tp_new = object_create,
+	.tp_dealloc = object_dealloc,
+	.tp_flags = Py_TPFLAGS_DEFAULT,
+};
+

Added: trunk/openchange/pymapi/pymapi.c
===================================================================
--- trunk/openchange/pymapi/pymapi.c	                        (rev 0)
+++ trunk/openchange/pymapi/pymapi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,105 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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 "pymapi/pymapi.h"
+
+void initmapi(void);
+
+static PyObject *py_get_proptag_value(PyObject *mod, PyObject *args)
+{
+	char *propname;
+	if (!PyArg_ParseTuple(args, "s", &propname))
+		return NULL;
+
+	return PyInt_FromLong(get_proptag_value(propname));
+}
+
+static PyObject *py_get_proptag_name(PyObject *mod, PyObject *args)
+{
+	uint32_t proptag;
+	const char *name;
+	if (!PyArg_ParseTuple(args, "i", &proptag))
+		return NULL;
+
+	name = get_proptag_name(proptag);
+	if (name == NULL)
+		return Py_None;
+	return PyString_FromString(name);
+}
+
+static PyObject *py_get_importance(PyObject *mod, PyObject *args)
+{
+	uint32_t importance;
+	const char *name;
+	if (!PyArg_ParseTuple(args, "i", &importance))
+		return NULL;
+
+	name = get_importance(importance);
+	if (name == NULL)
+		return Py_None;
+	return PyString_FromString(name);
+}
+
+static PyObject *py_get_task_status(PyObject *mod, PyObject *args)
+{
+	uint32_t task_status;
+	const char *name;
+	if (!PyArg_ParseTuple(args, "i", &task_status))
+		return NULL;
+
+	name = get_task_status(task_status);
+	if (name == NULL)
+		return Py_None;
+	return PyString_FromString(name);
+}
+
+static PyMethodDef mapi_methods[] = {
+	{ "get_proptag_value", (PyCFunction)py_get_proptag_value, METH_VARARGS, NULL },
+	{ "get_proptag_name", (PyCFunction)py_get_proptag_name, METH_VARARGS, NULL },
+	{ "get_importance", (PyCFunction)py_get_importance, METH_VARARGS, NULL },
+	{ "get_task_status", (PyCFunction)py_get_task_status, METH_VARARGS, NULL },
+	{ NULL }
+};
+
+void initmapi(void)
+{
+	PyObject *m;
+
+	if (PyType_Ready(&PyMapiSessionType) < 0)
+		return;
+
+	if (PyType_Ready(&PyMapiObjectType) < 0)
+		return;
+
+	if (PyType_Ready(&PyMapiMsgStoreType) < 0)
+		return;
+
+	m = Py_InitModule3("mapi", mapi_methods, "MAPI/RPC Python bindings");
+	if (m == NULL)
+		return;
+
+	Py_INCREF((PyObject *)&PyMapiSessionType);
+	PyModule_AddObject(m, "Session", (PyObject *)&PyMapiSessionType);
+
+	Py_INCREF((PyObject *)&PyMapiObjectType);
+	PyModule_AddObject(m, "Object", (PyObject *)&PyMapiObjectType);
+
+	Py_INCREF((PyObject *)&PyMapiMsgStoreType);
+	PyModule_AddObject(m, "MessageStore", (PyObject *)&PyMapiMsgStoreType);
+}

Added: trunk/openchange/pymapi/pymapi.h
===================================================================
--- trunk/openchange/pymapi/pymapi.h	                        (rev 0)
+++ trunk/openchange/pymapi/pymapi.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,52 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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 _PYMAPI_H_
+#define _PYMAPI_H_
+
+#include <libmapi/libmapi.h>
+#include <Python.h>
+
+/* mapi.Session */
+PyAPI_DATA(PyTypeObject) PyMapiSessionType;
+PyObject *PyMapiSession_FromMapiSession(struct mapi_session *session);
+
+/* mapi.Object */
+typedef struct {
+	PyObject_HEAD	
+	mapi_object_t *object;
+} PyMapiObjectObject;
+
+PyAPI_DATA(PyTypeObject) PyMapiObjectType;
+mapi_object_t *PyMapiObject_GetMapiObject(PyObject *);
+#define PyMapiObject_Check(op) PyObject_TypeCheck(op, &PyMapiObjectType)
+
+/* mapi.MessageStore */
+PyAPI_DATA(PyTypeObject) PyMapiMsgStoreType;
+
+/* Set a MAPISTATUS error as a Python exception */
+#define PyErr_FromMAPISTATUS(err) Py_BuildValue("(i,z)", err, NULL)
+#define PyErr_SetMAPISTATUS(err) PyErr_SetObject(PyExc_RuntimeError, PyErr_FromMAPISTATUS(err))
+#define PyErr_MAPISTATUS_IS_ERR_RAISE(err) \
+	if (err != MAPI_E_SUCCESS) { \
+		PyErr_SetMAPISTATUS(err); \
+		return NULL; \
+	}
+
+#endif

Added: trunk/openchange/pymapi/session.c
===================================================================
--- trunk/openchange/pymapi/session.c	                        (rev 0)
+++ trunk/openchange/pymapi/session.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,190 @@
+/*
+   OpenChange MAPI implementation.
+
+   Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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 "pymapi/pymapi.h"
+
+typedef struct {
+	PyObject_HEAD	
+	struct mapi_session *session;
+} PyMapiSessionObject;
+
+static PyObject *py_session_create(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+	enum MAPISTATUS retval;
+	char *kwnames[] = { "profname", "password", "provider" };
+	char *profname, *password;
+	uint32_t provider = 0;
+	struct mapi_session *session;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss|i", kwnames, 
+										&profname, &password, &provider))
+		return NULL;
+
+	retval = MapiLogonProvider(&session, profname, password, provider);
+	if (!retval) {
+		PyErr_SetMAPISTATUS(retval);
+		return NULL;
+	}
+	return PyMapiSession_FromMapiSession(session);
+}
+
+PyObject *PyMapiSession_FromMapiSession(struct mapi_session *session)
+{
+	PyMapiSessionObject *ret;
+	ret = PyObject_New(PyMapiSessionObject, &PyMapiSessionType);
+	ret->session = session;
+	return (PyObject *)ret;
+}
+
+static PyObject *py_session_login(PyObject *args, PyObject *kwargs)
+{
+	/* FIXME */
+	return NULL;
+}
+
+static PyObject *py_open_msg_store(PyObject *self, PyObject *args)
+{
+	PyObject *py_mapi_object;
+	PyMapiSessionObject *self_session = (PyMapiSessionObject *)self;
+	mapi_object_t *obj;
+	enum MAPISTATUS retval;
+
+	if (!PyArg_ParseTuple(args, "O", &py_mapi_object))
+		return NULL;
+
+	obj = PyMapiObject_GetMapiObject(py_mapi_object);
+	if (obj == NULL) {
+		PyErr_SetString(PyExc_TypeError, "Expected MAPI Object");
+		return NULL;
+	}
+
+	retval = OpenMsgStore(self_session->session, obj);
+	if (!retval) {
+		PyErr_SetMAPISTATUS(retval);
+		return NULL;
+	}
+
+	return Py_None;
+}
+
+static PyObject *py_open_user_mailbox(PyObject *self, PyObject *args)
+{
+	PyObject *py_mapi_object;
+	PyMapiSessionObject *self_session = (PyMapiSessionObject *)self;
+	mapi_object_t *obj;
+	enum MAPISTATUS retval;
+	char *username;
+
+	if (!PyArg_ParseTuple(args, "sO", &username, &py_mapi_object))
+		return NULL;
+
+	obj = PyMapiObject_GetMapiObject(py_mapi_object);
+	if (obj == NULL) {
+		PyErr_SetString(PyExc_TypeError, "Expected MAPI Object");
+		return NULL;
+	}
+
+	retval = OpenUserMailbox(self_session->session, username, obj);
+	if (!retval) {
+		PyErr_SetMAPISTATUS(retval);
+		return NULL;
+	}
+
+	return Py_None;
+}
+
+static PyObject *py_open_public_folder(PyObject *self, PyObject *args)
+{
+	PyObject *py_mapi_object;
+	PyMapiSessionObject *self_session = (PyMapiSessionObject *)self;
+	mapi_object_t *obj;
+	enum MAPISTATUS retval;
+
+	if (!PyArg_ParseTuple(args, "O", &py_mapi_object))
+		return NULL;
+
+	obj = PyMapiObject_GetMapiObject(py_mapi_object);
+	if (obj == NULL) {
+		PyErr_SetString(PyExc_TypeError, "Expected MAPI Object");
+		return NULL;
+	}
+
+	retval = OpenPublicFolder(self_session->session, obj);
+	if (!retval) {
+		PyErr_SetMAPISTATUS(retval);
+		return NULL;
+	}
+
+	return Py_None;
+}
+
+static PyObject *py_unsubscribe(PyMapiSessionObject *self, PyObject *args)
+{
+	uint32_t ulConnection;
+	enum MAPISTATUS status;
+	
+	if (!PyArg_ParseTuple(args, "i", &ulConnection))
+		return NULL;
+
+	status = Unsubscribe(self->session, ulConnection);
+	PyErr_MAPISTATUS_IS_ERR_RAISE(status);
+
+	return Py_None;
+}
+
+static PyMethodDef session_methods[] = {
+	{ "login", (PyCFunction) py_session_login, METH_VARARGS|METH_KEYWORDS },
+	{ "open_msg_store", (PyCFunction) py_open_msg_store, METH_VARARGS,
+		"S.open_msg_store(object)\n\n"
+		"This function opens the main message store. This allows access to "
+		"the normal user folders."
+	},
+	{ "open_user_mailbox", (PyCFunction) py_open_user_mailbox, METH_VARARGS,
+		"S.open_user_mailbox(username, object)\n\n"
+		"Open another users mailbox."
+	},
+	{ "open_public_folder", (PyCFunction) py_open_public_folder, METH_VARARGS,
+		"S.open_public_folder(object)\n\n"
+		"This function opens the public folder store. This allows access to "
+		"the public folders."
+	},
+	{ "unsubscribe", (PyCFunction) py_unsubscribe, METH_VARARGS,
+		"S.Unsubscribe(int) -> None"
+	},
+	{ NULL },
+};
+
+static PyGetSetDef session_getsetters[] = {
+	{ "default_profile_path", NULL, NULL },
+	{ "profile_name", NULL, NULL },
+	{ "message_store", NULL, NULL },
+	{ NULL }
+};
+
+PyTypeObject PyMapiSessionType = {
+	PyObject_HEAD_INIT(NULL) 0,
+	.tp_name = "Session",
+	.tp_basicsize = sizeof(PyMapiSessionObject),
+	.tp_methods = session_methods,
+	.tp_getset = session_getsetters,
+	.tp_doc = "MAPI Session",
+	.tp_new = py_session_create,
+	.tp_flags = Py_TPFLAGS_DEFAULT,
+};
+

Added: trunk/openchange/python/openchange/__init__.py
===================================================================
--- trunk/openchange/python/openchange/__init__.py	                        (rev 0)
+++ trunk/openchange/python/openchange/__init__.py	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+
+# OpenChange Python bindings
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+__docformat__ = 'restructuredText'
+
+import os, sys
+
+def find_samba_python_path():
+    """Find the python path for the Samba python modules
+
+    :return: Python path to Samba python modules, or None if 
+        it was already in the path
+    """
+    try:
+        import samba
+        return None # No extra path necessary
+    except ImportError:
+        SAMBA_PREFIXES = ["/usr/local/samba", "/opt/samba"]
+        PYTHON_NAMES = ["python2.3", "python2.4", "python2.5"]
+        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
+        raise ImportError("Unable to find the Samba python path")

Added: trunk/openchange/python/openchange/mailbox.py
===================================================================
--- trunk/openchange/python/openchange/mailbox.py	                        (rev 0)
+++ trunk/openchange/python/openchange/mailbox.py	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,307 @@
+#!/usr/bin/python
+
+# OpenChange provisioning
+# Copyright (C) Julien Kerihuel <j.kerihuel at openchange.org> 2009
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+import os
+import samba
+from samba import Ldb
+import ldb
+import uuid
+
+__docformat__ = 'restructuredText'
+
+
+class NoSuchServer(Exception):
+    """Raised when a server could not be found."""
+
+
+class OpenChangeDB(object):
+    """The OpenChange database.
+    """
+
+    def __init__(self, url):
+        self.url = url
+        self.ldb = Ldb(self.url)
+
+    def reopen(self):
+        self.ldb = Ldb(self.url)
+
+    def setup(self):
+        self.ldb.add_ldif("""
+dn: @OPTIONS
+checkBaseOnSearch: TRUE
+
+dn: @INDEXLIST
+ at IDXATTR: cn
+
+dn: @ATTRIBUTES
+cn: CASE_INSENSITIVE
+dn: CASE_INSENSITIVE
+
+""")
+        self.reopen()
+
+    def add_server(self, ocserverdn, netbiosname, firstorg, firstou):
+        self.ldb.add({"dn": ocserverdn,
+                  "objectClass": ["top", "server"],
+                  "cn": netbiosname,
+                  "GlobalCount": "0x1",
+                  "ReplicaID": "0x1"})
+        self.ldb.add({"dn": "CN=%s,%s" % (firstorg, ocserverdn),
+                  "objectClass": ["top", "org"],
+                  "cn": firstorg})
+        self.ldb.add({"dn": "CN=%s,CN=%s,%s" % (firstou, firstorg, ocserverdn),
+                  "objectClass": ["top", "ou"],
+                  "cn": firstou})
+
+    def lookup_server(self, cn, attributes=[]):
+        # Step 1. Search Server object
+        filter = "(&(objectClass=server)(cn=%s))" % cn
+        res = self.ldb.search("", scope=ldb.SCOPE_SUBTREE,
+                           expression=filter, attrs=attributes)
+        if len(res) != 1:
+            raise NoSuchServer(cn)
+        return res[0]
+
+    def lookup_mailbox_user(self, server, username):
+        """Check if a user already exists in openchange database.
+
+        :param server: Server object name
+        :param username: Username object
+        :return: LDB Object of the user
+        """
+        server_dn = self.lookup_server(server, []).dn
+
+        # Step 2. Search User object
+        filter = "(&(objectClass=mailbox)(cn=%s))" % (username)
+        return self.ldb.search(server_dn, scope=ldb.SCOPE_SUBTREE,
+                           expression=filter, attrs=[])
+
+    def user_exists(self, server, username):
+        """Check whether a user exists.
+
+        :param username: Username of the user
+        :param server: Server object name
+        """
+        return len(self.lookup_mailbox_user(server, username)) == 1
+
+    def get_message_attribute(self, server, attribute):
+        """Retrieve attribute value from given message database (server).
+
+        :param server: Server object name
+        """
+        return int(self.lookup_server(server, [attribute])[attribute][0], 16)
+
+    def get_message_ReplicaID(self, server):
+        """Retrieve current mailbox Replica ID for given message database (server).
+
+        :param server: Server object name
+        """
+        return self.get_message_attribute(server, "ReplicaID")
+
+    def get_message_GlobalCount(self, server):
+        """Retrieve current mailbox Global Count for given message database (server).
+
+        :param server: Server object name
+        """
+        return self.get_message_attribute(server, "GlobalCount")
+
+
+    def set_message_GlobalCount(self, server, GlobalCount):
+        """Update current mailbox GlobalCount for given message database (server).
+
+        :param server: Server object name
+        :param index: Mailbox new GlobalCount value
+        """
+        server_dn = self.lookup_server(server, []).dn
+
+        newGlobalCount = """
+dn: %s
+changetype: modify
+replace: GlobalCount
+GlobalCount: 0x%x
+""" % (server_dn, GlobalCount)
+
+        self.ldb.transaction_start()
+        try:
+            self.ldb.modify_ldif(newGlobalCount)
+        finally:
+            self.ldb.transaction_commit()
+
+    def add_mailbox_user(self, basedn, username):
+        """Add a user record in openchange database.
+
+        :param username: Username
+        :return: DN of the created object
+        """
+        
+        mailboxGUID = str(uuid.uuid4())
+        replicaID = str(1)
+        replicaGUID = str(uuid.uuid4())
+        
+        retdn = "CN=%s,%s" % (username, basedn)
+        self.ldb.add({"dn": retdn,
+                  "objectClass": ["mailbox", "container"],
+                  "cn": username,
+                  "MailboxGUID": mailboxGUID,
+                  "ReplicaID": replicaID,
+                  "ReplicaGUID": replicaGUID})
+        return retdn
+
+    def add_storage_dir(self, mapistoreURL, username):
+        """Add mapistore storage space for the user
+
+        :param username: Username object
+        :param mapistore: mapistore object
+        """
+
+        mapistore_dir = os.path.join(mapistoreURL, username)
+        if not os.path.isdir(mapistore_dir):
+            os.makedirs(mapistore_dir, mode=0700)
+    
+    def add_folder_property(self, folderID, attribute, value):
+        """Add a attribute/value to the record folderID refers to
+
+        :param folderID: the folder identifier where to add attribute/value
+        :param attribute: the ldb attribute
+        :param value: the attribute value
+        """
+
+        # Step 1. Find the folder record
+        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % folderID, ["*"])
+        if len(res) != 1:
+            raise Exception("Invalid search (PidTagFolderId=%s)" % folderID)
+
+        # Step 2. Add attribute/value pair
+        m = ldb.Message()
+        m.dn = ldb.Dn(self.ldb, "%s" % res[0].dn)
+        m[attribute] = ldb.MessageElement([value], ldb.CHANGETYPE_ADD, attribute);
+        self.ldb.modify(m)
+
+    def add_mailbox_root_folder(self, ocfirstorgdn, username, 
+                                foldername, parentfolder, 
+                                GlobalCount, ReplicaID,
+                                SystemIdx, mapistoreURL):
+        """Add a root folder to the user mailbox
+
+        :param username: Username object
+        :param foldername: Folder name
+        :param GlobalCount: current global counter for message database
+        :param ReplicaID: replica identifier for message database
+        :param SystemIdx: System Index for root folders
+        """
+
+        ocuserdn = "CN=%s,%s" % (username, ocfirstorgdn)
+        FID = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
+
+        # Step 1. If we are handling Mailbox Root
+        if parentfolder == 0:
+            m = ldb.Message()
+            m.dn = ldb.Dn(self.ldb, ocuserdn)
+            m["PidTagFolderId"] = ldb.MessageElement([FID], ldb.CHANGETYPE_ADD, "PidTagFolderId")
+            m["SystemIdx"] = ldb.MessageElement([str(SystemIdx)], ldb.CHANGETYPE_ADD, "SystemIdx")
+            m["mapistore_uri"] = ldb.MessageElement(["sqlite://%s/%s/%s.db" % (mapistoreURL, username, FID)], ldb.CHANGETYPE_ADD, "mapistore_uri")
+            self.ldb.modify(m)
+            return FID
+
+        # Step 2. Lookup parent DN
+        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % parentfolder, ["*"])
+        if len(res) != 1:
+            raise Exception("Invalid search (PidTagFolderId=%s)" % parentfolder)
+
+        # Step 3. Add root folder to correct container
+        self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
+                  "objectClass": ["systemfolder"],
+                  "cn": FID,
+                  "PidTagParentFolderId": parentfolder,
+                  "PidTagFolderId": FID,
+                  "PidTagDisplayName": foldername,
+                  "mapistore_uri": "sqlite://%s/%s/%s.db" % (mapistoreURL, username, FID),
+                  "FolderType": str(1),
+                  "SystemIdx": str(SystemIdx)})
+
+        return FID
+
+    def add_mailbox_special_folder(self, username, parentfolder, ref_fid, 
+                                   foldername, containerclass, GlobalCount, ReplicaID, 
+                                   mapistoreURL):
+        """Add a special folder to the user mailbox
+
+        :param username: Username object
+        :param parent_folder: Folder identifier where record should be added
+        :param ref_fid: Folder Identifier referring special folder
+        :param foldername: Folder name
+        :param containerclass: Folder container class
+        :param GlobalCount: current global counter for message database
+        :param ReplicaID: replica identifier for message database
+        :param mapistoreURL: mapistore default content repository URI
+        """
+
+        FID = gen_mailbox_folder_fid(GlobalCount, ReplicaID)
+
+        # Step 1. Lookup parent DN
+        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % parentfolder, ["*"])
+        if len(res) != 1:
+            raise Exception("Invalid search (PidTagFolderId=%s)" % parentfolder)
+
+        # Step 2. Add special folder to user subtree
+        self.ldb.add({"dn": "CN=%s,%s" % (FID, res[0].dn),
+                      "objectClass": ["specialfolder"],
+                      "cn": FID,
+                      "PidTagFolderId": FID,
+                      "PidTagDisplayName": foldername,
+                      "PidTagContainerClass": containerclass,
+                      "mapistore_uri": "sqlite://%s/%s/%s.db" % (mapistoreURL, username, FID),
+                      "PidTagContentCount": str(0),
+                      "PidTagContentUnreadCount": str(0),
+                      "PidTagSubFolders": str(0),
+                      "FolderType": str(1)})
+
+        return FID
+
+    def set_receive_folder(self, username, ocfirstorgdn, fid, messageclass):
+        """Set MessageClass for given folder
+
+        :param username: Username object
+        :param ocfirstorgdn: Base DN
+        :param fid: Folder identifier
+        :param messageclass: Explicit Message Class
+        """
+        
+        # Step 1. Search fid DN
+        res = self.ldb.search("", ldb.SCOPE_SUBTREE, "(PidTagFolderId=%s)" % fid, ["*"])
+        if len(res) != 1:
+            raise "Invalid search (PidTagFolderId=%s)" % fid
+
+        m = ldb.Message()
+        m.dn = res[0].dn
+        m["PidTagMessageClass"] = ldb.MessageElement([messageclass], ldb.CHANGETYPE_ADD, "PidTagMessageClass")
+        self.ldb.modify(m)
+
+
+def gen_mailbox_folder_fid(GlobalCount, ReplicaID):
+    """Generates a Folder ID from index.
+
+    :param GlobalCount: Message database global counter
+    :param ReplicaID: Message database replica identifier
+    """
+
+    folder = "0x%.12x%.4x" % (GlobalCount, ReplicaID)
+
+    return folder

Added: trunk/openchange/python/openchange/provision.py
===================================================================
--- trunk/openchange/python/openchange/provision.py	                        (rev 0)
+++ trunk/openchange/python/openchange/provision.py	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,469 @@
+#!/usr/bin/python
+
+# OpenChange provisioning
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 2008-2009
+# Copyright (C) Julien Kerihuel <j.kerihuel at openchange.org> 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/>.
+#
+
+from base64 import b64encode
+import os
+import samba
+from openchange import mailbox
+from samba import Ldb
+from samba.samdb import SamDB
+from samba.auth import system_session
+from samba.provision import setup_add_ldif, setup_modify_ldif
+import ldb
+
+__docformat__ = 'restructuredText'
+
+DEFAULTSITE = "Default-First-Site-Name"
+FIRST_ORGANIZATION = "First Organization"
+FIRST_ORGANIZATION_UNIT = "First Organization Unit"
+
+def openchangedb_url(lp):
+    return os.path.join(lp.get("private dir"), "openchange.ldb")
+
+def openchangedb_mapistore_url(lp):
+    return os.path.join(lp.get("private dir"), "mapistore");
+
+class ProvisionNames(object):
+
+    def __init__(self):
+        self.rootdn = None
+        self.domaindn = None
+        self.configdn = None
+        self.schemadn = None
+        self.dnsdomain = None
+        self.netbiosname = None
+        self.domain = None
+        self.hostname = None
+        self.firstorg = None
+        self.firstou = None
+        self.firstorgdn = None
+        # OpenChange dispatcher database specific
+        self.ocfirstorgdn = None
+        self.ocserverdn = None
+
+def guess_names_from_smbconf(lp, firstorg=None, firstou=None):
+    """Guess configuration settings to use from smb.conf.
+    
+    :param lp: Loadparm context.
+    :param firstorg: First Organization
+    :param firstou: First Organization Unit
+    """
+
+    netbiosname = lp.get("netbios name")
+    hostname = netbiosname.lower()
+
+    dnsdomain = lp.get("realm")
+    dnsdomain = dnsdomain.lower()
+
+    serverrole = lp.get("server role")
+    if serverrole == "domain controller":
+        domain = lp.get("workgroup")
+        domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
+    else:
+        domain = netbiosname
+        domaindn = "CN=" + netbiosname
+
+    rootdn = domaindn
+    configdn = "CN=Configuration," + rootdn
+    schemadn = "CN=Schema," + configdn
+    sitename = DEFAULTSITE
+
+    names = ProvisionNames()
+    names.rootdn = rootdn
+    names.domaindn = domaindn
+    names.configdn = configdn
+    names.schemadn = schemadn
+    names.dnsdomain = dnsdomain
+    names.domain = domain
+    names.netbiosname = netbiosname
+    names.hostname = hostname
+    names.sitename = sitename
+
+    if firstorg is None:
+        firstorg = FIRST_ORGANIZATION
+
+    if firstou is None:
+        firstou = FIRST_ORGANIZATION_UNIT
+
+    names.firstorg = firstorg
+    names.firstou = firstou
+    names.firstorgdn = "CN=%s,CN=Microsoft Exchange,CN=Services,%s" % (firstorg, configdn)
+    names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn)
+
+    # OpenChange dispatcher DB names
+    names.ocserverdn = "CN=%s,%s" % (names.netbiosname, names.domaindn)
+    names.ocfirstorg = firstorg
+    names.ocfirstorgdn = "CN=%s,CN=%s,%s" % (firstou, names.ocfirstorg, names.ocserverdn)
+
+    return names
+
+
+def install_schemas(setup_path, names, lp, creds):
+    """Install the OpenChange-specific schemas in the SAM LDAP database. 
+    
+    :param setup_path: Path to the setup directory.
+    :param names: provision names object.
+    :param lp: Loadparm context
+    :param creds: Credentials Context
+    """
+    session_info = system_session()
+
+    # Step 1. Extending the prefixmap attribute of the schema DN record
+    db = SamDB(url=lp.get("sam database"), session_info=session_info,
+                  credentials=creds, lp=lp)
+
+    prefixmap = open(setup_path("AD/prefixMap.txt"), 'r').read()
+
+    db.transaction_start()
+
+    try:
+        print "[+] Step 1: Register Exchange OIDs"
+        setup_modify_ldif(db,
+                          setup_path("AD/provision_schema_basedn_modify.ldif"), {
+                "SCHEMADN": names.schemadn,
+                "NETBIOSNAME": names.netbiosname,
+                "DEFAULTSITE": names.sitename,
+                "CONFIGDN": names.configdn,
+                "SERVERDN": names.serverdn,
+                "PREFIXMAP_B64": b64encode(prefixmap)
+                })
+    except:
+        db.transaction_cancel()
+        raise
+
+    db.transaction_commit()
+
+
+    # Step 2. Add new Exchange classes to the schema
+    db = SamDB(url=lp.get("sam database"), session_info=session_info, 
+                  credentials=creds, lp=lp)
+
+    db.transaction_start()
+
+    try:
+        print "[+] Step 2: Add new Exchange classes and attributes to Samba schema"
+        setup_add_ldif(db, setup_path("AD/oc_provision_schema.ldif"), { 
+                "SCHEMADN": names.schemadn
+                })
+    except:
+        db.transaction_cancel()
+        raise
+
+    db.transaction_commit()
+
+    # Step 3. Add ADSC classes to the schema
+    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"
+        setup_modify_ldif(db, setup_path("AD/oc_provision_schema_modify.ldif"), {
+                "SCHEMADN": names.schemadn
+                })
+    except:
+        db.transaction_cancel()
+        raise
+
+    db.transaction_commit()
+
+
+    # Step 4. Add configuration objects
+    db = SamDB(url=lp.get("sam database"), session_info=system_session(),
+                  credentials=creds, lp=lp)
+
+    db.transaction_start()
+
+    try:
+        print "[+] Step 5: Exchange Samba with Exchange configuration objects"
+        setup_add_ldif(db, setup_path("AD/oc_provision_configuration.ldif"), {
+                "FIRSTORG": names.firstorg,
+                "FIRSTORGDN": names.firstorgdn,
+                "CONFIGDN": names.configdn,
+                "SCHEMADN": names.schemadn,
+                "DOMAINDN": names.domaindn,
+                "DOMAIN": names.domain,
+                "DNSDOMAIN": names.dnsdomain,
+                "NETBIOSNAME": names.netbiosname,
+                "HOSTNAME": names.hostname
+                })
+    except:
+        db.transaction_cancel()
+        raise
+
+    db.transaction_commit()
+
+
+def newmailbox(lp, username, firstorg, firstou):
+    names = guess_names_from_smbconf(lp, firstorg, firstou)
+
+    db = mailbox.OpenChangeDB(openchangedb_url(lp))
+
+    # Step 1. Retrieve current FID index
+    GlobalCount = db.get_message_GlobalCount(names.netbiosname)
+    ReplicaID = db.get_message_ReplicaID(names.netbiosname)
+
+    print "[+] Mailbox for '%s'" % (username)
+    print "==================" + "=" * len(username)
+    print "* GlobalCount (0x%x) and ReplicaID (0x%x)" % (GlobalCount, ReplicaID)
+
+    # Step 2. Check if the user already exists
+    assert not db.user_exists(names.netbiosname, username)
+
+    # Step 3. Create a default mapistore content repository for this user
+    db.add_storage_dir(mapistoreURL=openchangedb_mapistore_url(lp), username=username)
+    print "* Mapistore content repository created: %s" % os.path.join(openchangedb_mapistore_url(lp), username)
+
+    # Step 4. Create the user object
+    retdn = db.add_mailbox_user(names.ocfirstorgdn, username=username)
+    print "* User object created: %s" % (retdn)
+
+    # Step 5. Create system mailbox folders for this user
+    print "* Adding System Folders"
+
+    system_folders = ({
+        "Deferred Actions": ({}, 2),
+        "Spooler Queue": ({}, 3),
+        "IPM Subtree": ({
+            "Inbox": ({}, 5),
+            "Outbox": ({}, 6),
+            "Sent Items": ({}, 7),
+            "Deleted Items": ({}, 8),
+        }, 4),
+        "Common Views": ({}, 9),
+        "Schedule": ({}, 10),
+        "Search": ({}, 11),
+        "Views": ({}, 12),
+        "Shortcuts": ({}, 13),
+    }, 1)
+
+    fids = {}
+    def add_folder(parent_fid, path, children, SystemIdx):
+        name = path[-1]
+
+        GlobalCount = db.get_message_GlobalCount(names.netbiosname)
+        ReplicaID = db.get_message_ReplicaID(names.netbiosname)
+
+        fid = db.add_mailbox_root_folder(names.ocfirstorgdn, 
+            username=username, foldername=name,
+            parentfolder=parent_fid, GlobalCount=GlobalCount, 
+            ReplicaID=ReplicaID, SystemIdx=SystemIdx, 
+            mapistoreURL=openchangedb_mapistore_url(lp))
+
+        GlobalCount += 1
+        db.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
+
+        fids[path] = fid
+
+        print "\t* %-40s: %s" % (name, fid)
+        for name, grandchildren in children.iteritems():
+            add_folder(fid, path + (name,), grandchildren[0], grandchildren[1])
+
+    add_folder(0, ("Mailbox Root",), system_folders[0], system_folders[1])
+
+    # Step 6. Add special folders
+    print "* Adding Special Folders:"
+    special_folders = [
+        (("Mailbox Root", "IPM Subtree"), "Calendar",   "IPF.Appointment",  "PidTagIpmAppointmentEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Contacts",   "IPF.Contact",      "PidTagIpmContactEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Journal",    "IPF.Journal",      "PidTagIpmJournalEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Notes",      "IPF.StickyNote",   "PidTagIpmNoteEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Tasks",      "IPF.Task",         "PidTagIpmTaskEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Reminders",  "Outlook.Reminder", "PidTagRemindersOnlineEntryId"),
+        (("Mailbox Root", "IPM Subtree"), "Drafts",     "IPF.Notes",        "PidTagIpmDraftsEntryId")
+        ]
+
+    fid_inbox = fids[("Mailbox Root", "IPM Subtree", "Inbox")]
+    fid_mailbox = fids[("Mailbox Root",)]
+    for path, foldername, containerclass, pidtag in special_folders:
+        GlobalCount = db.get_message_GlobalCount(names.netbiosname)
+        ReplicaID = db.get_message_ReplicaID(names.netbiosname)
+        fid = db.add_mailbox_special_folder(username, fids[path], fid_inbox, foldername, 
+                                            containerclass, GlobalCount, ReplicaID, 
+                                            openchangedb_mapistore_url(lp))
+        db.add_folder_property(fid_inbox, pidtag, fid)
+        db.add_folder_property(fid_mailbox, pidtag, fid)
+        GlobalCount += 1
+        db.set_message_GlobalCount(names.netbiosname, GlobalCount=GlobalCount)
+        print "\t* %-40s: %s (%s)" % (foldername, fid, containerclass)
+
+    # Step 7. Set default receive folders
+    print "* Adding default Receive Folders:"
+    receive_folders = [
+        (("Mailbox Root", "IPM Subtree", "Inbox"), "All"),
+        (("Mailbox Root", "IPM Subtree", "Inbox"), "IPM"),
+        (("Mailbox Root", "IPM Subtree", "Inbox"), "Report.IPM"),
+        (("Mailbox Root", "IPM Subtree",), "IPC")
+        ]
+    
+    for path, messageclass in receive_folders:
+        print "\t* %-40s Message Class added to %s" % (messageclass, fids[path])
+        db.set_receive_folder(username, names.ocfirstorgdn, fids[path], 
+                              messageclass)
+
+    # Step 8. Set additional properties on Inbox
+    print "* Adding additional default properties to Inbox"
+    db.add_folder_property(fid_inbox, "PidTagContentCount", "0")
+    db.add_folder_property(fid_inbox, "PidTagContentUnreadCount", "0")
+    db.add_folder_property(fid_inbox, "PidTagSubFolders", "FALSE")
+    db.add_folder_property(fid_inbox, "PidTagAccess", "63")
+
+    GlobalCount = db.get_message_GlobalCount(names.netbiosname)
+    print "* GlobalCount (0x%x)" % GlobalCount
+
+
+def newuser(lp, creds, username=None):
+    """extend user record with OpenChange settings.
+    
+    :param lp: Loadparm context
+    :param creds: Credentials context
+    :param username: Name of user to extend
+    """
+
+    names = guess_names_from_smbconf(lp, None, None)
+
+    db = Ldb(url="users.ldb", session_info=system_session(),
+                  credentials=creds, lp=lp)
+
+    user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)
+
+    extended_user = """
+dn: %s
+changetype: modify
+add: displayName
+add: auxiliaryClass
+add: mailNickName
+add: homeMDB
+add: legacyExchangeDN
+add: proxyAddresses
+replace: msExchUserAccountControl
+displayName: %s
+auxiliaryClass: msExchBaseClass
+mailNickname: %s
+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
+legacyExchangeDN: /o=%s/ou=First Administrative Group/cn=Recipients/cn=%s
+proxyAddresses: smtp:postmaster@%s
+proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=%s
+proxyAddresses: SMTP:%s@%s
+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)
+
+    print "[+] User %s extended and enabled" % username
+
+
+def accountcontrol(lp, creds, username=None, value=0):
+    """enable/disable an OpenChange user account.
+
+    :param lp: Loadparm context
+    :param creds: Credentials context
+    :param username: Name of user to disable
+    :param value: the control value
+    """
+
+    names = guess_names_from_smbconf(lp, None, None)
+
+    db = Ldb(url="users.ldb", session_info=system_session(),
+                  credentials=creds, lp=lp)
+
+    user_dn = "CN=%s,CN=Users,%s" % (username, names.domaindn)
+    extended_user = """
+dn: %s
+changetype: modify
+replace: msExchUserAccountControl
+msExchUserAccountControl: %d
+""" % (user_dn, value)
+    db.modify_ldif(extended_user)
+    if value == 2:
+        print "[+] Account %s disabled" % username
+    else:
+        print "[+] Account %s enabled" % username
+
+
+def provision(setup_path, lp, creds, firstorg=None, firstou=None):
+    """Extend Samba4 with OpenChange data.
+    
+    :param setup_path: Path to the setup directory
+    :param lp: Loadparm context
+    :param creds: Credentials context
+    :param firstorg: First Organization
+    :param firstou: First Organization Unit
+    """
+    names = guess_names_from_smbconf(lp, firstorg, firstou)
+
+    print "NOTE: This operation can take several minutes"
+
+    # Install OpenChange-specific schemas
+    install_schemas(setup_path, names, lp, creds)
+
+
+def openchangedb_provision(lp, firstorg=None, firstou=None):
+    """Create the OpenChange database.
+
+    :param lp: Loadparm context
+    :param firstorg: First Organization
+    :param firstou: First Organization Unit
+    """
+    names = guess_names_from_smbconf(lp, firstorg, firstou)
+    
+    print "Setting up openchange db"
+    openchange_ldb = mailbox.OpenChangeDB(openchangedb_url(lp))
+    openchange_ldb.setup()
+
+    # Add a server object
+    # It is responsible for holding the GlobalCount identifier (48 bytes)
+    # and the Replica identifier
+    openchange_ldb.add_server(names.ocserverdn, names.netbiosname, 
+        names.firstorg, names.firstou)
+
+
+def find_setup_dir():
+    """Find the setup directory used by provision."""
+    dirname = os.path.dirname(__file__)
+    if "/site-packages/" in dirname:
+        prefix = dirname[:dirname.index("/site-packages/")]
+        for suffix in ["share/openchange/setup", "share/setup", "share/samba/setup", "setup"]:
+            ret = os.path.join(prefix, suffix)
+            if os.path.isdir(ret):
+                return ret
+    # In source tree
+    ret = os.path.join(dirname, "../../setup")
+    if os.path.isdir(ret):
+        return ret
+    raise Exception("Unable to find setup directory.")

Added: trunk/openchange/python/openchange/tests/test_mailbox.py
===================================================================
--- trunk/openchange/python/openchange/tests/test_mailbox.py	                        (rev 0)
+++ trunk/openchange/python/openchange/tests/test_mailbox.py	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+
+# OpenChange provisioning
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+from openchange.mailbox import NoSuchServer, OpenChangeDB, gen_mailbox_folder_fid
+
+import os
+import unittest
+
+class OpenChangeDBTests(unittest.TestCase):
+    """Tests for OpenChangeDB."""
+
+    def setUp(self):
+        if os.path.exists("openchange.ldb"):
+            os.unlink("openchange.ldb")
+        self.db = OpenChangeDB("openchange.ldb") 
+        self.db.setup()
+
+    def test_user_exists_no_server(self):
+        self.assertRaises(NoSuchServer, self.db.user_exists, "someserver", "foo")
+
+    def test_server_lookup_doesnt_exist(self):
+        self.assertRaises(NoSuchServer, self.db.lookup_server, 
+            "nonexistantserver")
+
+    def test_server_lookup(self):
+        self.db.add_server("dc=blaserver", "blaserver", "firstorg", "firstou")
+        self.assertEquals("dc=blaserver", str(self.db.lookup_server("blaserver")['dn']))
+
+    def test_add_mailbox_user(self):
+        self.db.add_server("cn=myserver", "myserver", "firstorg", "firstou")
+        self.db.add_mailbox_user("cn=firstorg,cn=firstou,cn=myserver", "someuser")
+        self.assertTrue(self.db.user_exists("myserver", "someuser"))
+
+    def test_msg_globalcount_initial(self):
+        self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou")
+        self.assertEquals(1, self.db.get_message_GlobalCount("myserver"))
+
+    def test_set_msg_globalcount(self):
+        self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou")
+        self.db.set_message_GlobalCount("myserver", 42)
+        self.assertEquals(42, self.db.get_message_GlobalCount("myserver"))
+
+    def test_msg_replicaid_initial(self):
+        self.db.add_server("dc=myserver", "myserver", "firstorg", "firstou")
+        self.assertEquals(1, self.db.get_message_ReplicaID("myserver"))
+
+
+class MailboxFIDTests(unittest.TestCase):
+    
+    def test_simple(self):
+        self.assertEquals("0x00000000109282806", gen_mailbox_folder_fid(4242, 534534))
+

Added: trunk/openchange/python/openchange/tests/test_provision.py
===================================================================
--- trunk/openchange/python/openchange/tests/test_provision.py	                        (rev 0)
+++ trunk/openchange/python/openchange/tests/test_provision.py	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+
+# OpenChange provisioning
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+from samba import param
+from samba.credentials import Credentials
+from samba.samdb import SamDB
+from samba.tests import TestCaseInTempDir
+from samba.tests.samdb import SamDBTestCase
+from openchange.provision import install_schemas, openchangedb_provision, guess_names_from_smbconf, find_setup_dir
+
+import os
+import unittest
+
+class ExtendedSamDBTestCase(SamDBTestCase):
+
+    def test_install_schemas(self):
+        def setup_path(relpath):
+            return os.path.join(find_setup_dir(), relpath)
+
+        names = guess_names_from_smbconf(self.lp)
+        creds = Credentials()
+        creds.set_anonymous()
+        self.lp.set("sam database", os.path.join(self.tempdir, "samdb.ldb"))
+        install_schemas(setup_path, names, self.lp, creds)
+
+
+class OpenChangeDBProvisionTestCase(TestCaseInTempDir):
+
+    def test_provision(self):
+        lp = param.LoadParm()
+        lp.load_default()
+        lp.set("private dir", self.tempdir)
+        openchangedb_provision(lp)
+        os.unlink(os.path.join(self.tempdir, "openchange.ldb"))

Added: trunk/openchange/script/check_exchange
===================================================================
--- trunk/openchange/script/check_exchange	                        (rev 0)
+++ trunk/openchange/script/check_exchange	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,191 @@
+#!/usr/bin/perl
+#
+# Nagois Plug-In to check Exchange Server
+#
+# Bill Edmunds, Academic Services, University of Exeter
+# 25th March, 2008
+#
+
+use strict;
+use lib "nagios/plugins";
+use utils qw($TIMEOUT %ERRORS &print_revision &support);
+use vars qw($PROGNAME);
+use Time::HiRes qw(gettimeofday tv_interval);
+
+# Variables
+$PROGNAME = 'check_exchange';
+my $SUCCESS = 'MAPI_E_SUCCESS';
+my $MYTIME = 10;
+my $version = "1.0";
+my $verbose = 0;
+my $pdb = '/usr/lib/nagios/plugins/check_exchange.ldb';
+my $cmd = 'openchangeclient';
+my $author = "Bill Edmunds, Academic Services, University of Exeter";
+my $email = 'W.Edmunds at exeter.ac.uk';
+my ($host, $stime, $etime, $warning, $critical);
+our($opt_h, $opt_V, $opt_v, $opt_H, $opt_d, $opt_w, $opt_c);
+my $status = 'UNKNOWN';
+
+$ENV{'BASH_ENV'}=''; 
+$ENV{'ENV'}='';
+$ENV{'PATH'}='/usr/local/samba/bin';
+$ENV{'LC_ALL'}='C';
+
+# Options
+use Getopt::Long;
+Getopt::Long::Configure('bundling');
+GetOptions(
+        "V"   => \$opt_V, "version"    => \$opt_V,
+        "h"   => \$opt_h, "help"       => \$opt_h,
+        "v+"  => \$opt_v, "verbose+"   => \$opt_v,
+        "H=s" => \$opt_H, "hostname=s" => \$opt_H,
+        "d=s" => \$opt_d, "database=s" => \$opt_d,
+        "w=f" => \$opt_w, "warning=f"  => \$opt_w,
+        "c=f" => \$opt_c, "critical=f" => \$opt_c,
+);
+
+# -h means help
+if ($opt_h) {
+    print_help();
+    exit $ERRORS{'OK'};
+}
+
+# -V means version
+if ($opt_V) {
+    print_revision($PROGNAME, "\$Revision: $version \$ ");
+    exit $ERRORS{'OK'};
+}
+
+# -v means verbose
+if ($opt_v) {
+    $verbose = 1;
+    print "$PROGNAME: Check access to MS Exchange via Openchange client\n\n";
+}
+
+# -H means host/profile name
+$opt_H || plugin_error("No hostname specified");
+
+if (! utils::is_hostname($opt_H)){
+        plugin_error("$opt_H is not a valid host name");
+} else {
+        $host = $opt_H;
+}
+
+# -d means profile database name
+if (defined($opt_d) && -r $opt_d) {
+    $pdb = $opt_d;
+} else {
+    plugin_error("No profile database available") if ! -r $pdb;
+}
+
+$verbose && print "$PROGNAME: Profile database is $pdb\n\n";
+
+# -c means critical threshold
+if ($opt_c && $opt_c =~ /^\d+\.*\d*$/ && $opt_c < $TIMEOUT) {
+        $critical = $opt_c;
+} else {
+        plugin_error("Specify critical threshold 0.1 - $TIMEOUT");
+}
+
+# -w means warning threshold
+if ($opt_w =~ /^\d+\.*\d*/ && $opt_w < $critical) {
+        $warning = $opt_w;
+} else {
+        plugin_error("Specify warning threshold 0.0 - $critical");
+}
+
+# Timeout
+if (defined($TIMEOUT)) {
+  $verbose && print "$PROGNAME: Alarm set at $TIMEOUT\n\n";
+  alarm($TIMEOUT);
+} else {
+  $verbose && print "$PROGNAME: Alarm set at $MYTIME\n\n";
+  alarm($MYTIME);
+}
+
+$stime = [gettimeofday];
+$verbose && print "$PROGNAME: Running $cmd -f $pdb -p $host -F\n\n";
+open(CMD, "$cmd -f $pdb -p $host -F |") || plugin_error("Can't run openchangeclient");
+while(<CMD>) {
+    if ($verbose > 1)  { print "$PROGNAME: $_"; }
+    $status = 'OK' if /$SUCCESS/io;
+    last if $status eq 'OK';
+}
+$etime = tv_interval($stime);
+
+$status = 'CRITICAL' if ($etime >= $critical || $status eq 'UNKNOWN');
+$status = 'WARNING' if ($etime >= $warning && $status ne 'CRITICAL');
+
+$verbose && print "$PROGNAME: status $status\n\n";
+
+#print "Elapsed time: $etime|time=$etime\n";
+# update to include measurement unit for Centreon graphs
+printf "Elapsed time: %s|time=%ss\n",$etime,$etime;
+
+exit $ERRORS{"$status"};
+
+# print_usage: Print usage information
+sub print_usage {
+    print <<EndOfUsage
+Usage: 
+ $PROGNAME -H HOSTNAME [-d DATABASE] -w WTIME -c CTIME [-v]
+ $PROGNAME [-h | --help]
+ $PROGNAME [-V | --version]
+EndOfUsage
+}
+
+# print_help: Print help information
+sub print_help {
+    print_revision($PROGNAME, "\$Revision: $version \$ ");
+    print <<EndOfHelp;
+
+Author: $author
+$email
+License: GNU General Public License
+
+$PROGNAME: Check access to MS Exchange via Openchange client
+
+EndOfHelp
+    print_usage();
+    print <<EndOfHelp;
+
+Options:
+ -h, --help
+    Print detailed help screen.
+ -V, --version
+    Print version information.
+ -v, --verbose
+    Print verbose information.
+ -H HOSTNAME, --hostname=HOSTNAME
+    Use HOSTNAME as the MS Exchange host (Note: this is actually the
+    profile name within the Openchange profile database. The associated
+    host information is stored against the profile information).
+ -d DATABASE, --database=DATABASE
+    Use DATABASE as the profile database (Note: the profile name
+    should match the HOSTNAME above).
+ -w WTIME, --warning=WTIME
+    Exit with WARNING status if time exceeds WTIME.
+ -c CTIME, --critical=CTIME
+    Exit with CRITICAL status if time exceeds CTIME.
+
+Profile database:
+    Location currently set to:
+       $pdb
+
+Created using:
+    mapiprofile -f <DATABASE> -P <HOSTNAME> -u <USERNAME> -p <PASSWORD> -M LOCALHOST
+                -D <DOMAIN> -I <IPADDRESS> -c
+
+Note that HOSTNAME is strictly the profile name, and the host connection is really derived
+from the IPADDRESS.
+
+The author wishes to offer thanks to the OpenChange team at: openchange.org
+EndOfHelp
+}
+
+sub plugin_error {
+    my $msg = $_[0];
+    print STDERR "$PROGNAME: $msg\n";
+    print_usage();
+    exit $ERRORS{'UNKNOWN'};
+}


Property changes on: trunk/openchange/script/check_exchange
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/script/installman.sh
===================================================================
--- trunk/openchange/script/installman.sh	                        (rev 0)
+++ trunk/openchange/script/installman.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+MANDIR=$1
+shift 1
+MANPAGES=$*
+
+for I in $MANPAGES
+do
+	SECTION=`echo $I | grep -o '.$'`
+	DIR="$MANDIR/man$SECTION"
+	if [ ! -d "$DIR" ]
+	then
+		mkdir -p "$DIR"
+	fi
+
+	BASE=`basename $I`
+	
+	echo "Installing manpage \"$BASE\" in $DIR"
+	cp $I $DIR
+done
+
+cat << EOF
+======================================================================
+The man pages have been installed. You may uninstall them using the command
+the command "make uninstallman" or make "uninstall" to uninstall binaries,
+man pages and shell scripts.
+======================================================================
+EOF
+
+exit 0


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

Added: trunk/openchange/script/installoc.sh
===================================================================
--- trunk/openchange/script/installoc.sh	                        (rev 0)
+++ trunk/openchange/script/installoc.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,18 @@
+#!/bin/sh
+# install OpenChange miscellaneous files
+
+SRCDIR="$1"
+JSDIR="$2"
+SETUPDIR="$3"
+
+cd $SRCDIR || exit 1
+
+echo "Installing OpenChange js libs.."
+cp libmapi/setup/scripting/libjs/*.js $JSDIR || exit 1
+echo "Done.."
+
+echo "Installing OpenChange setup templates.."
+cp libmapi/setup/*.ldif $SETUPDIR || exit 1
+echo "All Ok"
+
+exit 0


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

Added: trunk/openchange/script/installsamba4.sh
===================================================================
--- trunk/openchange/script/installsamba4.sh	                        (rev 0)
+++ trunk/openchange/script/installsamba4.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,400 @@
+#!/bin/sh
+
+#
+# VARS
+#
+. `dirname $0`/samba4_ver.sh
+
+if which gmake 2>/dev/null; then
+	MAKE=gmake
+else
+	MAKE=make
+fi
+
+/usr/bin/env -i PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/samba/lib/pkgconfig
+
+RUNDIR=`dirname $0`
+HOST_OS=`$RUNDIR/../config.guess`
+
+#
+# Error check
+#
+error_check() {
+    error=$1
+    step=$2
+
+    if [ $error -ne 0 ]; then
+	echo "Error in $2 (error code $1)"
+	exit 1
+    fi
+}
+
+cleanup_talloc() {
+    # cleanup existing talloc installation
+    if test -f samba4/lib/talloc/Makefile; then
+	echo "Step0: cleaning up talloc directory"
+	OLD_PWD=$PWD
+	cd samba4/lib/talloc
+	make realdistclean
+	cd $OLD_PWD
+    fi
+}
+
+cleanup_tdb() {
+    # cleanup existing tdb installation
+    if test -f samba/lib/tdb/Makefile; then
+	echo "Step0: cleaning up tdb directory"
+	OLD_PWD=$PWD
+	cd samba4/lib/tdb
+	make realdistclean
+	cd $OLD_PWD
+    fi
+}
+
+delete_install() {
+
+    # cleanup existing existing samba4 installation
+    if test -d /usr/local/samba; then
+	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
+	echo "A previous samba4 installation has been detected"
+	echo "It is highly recommended to delete it prior compiling Samba4"
+	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
+	echo ""
+	echo -n "Proceed? [Yn]: "
+	read answer
+	case "$answer" in
+	    Y|y|yes)
+		echo "Step0: Removing previous samba4 installation"
+		sudo rm -rf /usr/local/samba
+		;;
+	    N|n|no)
+		echo "Step0: Keep previous samba4 installation"
+		;;
+	esac
+    fi
+
+	cleanup_talloc
+	cleanup_tdb
+}
+
+#
+# Checkout Samba4
+#
+checkout() {
+    OLD_PWD=$PWD
+
+    GITPATH=`whereis -b git`
+
+    if test x"$GITPATH" = x"git:"; then
+	echo "git was not found in your path!"
+	echo "Please install git"
+	exit 1
+    fi
+
+    echo "Step1: Fetching Samba4 latest GIT revision"
+    git clone git://git.samba.org/samba.git samba4
+    error_check $? "Step1"
+
+    echo "Step2: Creating openchange local copy"
+    cd samba4
+    git checkout -b openchange origin/master
+    error_check $? "Step2"
+
+    echo "Step3: Revert to commit $SAMBA4_GIT_REV"
+    git reset --hard $SAMBA4_GIT_REV
+    error_check $? "Step3"
+
+    cd $OLD_PWD
+    return $?
+}
+
+#
+# Download Samba4 release
+#
+download() {
+    OLD_PWD=$PWD
+
+    WGETPATH=`whereis -b wget`
+    TARPATH=`whereis -b tar`
+
+    if test x"$WGETPATH" = x"wget:"; then
+	echo "wget was not found in your path!"
+	echo "Please install wget"
+	exit 1
+    fi
+
+    if test x"$TARPATH" = x"tar:"; then
+	echo "tar was not found in your path!"
+	echo "Please install tar"
+	exit 1
+    fi
+
+    echo "Step0: Checking for previous samba4 directory"
+    if test -d samba4; then
+	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
+	echo "A previous samba4 directory has been detected in current folder."
+	echo "Should we delete the existing samba4 directory?"
+	echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
+	echo ""
+	echo -n "Proceed? [Yn]: "
+	read answer
+	case "$answer" in
+	    Y|y|yes)
+		echo "Step0: removing previous samba4 directory"
+		sudo rm -rf samba4
+		;;
+	    N|n|no)
+		echo "Step0: Keep existing directory"
+		return
+		;;
+	esac
+    fi
+
+    echo "Step2: Fetching samba-$SAMBA4_RELEASE tarball"
+    if ! test -e samba-$SAMBA4_RELEASE.tar.gz; then
+	rm -rf samba-$SAMBA4_RELEASE.tar.gz
+	wget http://us1.samba.org/samba/ftp/samba4/samba-$SAMBA4_RELEASE.tar.gz
+	error_check $? "Step1"
+    fi     
+
+    echo "Step3: Extracting $SAMBA4_RELEASE"
+    tar xzvf samba-$SAMBA4_RELEASE.tar.gz
+    error_check $? "Step2"
+    mv samba-$SAMBA4_RELEASE samba4
+
+    cd $OLD_PWD
+    return $?
+}
+
+#
+# Apply patches to samba4
+#
+patch() {
+    case "$HOST_OS" in
+	*freebsd*)
+
+	    echo "[+] Patching tevent for FreeBSD"
+	    OLD_PWD=$PWD
+	    cd samba4/lib/tevent
+	    sed 's/\$(PYTHON_CONFIG) --libs/\$(PYTHON_CONFIG) --ldflags/g' tevent.mk > tevent.mk2
+	    mv tevent.mk2 tevent.mk
+	    cd $OLD_PWD
+
+	    echo "[+] Patching heimdal for FreeBSD"
+	    OLD_PWD=$PWD
+	    cd samba4/source4/heimdal/lib/roken
+	    sed "s/#if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__)/#if defined(HAVE_OPENPTY) || defined(__linux) || defined(__osf__) || defined(__FreeBSD__)/g" rkpty.c > rkpty2.c
+	    mv rkpty2.c rkpty.c
+	    sed -e "54i\\
+#if defined(__FreeBSD__)\\
+#include <sys/ioctl.h>\\
+#include <termios.h>\\
+#include <libutil.h>\\
+#endif" rkpty.c > rkpty2.c
+	    mv rkpty2.c rkpty.c
+	    cd $OLD_PWD
+	    ;;
+    esac
+
+    return $?
+}
+
+#
+# Compile and Install samba4 packages:
+# talloc, tdb
+#
+packages() {
+    OLD_PWD=$PWD
+
+    delete_install
+
+    echo "Step1: Installing talloc library"
+    cd samba4/lib/talloc
+    error_check $? "Step1"
+
+    ./autogen.sh
+    error_check $? "Step1"
+
+    ./configure --prefix=/usr/local/samba
+    error_check $? "Step1"
+
+    make
+    error_check $? "Step1"
+
+    sudo make install
+    error_check $? "Step1"
+
+    make realdistclean
+    error_check $? "Step1"
+
+    cd $OLD_PWD
+
+    echo "Step2: Installing tdb library"
+
+    cd samba4/lib/tdb
+    error_check $? "Step2"
+
+    ./autogen.sh
+    error_check $? "Step2"
+
+    ./configure --prefix=/usr/local/samba
+    error_check $? "Step2"
+
+    make
+    error_check $? "Step2"
+
+    sudo make install
+    error_check $? "Step2"
+
+    make realdistclean
+    error_check $? "Step2"
+
+    cd $OLD_PWD
+
+    echo "Step3: Installing tevent library"
+
+    cd samba4/lib/tevent
+    error_check $? "Step3"
+
+    ./autogen.sh
+    error_check $? "Step3"
+
+    ./configure --prefix=/usr/local/samba
+    error_check $? "Step3"
+
+    make
+    error_check $? "Step3"
+
+    sudo make install
+    error_check $? "Step3"
+
+    make realdistclean
+    error_check $? "Step3"
+
+    cd $OLD_PWD
+}
+
+#
+# Compile Samba4
+#
+compile() {
+
+    OLD_PWD=$PWD
+
+    # Cleanup tdb and talloc directories
+    cleanup_talloc
+    cleanup_tdb
+
+    echo "Step1: Preparing Samba4 system"
+    cd samba4/source4
+    error_check $? "Step1"
+
+    ./autogen.sh
+    error_check $? "Step1"
+
+    ./configure.developer --enable-debug
+    error_check $? "Step1"
+
+    echo "Step2: Compile Samba4 (IDL)"
+    $MAKE idl_full
+
+    echo "Step3: Compile Samba4 (Source)"
+   	$MAKE 
+    error_check $? "Step3"
+
+    cd $OLD_PWD
+}
+
+#
+# Post install operations
+#
+post_install() {
+    case "$HOST_OS" in
+	*freebsd*)
+	    OLD_PWD=$PWD
+	    cd samba4/pidl
+	    sudo $MAKE install
+	    error_check $? "Step 1"
+	    cd $OLD_PWD
+            echo "[+] Add comparison_fn_t support to ndr.h header file"
+            OLD_PWD=$PWD
+            cd /usr/local/samba/include
+            sudo sed -e "34i\\
+#if defined(__FreeBSD__)\\
+# ifndef HAVE_COMPARISON_FN_T\\
+typedef int (*comparison_fn_t)(const void *, const void *);\\
+# endif\\
+#endif" ndr.h > /tmp/ndr.h
+            sudo mv /tmp/ndr.h ndr.h
+            cd $OLD_PWD
+	    ;;
+    esac
+}
+
+#
+# Install Samba4
+#
+install() {
+
+    OLD_PWD=$PWD
+
+    echo "Step1: Installing Samba"
+    echo "===> we are in $PWD"
+    cd samba4/source4
+    error_check $? "Step1"
+
+    sudo $MAKE install
+    error_check $? "Step1"
+
+    cd $OLD_PWD
+}
+
+
+#
+# main program
+#
+case $1 in
+    checkout)
+	checkout
+	;;
+    download)
+	download
+	;;
+    patch)
+	patch
+	;;
+    packages)
+	packages
+	;;
+    compile)
+	compile
+	;;
+    install)
+	install
+	;;
+    post_install)
+	post_install
+	;;
+    git-all)
+	checkout
+	patch
+	packages
+	compile
+	install
+	post_install
+	;;
+    all)
+	download
+	patch
+	packages
+	compile
+	install
+	post_install
+	;;
+    *)
+	echo $"Usage: $0 {checkout|patch|packages|compile|install|post_install|git-all}"
+	echo $"Usage: $0 {download|patch|packages|compile|install|post_install|all}"
+	;;
+esac
+
+exit 0


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

Added: trunk/openchange/script/mapi_object_init.prop
===================================================================
--- trunk/openchange/script/mapi_object_init.prop	                        (rev 0)
+++ trunk/openchange/script/mapi_object_init.prop	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,31 @@
+void
+uno_check(void)
+{	/* warning, named args to select() are currently not supported */
+
+	if (select("mapi_object_init", FCALL, NONE))	/* unmarked symbols of type function call */
+	{	if (select("", USE, NONE))		/* unmarked symbols USEd in those stmnts */
+		{	if (match(1, DEF, NONE))	/* are there matching symbols with mark 1? */
+				error("mapi_object_init follows mapi_object_init");
+			else
+				mark(1);		/* mark 1 */
+		}
+	}
+
+	if (select("mapi_object_release", FCALL, NONE))
+	{	if (select("", USE, NONE))
+		{	if (match(1, USE, NONE))
+				unmark();		/* remove mark */
+			else
+				error("mapi_object_release without mapi_object_init");
+		} else
+			error("no argument to mapi_object_release");
+	}
+
+	if (path_ends())
+	{	if (marked(1, ANY, NONE))
+		{	if (known_zero())
+				no_error();
+			else
+				error("mapi_object_init without mapi_object_release");
+	}	}
+}

Added: trunk/openchange/script/mkproto.pl
===================================================================
--- trunk/openchange/script/mkproto.pl	                        (rev 0)
+++ trunk/openchange/script/mkproto.pl	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,287 @@
+#!/usr/bin/perl
+# Simple script for generating prototypes for C functions
+# Written by Jelmer Vernooij
+# based on the original mkproto.sh by Andrew Tridgell
+
+use strict;
+
+# don't use warnings module as it is not portable enough
+# use warnings;
+
+use Getopt::Long;
+
+#####################################################################
+# read a file into a string
+
+my $public_file = undef;
+my $private_file = undef;
+my $public_define = undef;
+my $private_define = undef;
+my $_public = "";
+my $_private = "";
+my $public_data = \$_public;
+my $private_data = \$_private;
+
+sub public($)
+{
+	my ($d) = @_;
+	$$public_data .= $d;
+}
+
+sub private($)
+{
+	my ($d) = @_;
+	$$private_data .= $d;
+}
+
+sub usage()
+{
+	print "Usage: mkproto.pl [options] [c files]\n";
+	print "OPTIONS:\n";
+	print "  --public=FILE          Write prototypes for public functions to FILE\n";
+	print "  --private=FILE         Write prototypes for private functions to FILE\n";
+	print "  --define=DEF           Use DEF to check whether header was already included\n";
+	print "  --public-define=DEF    Same as --define, but just for public header\n";
+	print "  --private-define=DEF   Same as --define, but just for private header\n";
+	print "  --help                 Print this help message\n\n";
+	exit 0;
+}
+
+GetOptions(
+	'public=s' => sub { my ($f,$v) = @_; $public_file = $v; },
+	'private=s' => sub { my ($f,$v) = @_; $private_file = $v; },
+	'define=s' => sub { 
+		my ($f,$v) = @_; 
+		$public_define = $v; 
+		$private_define = "$v\_PRIVATE"; 
+	},
+	'public-define=s' => \$public_define,
+	'private-define=s' => \$private_define,
+	'help' => \&usage
+) or exit(1);
+
+if (not defined($public_define) and defined($public_file)) {
+	$public_define = ".." . uc($public_file) . "__";
+	$public_define =~ tr{./}{__};
+} elsif (not defined($public_define)) {
+	$public_define = '_PROTO_H_';
+}
+
+if (not defined($private_define) and defined($private_file)) {
+	$private_define = "__" . uc($private_file) . "__";
+	$private_define =~ tr{./}{__};
+} elsif (not defined($public_define)) {
+	$public_define = '_PROTO_H_';
+}
+
+if ((defined($private_file) and defined($public_file) and ($private_file eq $public_file)) or 
+	(not defined($private_file) and not defined($public_file))) {
+	$private_data = $public_data;
+}
+
+sub file_load($)
+{
+    my($filename) = shift;
+    local(*INPUTFILE);
+    open(INPUTFILE, $filename) || return undef;
+    my($saved_delim) = $/;
+    undef $/;
+    my($data) = <INPUTFILE>;
+    close(INPUTFILE);
+    $/ = $saved_delim;
+    return $data;
+}
+
+sub print_header($$)
+{
+	my ($file, $header_name) = @_;
+	$file->("#ifndef $header_name\n");
+	$file->("#define $header_name\n\n");
+	$file->("#undef _PRINTF_ATTRIBUTE\n");
+	$file->("#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)\n\n");
+	$file->("#ifndef __BEGIN_DECLS\n");
+	$file->("#ifdef __cplusplus\n");
+	$file->("#define __BEGIN_DECLS		extern \"C\" {\n");
+	$file->("#define __END_DECLS		}\n");
+	$file->("#else\n");
+	$file->("#define __BEGIN_DECLS\n");
+	$file->("#define __END_DECLS\n");
+	$file->("#endif\n");
+	$file->("#endif\n");
+	$file->("\n__BEGIN_DECLS\n\n");
+	$file->("/* This file was automatically generated by mkproto.pl. DO NOT EDIT */\n\n");
+}
+
+sub print_footer($$) 
+{
+	my ($file, $header_name) = @_;
+	$file->("\n__END_DECLS\n\n");
+	$file->("#undef _PRINTF_ATTRIBUTE\n");
+	$file->("#define _PRINTF_ATTRIBUTE(a1, a2)\n");
+	$file->("\n#endif /* $header_name */\n\n");
+}
+
+sub handle_loadparm($$) 
+{
+	my ($file,$line) = @_;
+
+	if ($line =~ /^_PUBLIC_ FN_(GLOBAL|LOCAL)_(CONST_STRING|STRING|bool|CHAR|INTEGER|LIST)\((\w+),.*\)/o) {
+		my $scope = $1;
+		my $type = $2;
+		my $name = $3;
+
+		my %tmap = (
+			    "bool" => "bool ",
+			    "CONST_STRING" => "const char *",
+			    "STRING" => "const char *",
+			    "INTEGER" => "int ",
+			    "CHAR" => "char ",
+			    "LIST" => "const char **",
+			    );
+
+		my %smap = (
+			    "GLOBAL" => "void",
+			    "LOCAL" => "int "
+			    );
+
+		$file->("$tmap{$type}$name($smap{$scope});\n");
+	}
+}
+
+sub delete_arguments($)
+{
+	my ($proto) = @_;
+
+	chomp($proto);
+
+	# If function with void argument do not process it
+	return $proto if ($proto =~ /\(void\)/);
+
+	# Remove the argument name
+	$proto =~ s/([\w],[\s])*([\*]*)(\w)*([\,\)])/$1$2$4/g;
+
+	# Remove extra space between type and sep
+	$proto =~ s/([\w]+)([\s]+)([\,\)])/$1$3/g;
+
+	# Remove any spaces between , and the next char
+	$proto =~ s/([\,])(^[\w]+)([\w\)]+)/$1 $3/g;
+	
+	# Remove tabulations
+	$proto =~ s/[\s]{2,}//g;
+
+	# Remove \n
+	$proto =~ s/[\n]+/ /g;
+
+	return $proto;
+}
+
+sub process_file($$$) 
+{
+	my ($public_file, $private_file, $filename) = @_;
+
+	$filename =~ s/\.o$/\.c/g;
+
+	open(FH, "< $filename") || die "Failed to open $filename";
+
+	$private_file->("\n/* The following definitions come from $filename  */\n\n");
+
+	while (my $line = <FH>) {	      
+		my $target = \&private;
+		my $is_public = 0;
+
+		# these are ordered for maximum speed
+		next if ($line =~ /^\s/);
+	      
+		next unless ($line =~ /\(/);
+
+		next if ($line =~ /^\/|[;]/);
+
+		if ($line =~ /^_PUBLIC_ FN_/) {
+			handle_loadparm($public_file, $line);
+			next;
+		}
+
+		if ($line =~ /^_PUBLIC_[\t ]/) {
+			$target = \&public;
+			$is_public = 1;
+		}
+
+		next unless ( $is_public || $line =~ /
+			      ^void|^bool|^int|^struct|^char|^const|^\w+_[tT]\s|^uint|^unsigned|^long|
+			      ^NTSTATUS|^ADS_STATUS|^enum\s.*\(|^DATA_BLOB|^WERROR|^XFILE|^FILE|^DIR|
+			      ^double|^TDB_CONTEXT|^TDB_DATA|^TALLOC_CTX|^NTTIME|^FN_|^init_module|
+			      ^GtkWidget|^GType|^smb_ucs2_t
+			      /xo);
+
+		next if ($line =~ /^int\s*main/);
+
+		if ( $line =~ /\(.*\)\s*$/o ) {
+			chomp $line;
+			$line = delete_arguments($line);
+			$target->("$line;\n");
+			next;
+		}
+
+		$line = delete_arguments($line);
+		$target->($line);
+
+		while ($line = <FH>) {
+			if ($line =~ /\)\s*$/o) {
+				chomp $line;
+				$line = delete_arguments($line);
+				$target->("$line;\n");
+				last;
+			}
+			$target->($line);
+		}
+	}
+
+	close(FH);
+}
+
+print_header(\&public, $public_define);
+if ($public_file ne $private_file) {
+	print_header(\&private, $private_define);
+
+	private("/* this file contains prototypes for functions that " .
+			"are private \n * to this subsystem or library. These functions " .
+			"should not be \n * used outside this particular subsystem! */\n\n");
+
+	public("/* this file contains prototypes for functions that " . 
+			"are part of \n * the public API of this subsystem or library. */\n\n");
+
+}
+
+public("#ifndef _PUBLIC_\n#define _PUBLIC_\n#endif\n\n");
+
+process_file(\&public, \&private, $_) foreach (@ARGV);
+print_footer(\&public, $public_define);
+if ($public_file ne $private_file) {
+	print_footer(\&private, $private_define);
+}
+
+if (not defined($public_file)) {
+	print STDOUT $$public_data;
+}
+
+if (not defined($private_file) and defined($public_file)) {
+	print STDOUT $$private_data;
+}
+
+my $old_public_data = file_load($public_file);
+my $old_private_data = file_load($private_file);
+
+if (not defined($old_public_data) or ($old_public_data ne $$public_data))
+{
+	open(PUBLIC, ">$public_file") or die("Can't open `$public_file': $!"); 
+	print PUBLIC "$$public_data";
+	close(PUBLIC);
+} 
+
+if (($public_file ne $private_file) and (
+	not defined($old_private_data) or ($old_private_data ne $$private_data))) {
+
+	open(PRIVATE, ">$private_file") or die("Can't open `$private_file': $!"); 
+	print PRIVATE "$$private_data";
+	close(PRIVATE);
+}


Property changes on: trunk/openchange/script/mkproto.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/script/mkrelease.sh
===================================================================
--- trunk/openchange/script/mkrelease.sh	                        (rev 0)
+++ trunk/openchange/script/mkrelease.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+#
+# ./script/mkrelease.sh VERSION NICKNAME FIRST_REVISION
+# ./script/mkrelease.sh 0.7 PHASER 308
+#
+
+TMPDIR=`mktemp libmapi-XXXXX`
+rm $TMPDIR || exit 1
+svn export . $TMPDIR || exit 1
+svn log -r$3:HEAD > $TMPDIR/CHANGELOG || exit 1
+
+( cd $TMPDIR/
+ ./autogen.sh || exit 1
+ ./configure || exit 1
+ make || exit 1
+ sed -i "s/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=yes/OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=no/g" VERSION || exit 1
+ ./autogen.sh || exit 1
+ ./configure || exit 1
+ make doxygen || exit 1
+ make distclean  || exit 1
+ rm .bzrignore
+) || exit 1
+
+VERSION=$1-$2
+mv $TMPDIR libmapi-$VERSION || exit 1
+tar -cf libmapi-$VERSION.tar libmapi-$VERSION || exit 1
+echo "Now run: "
+echo "gpg --detach-sign --armor libmapi-$VERSION.tar"
+echo "gzip libmapi-$VERSION.tar" 
+echo "And then upload "
+echo "libmapi-$VERSION.tar.gz libmapi-$VERSION.tar.asc" 


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

Added: trunk/openchange/script/mkversion.sh
===================================================================
--- trunk/openchange/script/mkversion.sh	                        (rev 0)
+++ trunk/openchange/script/mkversion.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+VERSION_FILE=$1
+OUTPUT_FILE=$2
+
+if test -z "$VERSION_FILE";then
+    $VERSION_FILE="VERSION"
+fi
+
+if test -z "$OUTPUT_FILE";then
+    $OUTPUT_FILE="libmapi/version.h"
+fi
+
+OPENCHANGE_VERSION_STRING=$3
+SOURCE_DIR=$4
+
+OPENCHANGE_MAJOR_RELEASE=`echo ${OPENCHANGE_VERSION_STRING} | cut -d. -f1`
+OPENCHANGE_MINOR_RELEASE=`echo ${OPENCHANGE_VERSION_STRING} | cut -d. -f2`
+
+OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=`sed -n 's/^OPENCHANGE_VERSION_IS_SVN_SNAPSHOT=//p' $SOURCE_DIR$VERSION_FILE`
+OPENCHANGE_VERSION_RELEASE_NICKNAME=`sed -n 's/^OPENCHANGE_VERSION_RELEASE_NICKNAME=//p' $SOURCE_DIR$VERSION_FILE`
+
+
+echo "/* Autogenerated by script/mkversion.h */" >> $OUTPUT_FILE
+echo "#define OPENCHANGE_MAJOR_RELEASE ${OPENCHANGE_MAJOR_RELEASE}" >> $OUTPUT_FILE
+echo "#define OPENCHANGE_MINOR_RELEASE ${OPENCHANGE_MINOR_RELEASE}" >> $OUTPUT_FILE
+
+#
+# SVN revision number
+#
+if test x"${OPENCHANGE_VERSION_IS_SVN_SNAPSHOT}" = x"yes";then
+    _SAVE_LANG=${LANG}
+    LANG=""
+    HAVEVER="no"
+
+    if test x"${HAVEVER}" != x"yes";then
+        HAVESVN=no
+        SVN_INFO=`svn info ${SOURCE_DIR} 2>/dev/null`
+        TMP_REVISION=`echo -e "${SVN_INFO}" | grep 'Last Changed Rev.*:' |sed -e 's/Last Changed Rev.*: \([0-9]*\).*/\1/'`
+        if test -n "$TMP_REVISION"; then
+            HAVESVN=yes
+            HAVEVER=yes
+        fi
+    fi
+
+    if test x"${HAVESVN}" = x"yes";then
+        OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_STRING}-SVN-build-${TMP_REVISION}"
+        echo "#define OPENCHANGE_VERSION_SVN_REVISION ${TMP_REVISION}" >> $OUTPUT_FILE
+    fi
+
+    LANG=${_SAVE_LANG}
+fi
+
+echo "#define OPENCHANGE_VERSION_OFFICIAL_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $OUTPUT_FILE
+
+##
+## Add a release nickname
+##
+if test -n "${OPENCHANGE_VERSION_RELEASE_NICKNAME}";then
+    echo "#define OPENCHANGE_VERSION_RELEASE_NICKNAME ${OPENCHANGE_VERSION_RELEASE_NICKNAME}" >> $OUTPUT_FILE
+    OPENCHANGE_VERSION_STRING="${OPENCHANGE_VERSION_STRING} (${OPENCHANGE_VERSION_RELEASE_NICKNAME})"
+fi
+
+echo "#define OPENCHANGE_VERSION_STRING \"${OPENCHANGE_VERSION_STRING}\"" >> $OUTPUT_FILE
+
+##
+## Add some System related information (useful for debug and report)
+##
+echo "" >> $OUTPUT_FILE
+echo "/* System related information */" >> $OUTPUT_FILE
+
+OPENCHANGE_SYS_KERNEL_NAME=`uname -s`
+OPENCHANGE_SYS_KERNEL_RELEASE=`uname -r`
+OPENCHANGE_SYS_PROCESSOR=`uname -p`
+
+echo "#define OPENCHANGE_SYS_KERNEL_NAME \"${OPENCHANGE_SYS_KERNEL_NAME}\"" >> $OUTPUT_FILE
+echo "#define OPENCHANGE_SYS_KERNEL_RELEASE \"${OPENCHANGE_SYS_KERNEL_RELEASE}\"" >> $OUTPUT_FILE
+echo "#define OPENCHANGE_SYS_PROCESSOR \"${OPENCHANGE_SYS_PROCESSOR}\"" >> $OUTPUT_FILE
+
+echo "$0: '$OUTPUT_FILE' created for OpenChange libmapi(\"${OPENCHANGE_VERSION_STRING}\")"
+
+exit 0


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

Added: trunk/openchange/script/samba4_ver.sh
===================================================================
--- trunk/openchange/script/samba4_ver.sh	                        (rev 0)
+++ trunk/openchange/script/samba4_ver.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,4 @@
+SAMBA4_GIT_REV=57f978d
+SAMBA4_GIT_VER=4.0.0alpha6
+SAMBA4_RELEASE=4.0.0alpha6
+

Added: trunk/openchange/script/uninstallman.sh
===================================================================
--- trunk/openchange/script/uninstallman.sh	                        (rev 0)
+++ trunk/openchange/script/uninstallman.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,28 @@
+#!/bin/sh
+# 4 July 96 Dan.Shearer at UniSA.edu.au
+# Updated for Samba4 by Jelmer Vernooij
+
+MANDIR=$1
+shift 1
+MANPAGES=$*
+
+for I in $MANPAGES
+do
+	SECTION=`echo $I | grep -o '.$'`
+	MAN=`echo $I | grep -o '[a-zA-Z_]*\.[0-9]'`
+	FNAME=$MANDIR/man$SECTION/$MAN
+	if test -f $FNAME; then
+	  echo Deleting $FNAME
+	  rm -f $FNAME 
+	  test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?   
+    fi
+done
+
+cat << EOF
+======================================================================
+The man pages have been uninstalled. You may install them again using 
+the command "make installman" or make "install" to install binaries,
+man pages and shell scripts.
+======================================================================
+EOF
+exit 0


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

Added: trunk/openchange/script/uno.dfn
===================================================================
--- trunk/openchange/script/uno.dfn	                        (rev 0)
+++ trunk/openchange/script/uno.dfn	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1 @@
+UnoType _Bool;

Added: trunk/openchange/setup/AD/oc_provision_configuration.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_configuration.ldif	                        (rev 0)
+++ trunk/openchange/setup/AD/oc_provision_configuration.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,2014 @@
+################################################################
+# CN=Services,${CONFIGDN} records
+################################################################
+
+
+#
+# Exchange configuration information object
+# This object stores configuration information for the Exchange Server 
+#
+dn: CN=Microsoft Exchange,CN=Services,${CONFIGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchConfigurationContainer
+cn: Microsoft Exchange
+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}
+globalAddressList: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+templateRoots: CN=Addressing,${FIRSTORGDN}
+#msExchPolicyRoots: CN=System Policies,${FIRSTORGDN}
+#msExchPolicyRoots: CN=Recipient Policies,${FIRSTORGDN}
+
+
+#
+# First Organization
+#
+dn: ${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchOrganizationContainer
+cn: First Organization
+distinguishedName: ${FIRSTORGDN}
+showInAdvancedViewOnly: TRUE
+adminDisplayName: {335A1087-5131-4D45-BE3E-3C6C7F76F5EC}
+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
+#
+dn: CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchAdminGroupContainer
+cn: Administrative Groups
+distinguishedName: CN=Administrative Groups,${FIRSTORGDN}
+displayName: Administrative Groups
+showInAdvancedViewOnly: TRUE
+name: Administrative Groups
+objectCategory: CN=ms-Exch-Admin-Group-Container,${SCHEMADN}
+
+
+#
+# First Administrative Group
+#
+dn: CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchAdminGroup
+cn: First Administrative Group
+distinguishedName: CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+displayName: First Administrative Group
+showInAdvancedViewOnly: TRUE
+siteFolderGUID: 4b2d197b-1cb3-486a-b8c3-42e8c5c08e27
+siteFolderServer: CN=Public Folder Store (${FIRSTORG}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+name: First Administrative Group
+legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group
+objectCategory: CN=ms-Exch-Admin-Group,${SCHEMADN}
+msExchAdminGroupMode: 0
+msExchDefaultAdminGroup: TRUE
+
+
+#
+# Servers
+#
+dn: CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchServersContainer
+cn: Servers
+distinguishedName: CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN} 
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Servers
+containerInfo: 8
+name: Servers
+objectCategory: CN=ms-Exch-Servers-Container,${SCHEMADN}
+
+
+#
+# The OpenChange Server object
+#
+dn: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: server
+objectClass: msExchExchangeServer
+cn: ${NETBIOSNAME}
+serialNumber: Version 6.5 (Build 6944.4)
+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}
+networkAddress: ncacn_np:${NETBIOSNAME}
+networkAddress: ncacn_spx:${NETBIOSNAME}
+networkAddress: ncacn_ip_tcp:${HOSTNAME}.${DNSDOMAIN}
+networkAddress: ncalrpc:${NETBIOSNAME}
+name: ${NETBIOSNAME}
+versionNumber: 6944
+serverRole: 0
+legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME}
+objectCategory: CN=ms-Exch-Exchange-Server,${SCHEMADN}
+#msExchHomeRoutingGroup: CN=First Routing Group,CN=Routing Groups,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchMessageTrackLogFilter: -262145
+msExchTrkLogCleaningInterval: 7
+#msExchResponsibleMTAServer: CN=Microsoft MTA,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchMailboxManagerActivationStyle: 0
+msExchMailboxManagerAdminMode: 2
+
+
+#
+# Information Store
+#
+dn: CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchInformationStore
+cn: InformationStore
+distinguishedName: CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+showInAdvancedViewOnly: TRUE
+adminDisplayName: InformationStore
+name: InformationStore
+objectCategory: CN=ms-Exch-Information-Store,${SCHEMADN}
+
+
+#
+# First Storage Group
+#
+dn: CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchStorageGroup
+cn: First Storage Group
+distinguishedName: CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+showInAdvancedViewOnly: TRUE
+adminDisplayName: First Storage Group
+name: First Storage Group
+systemFlags: 1610612736
+objectCategory: CN=ms-Exch-Storage-Group,${SCHEMADN}
+
+
+#
+# Public Folder Store (${NETBIOSNAME})
+#
+dn: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchMDB
+objectClass: msExchPublicMDB
+cn: Public Folder Store (${NETBIOSNAME})
+distinguishedName: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+displayName: Public Folder Store (${NETBIOSNAME})
+activationStyle: 1
+messageSizeLimit: 10240
+showInAdvancedViewOnly: TRUE
+#homeMTA: CN=Microsoft MTA,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+adminDisplayName: Public Folder Store (${NETBIOSNAME})
+proxyAddresses: SMTP:${NETBIOSNAME}-IS@${DNSDOMAIN}
+proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=EXCH2K3-IS;
+deliveryMechanism: 1
+garbageCollPeriod: 604800
+quotaNotificationStyle: 1
+#homeMDBBL: CN=SMTP (${NETBIOSNAME}-{E95EE010-3E8A-425B-806F-15ED60887F6B}),CN=Connections,${FIRSTORGDN}
+mailNickname: ${NETBIOSNAME}-IS
+name: Public Folder Store (${NETBIOSNAME})
+systemFlags: 1610612736
+legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME}/cn=Microsoft Public MDB
+objectCategory: CN=ms-Exch-Public-MDB,${SCHEMADN}
+textEncodedORAddress: c=US;a= ;p=First Organizati;o=Exchange;s=${NETBIOSNAME}-IS;
+mail: ${NETBIOSNAME}-IS@${DNSDOMAIN}
+msExchOwningServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+#msExchOwningPFTree: CN=Public Folders,CN=Folder Hierarchies,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchMaxCachedViews: 11
+msExchDatabaseCreated: TRUE
+msExchPoliciesIncluded: {627410A4-E1A9-4DD0-9568-FA22DEACB6B8},{26491CFC-9E50-
+ 4857-861B-0CB8DF22B5D7}
+
+
+#
+# Mailbox Store (${NETBIOSNAME})
+#
+dn: CN=Mailbox Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchMDB
+objectClass: msExchPrivateMDB
+cn: Mailbox Store (${NETBIOSNAME})
+distinguishedName: CN=Mailbox Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+displayName: Mailbox Store (${NETBIOSNAME})
+activationStyle: 1
+deletedItemFlags: 5
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Mailbox Store (${NETBIOSNAME})
+deliveryMechanism: 1
+garbageCollPeriod: 604800
+quotaNotificationStyle: 1
+name: Mailbox Store (${NETBIOSNAME})
+systemFlags: 1610612736
+legacyExchangeDN: /o=${FIRSTORG}/ou=First Administrative Group/cn=Configuration/cn=Servers/cn=${NETBIOSNAME}/cn=Microsoft Private MDB
+objectCategory: CN=ms-Exch-Private-MDB,${SCHEMADN}
+#msExchUseOAB: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+msExchOwningServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchHomePublicMDB: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchMailboxRetentionPeriod: 2592000
+msExchMaxCachedViews: 11
+msExchDatabaseCreated: TRUE
+
+
+#
+# All Address Lists Containers
+# description: Address book root container
+#
+dn: CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Address Lists Container
+distinguishedName: CN=Address Lists Container,${FIRSTORGDN}
+displayName: Address Lists Container
+showInAdvancedViewOnly: TRUE
+name: Address Lists Container
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+#
+# All Global Address Lists
+#
+dn: CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: All Global Address Lists
+distinguishedName: CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: All Global Address Lists
+showInAdvancedViewOnly: TRUE
+name: All Global Address Lists
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+
+
+#
+# Default global Address List
+#
+dn: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: Default Global Address List
+distinguishedName: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: Default Global Address List
+showInAdvancedViewOnly: TRUE
+name: Default Global Address List
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectCategory=msExchDynamicDistributionList) ))
+
+
+#
+# Offline Address Lists
+#
+dn: CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Offline Address Lists
+distinguishedName: CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: Offline Address Lists
+showInAdvancedViewOnly: TRUE
+name: Offline Address Lists
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+#
+# Default Offline Address List
+#
+dn: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchOAB
+cn: Default Offline Address List
+distinguishedName: CN=Default Offline Address List,CN=Offline Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+showInAdvancedViewOnly: TRUE
+offLineABStyle: 1
+offLineABContainers: CN=Default Global Address List,CN=All Global Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+offLineABServer: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+siteFolderGUID: e72eae5f-ee8e-4908-becb-fb58af7c62aa
+siteFolderServer: CN=Public Folder Store (${NETBIOSNAME}),CN=First Storage Group,CN=InformationStore,CN=${NETBIOSNAME},CN=Servers,${FIRSTORGDN}
+doOABVersion: 0
+name: Default Offline Address List
+systemFlags: 1610612736
+legacyExchangeDN: /o=${FIRSTORG}/cn=addrlists/cn=oabs/cn=Default Offline Address List
+objectCategory: CN=ms-Exch-OAB,${SCHEMADN}
+msExchOABDefault: TRUE
+
+
+#
+# Recipient Update Services
+#
+dn: CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Recipient Update Services
+distinguishedName: CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+displayName: Recipient Update Services
+showInAdvancedViewOnly: TRUE
+name: Recipient Update Services
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+#
+# Recipient Update Service (${DOMAIN})
+#
+dn: CN=Recipient Update Service (${DOMAIN}),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchAddressListService
+cn: Recipient Update Service (${DOMAIN})
+distinguishedName: CN=Recipient Update Service (${DOMAIN}),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+activationStyle: 2
+showInAdvancedViewOnly: TRUE
+name: Recipient Update Service (${DOMAIN})
+systemFlags: 1073741824
+objectCategory: CN=ms-Exch-Address-List-Service,${SCHEMADN}
+msExchServer1NetworkAddress: ${HOSTNAME}
+msExchServer1PageSize: 20
+msExchDoFullReplication: FALSE
+msExchReplicateNow: FALSE
+msExchPollInterval: 60
+msExchAddressListServiceLink: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchDomainLink: ${DOMAINDN}
+msExchServer1HighestUSNVector: ${NETBIOSNAME}:53500
+msExchDomainLocalGroupGuid: {D9CA41A1-5041-4FBF-8635-23B4D0BA8A48}
+msExchDomainGlobalGroupGuid: {1E2B98D3-4FAC-4FAE-B16F-A26AB09AAE34}
+msExchDomainLocalGroupSid: S-1-5-21-1226241484-1028146065-4277480997-1110
+msExchDomainGlobalGroupSid: S-1-5-21-1226241484-1028146065-4277480997-1109
+
+
+#
+# Recipient Update Service (Enterprise Configuration)
+#
+dn: CN=Recipient Update Service (Enterprise Configuration),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: msExchAddressListService
+cn: Recipient Update Service (Enterprise Configuration)
+distinguishedName: CN=Recipient Update Service (Enterprise Configuration),CN=Recipient Update Services,CN=Address Lists Container,${FIRSTORGDN}
+activationStyle: 2
+showInAdvancedViewOnly: TRUE
+name: Recipient Update Service (Enterprise Configuration)
+systemFlags: 1073741824
+objectCategory: CN=ms-Exch-Address-List-Service,CN=Schema,CN=Configuration,DC=
+ openchange2003,DC=local
+msExchServer1NetworkAddress: ${HOSTNAME}
+msExchServer1PageSize: 20
+msExchDoFullReplication: FALSE
+msExchReplicateNow: FALSE
+msExchPollInterval: 60
+msExchAddressListServiceLink: CN=${NETBIOSNAME},CN=Servers,CN=First Administrative Group,CN=Administrative Groups,${FIRSTORGDN}
+msExchDomainLink: CN=Configuration,${DOMAINDN}
+
+
+#
+# All Address Lists
+# description: Address book recipient
+#
+dn: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: All Address Lists
+distinguishedName: CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: All Address Lists
+showInAdvancedViewOnly: TRUE
+name: All Address Lists
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+
+#
+# All Users
+#
+dn: CN=All Users,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: All Users
+distinguishedName: CN=All Users,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: All Users
+showInAdvancedViewOnly: TRUE
+name: All Users
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*))) ))
+
+
+#
+# All Groups
+#
+dn: CN=All Groups,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: All Groups
+distinguishedName: CN=All Groups,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: All Groups
+showInAdvancedViewOnly: TRUE
+name: All Groups
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+purportedSearch: (& (mailnickname=*) (| (objectCategory=group) ))
+
+
+#
+# All Contacts
+# description: Address book recipient
+#
+dn: CN=All Contacts,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: All Contacts
+distinguishedName: CN=All Contacts,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: All Contacts
+showInAdvancedViewOnly: TRUE
+name: All Contacts
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+purportedSearch: (& (mailnickname=*) (| (&(objectCategory=person)(objectClass=contact)) ))
+
+
+#
+# Public Folders
+# description: Address book recipient
+#
+dn: CN=Public Folders,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+objectClass: top
+objectClass: addressBookContainer
+cn: Public Folders
+distinguishedName: CN=Public Folders,CN=All Address Lists,CN=Address Lists Container,${FIRSTORGDN}
+displayName: Public Folders
+showInAdvancedViewOnly: TRUE
+name: Public Folders
+systemFlags: 1610612736
+objectCategory: CN=Address-Book-Container,${SCHEMADN}
+purportedSearch: (& (mailnickname=*) (| (objectCategory=publicFolder) ))
+
+
+#
+# Addressing
+# description:  Address container
+#
+dn: CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Addressing
+distinguishedName: CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Addressing
+containerInfo: 16
+name: Addressing
+legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+
+#
+# Address-Templates
+# description: Specifies information for a Display Template
+#
+dn: CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Address-Templates
+distinguishedName: CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+showInAdvancedViewOnly: TRUE
+adminDisplayName: One-Off Address Templates
+containerInfo: 32
+name: Address-Templates
+legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing/cn=Address-Templates
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+msExchTemplateRDNs: 81A
+msExchTemplateRDNs: 403
+msExchTemplateRDNs: 422
+msExchTemplateRDNs: 427
+msExchTemplateRDNs: 426
+msExchTemplateRDNs: 425
+msExchTemplateRDNs: 402
+msExchTemplateRDNs: 424
+msExchTemplateRDNs: 41b
+msExchTemplateRDNs: 418
+msExchTemplateRDNs: 41a
+msExchTemplateRDNs: 42d
+msExchTemplateRDNs: 41e
+msExchTemplateRDNs: 40e
+msExchTemplateRDNs: 41f
+msExchTemplateRDNs: 419
+msExchTemplateRDNs: 414
+msExchTemplateRDNs: 406
+msExchTemplateRDNs: 405
+msExchTemplateRDNs: 41d
+msExchTemplateRDNs: 816
+msExchTemplateRDNs: 415
+msExchTemplateRDNs: 408
+msExchTemplateRDNs: 40b
+msExchTemplateRDNs: 413
+msExchTemplateRDNs: 416
+msExchTemplateRDNs: 40d
+msExchTemplateRDNs: 401
+msExchTemplateRDNs: 410
+msExchTemplateRDNs: C0A
+msExchTemplateRDNs: 404
+msExchTemplateRDNs: 804
+msExchTemplateRDNs: 412
+msExchTemplateRDNs: 40c
+msExchTemplateRDNs: 407
+msExchTemplateRDNs: 411
+msExchTemplateRDNs: 409
+
+
+#
+# Address-Types
+# description: E-Mail Address Generators
+#
+dn: CN=Address-Types,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Address-Types
+distinguishedName: CN=Address-Types,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+showInAdvancedViewOnly: TRUE
+adminDisplayName: E-Mail Address Generators
+containerInfo: 128
+name: Address-Types
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+#
+# Display-Templates
+#
+#
+dn: CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+objectClass: msExchContainer
+cn: Display-Templates
+distinguishedName: CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Details Templates
+containerInfo: 64
+name: Display-Templates
+legacyExchangeDN: /o=${FIRSTORG}/cn=Configuration/cn=Addressing/cn=Display-Templates
+objectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+#
+# Arabic Address-Templates
+#
+dn: CN=401,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 401
+distinguishedName: CN=401,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Arabic
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Arabic
+name: 401
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=401
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Bulgarian Address-Templates
+#
+dn: CN=402,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 402
+distinguishedName: CN=402,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Bulgarian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Bulgarian
+name: 402
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=402
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Catalan Address-Templates
+#
+dn: CN=403,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 403
+distinguishedName: CN=403,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Catalan
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Catalan
+name: 403
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=403
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Chinese Traditional Address-Templates
+#
+dn: CN=404,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 404
+distinguishedName: CN=404,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Chinese Traditional
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Chinese Traditional
+name: 404
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=404
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Czech Address-Templates
+#
+dn: CN=405,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 405
+distinguishedName: CN=405,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Czech
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Czech
+name: 405
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=405
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Danish Address-Templates
+#
+dn: CN=406,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 406
+distinguishedName: CN=406,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Danish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Danish
+name: 406
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=406
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# German Address-Templates
+#
+dn: CN=407,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 407
+distinguishedName: CN=407,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: German
+showInAdvancedViewOnly: TRUE
+adminDisplayName: German
+name: 407
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=407
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Greek Address-Templates
+#
+dn: CN=408,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 408
+distinguishedName: CN=408,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Greek
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Greek
+name: 408
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=408
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# English Address-Templates
+#
+dn: CN=409,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 409
+distinguishedName: CN=409,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: English
+showInAdvancedViewOnly: TRUE
+adminDisplayName: English
+name: 409
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=409
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Finish Address-Templates
+#
+dn: CN=40b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40b
+distinguishedName: CN=40b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Finnish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Finnish
+name: 40b
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40b
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# French Address-Templates (cocorico)
+#
+dn: CN=40c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40c
+distinguishedName: CN=40c,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: French
+showInAdvancedViewOnly: TRUE
+adminDisplayName: French
+name: 40c
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40c
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Hebrew Address-Templates
+#
+dn: CN=40d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40d
+distinguishedName: CN=40d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Hebrew
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Hebrew
+name: 40d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40d
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Hungarian Address-Templates
+#
+dn: CN=40e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40e
+distinguishedName: CN=40e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Hungarian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Hungarian
+name: 40e
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=40e
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Italian Address-Templates
+#
+dn: CN=410,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 410
+distinguishedName: CN=410,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Italian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Italian
+name: 410
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=410
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Japanese Address-Templates
+#
+dn: CN=411,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 411
+distinguishedName: CN=411,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Japanese
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Japanese
+name: 411
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=411
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Korean Address-Templates
+#
+dn: CN=412,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 412
+distinguishedName: CN=412,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Korean
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Korean
+name: 412
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=412
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Dutch Address-Templates
+#
+dn: CN=413,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 413
+distinguishedName: CN=413,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Dutch
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Dutch
+name: 413
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=413
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Norwegian Address-Templates
+#
+dn: CN=414,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 414
+distinguishedName: CN=414,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Norwegian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Norwegian
+name: 414
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=414
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Polish Address-Templates
+#
+dn: CN=415,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 415
+distinguishedName: CN=415,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Polish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Polish
+name: 415
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=415
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Brazilian Address-Templates (Samba)
+#
+dn: CN=416,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 416
+distinguishedName: CN=416,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Brazilian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Brazilian
+name: 416
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=416
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Romanian Address-Templates
+#
+dn: CN=418,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 418
+distinguishedName: CN=418,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Romanian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Romanian
+name: 418
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=418
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Russian Address-Templates
+#
+dn: CN=419,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 419
+distinguishedName: CN=419,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Russian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Russian
+name: 419
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=419
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Croatian Address-Templates
+#
+dn: CN=41a,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41a
+distinguishedName: CN=41a,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Croatian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Croatian
+name: 41a
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41a
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Slovak Address-Templates
+#
+dn: CN=41b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41b
+distinguishedName: CN=41b,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Slovak
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Slovak
+name: 41b
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41b
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Swedish Address-Templates
+#
+dn: CN=41d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41d
+distinguishedName: CN=41d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Swedish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Swedish
+name: 41d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41d
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Thai Address-Templates
+#
+dn: CN=41e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41e
+distinguishedName: CN=41e,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Thai
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Thai
+name: 41e
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41e
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Turkish Address-Templates
+#
+dn: CN=41f,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41f
+distinguishedName: CN=41f,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Turkish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Turkish
+name: 41f
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=41f
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Ukrainian Address-Templates
+#
+dn: CN=422,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 422
+distinguishedName: CN=422,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Ukrainian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Ukrainian
+name: 422
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=422
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Slovenian Address-Templates
+#
+dn: CN=424,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 424
+distinguishedName: CN=424,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Slovenian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Slovenian
+name: 424
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=424
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Estonian Address-Templates
+#
+dn: CN=425,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 425
+distinguishedName: CN=425,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Estonian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Estonian
+name: 425
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=425
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Latvian Address-Templates
+#
+dn: CN=426,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 426
+distinguishedName: CN=426,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Latvian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Latvian
+name: 426
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=426
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Lithuanian Address-Templates
+#
+dn: CN=427,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 427
+distinguishedName: CN=427,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Lithuanian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Lithuanian
+name: 427
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=427
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Basque Address-Templates
+#
+dn: CN=42d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 42d
+distinguishedName: CN=42d,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Basque
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Basque
+name: 42d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=42d
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Chinese Simplified Address-Templates
+#
+dn: CN=804,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 804
+distinguishedName: CN=804,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Chinese Simplified
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Chinese Simplified
+name: 804
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=804
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Portuguese Address-Templates
+#
+dn: CN=816,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 816
+distinguishedName: CN=816,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Portuguese
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Portuguese
+name: 816
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=816
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Serbian Address-Templates
+#
+dn: CN=81A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 81A
+distinguishedName: CN=81A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Serbian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Serbian
+name: 81A
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=81A
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Spanish Address-Templates
+#
+dn: CN=C0A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: C0A
+distinguishedName: CN=C0A,CN=Address-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Spanish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Spanish
+name: C0A
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Address-Templates/CN=C0A
+objectCategory: CN=Container,${SCHEMADN}
+msExchTemplateRDNs: CCMAIL
+msExchTemplateRDNs: MSA
+msExchTemplateRDNs: SMTP
+msExchTemplateRDNs: MS
+msExchTemplateRDNs: x400
+
+
+#
+# Arabic Display-Templates
+#
+dn: CN=401,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 401
+distinguishedName: CN=401,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Arabic
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Arabic
+name: 401
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=401
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Bulgarian Display-Templates
+#
+dn: CN=402,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 402
+distinguishedName: CN=402,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Bulgarian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Bulgarian
+name: 402
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=402
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Catalan Display-Templates
+#
+dn: CN=403,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 403
+distinguishedName: CN=403,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Catalan
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Catalan
+name: 403
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=403
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Chinese Traditional Display-Templates
+#
+dn: CN=404,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 404
+distinguishedName: CN=404,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Chinese Traditional
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Chinese Traditional
+name: 404
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=404
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Czech Display-Templates
+#
+dn: CN=405,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 405
+distinguishedName: CN=405,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Czech
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Czech
+name: 405
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=405
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Danish Display-Templates
+#
+dn: CN=406,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 406
+distinguishedName: CN=406,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Danish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Danish
+name: 406
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=406
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# German Display-Templtes
+#
+dn: CN=407,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 407
+distinguishedName: CN=407,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: German
+showInAdvancedViewOnly: TRUE
+adminDisplayName: German
+name: 407
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=407
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Greek Display-Templates
+#
+dn: CN=408,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 408
+distinguishedName: CN=408,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Greek
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Greek
+name: 408
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=408
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# English Display-Templates
+#
+dn: CN=409,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 409
+distinguishedName: CN=409,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: English
+showInAdvancedViewOnly: TRUE
+adminDisplayName: English
+name: 409
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=409
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Finish Display-Templates
+#
+dn: CN=40b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40b
+distinguishedName: CN=40b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Finnish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Finnish
+name: 40b
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40b
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# French Display-Templates (cocorico)
+#
+dn: CN=40c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40c
+distinguishedName: CN=40c,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: French
+showInAdvancedViewOnly: TRUE
+adminDisplayName: French
+name: 40c
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40c
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Hebrew Display-Templates
+#
+dn: CN=40d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40d
+distinguishedName: CN=40d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Hebrew
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Hebrew
+name: 40d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40d
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Hungarian Display-Templates
+#
+dn: CN=40e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 40e
+distinguishedName: CN=40e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Hungarian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Hungarian
+name: 40e
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=40e
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Italian Display-Templates
+#
+dn: CN=410,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 410
+distinguishedName: CN=410,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Italian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Italian
+name: 410
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=410
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Japanese Display-Templates
+#
+dn: CN=411,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 411
+distinguishedName: CN=411,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Japanese
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Japanese
+name: 411
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=411
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Korean Display-Templates
+#
+dn: CN=412,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 412
+distinguishedName: CN=412,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Korean
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Korean
+name: 412
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=412
+objectCategory: CN=Container,${SCHEMADN}
+
+
+
+#
+# Dutch Display-Templates
+#
+dn: CN=413,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 413
+distinguishedName: CN=413,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Dutch
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Dutch
+name: 413
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=413
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Norwegian Display-Templates
+#
+dn: CN=414,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 414
+distinguishedName: CN=414,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Norwegian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Norwegian
+name: 414
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=414
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Polish Display-Templates
+#
+dn: CN=415,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 415
+distinguishedName: CN=415,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Polish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Polish
+name: 415
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=415
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Brazilian Display-Templates (Samba)
+#
+dn: CN=416,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 416
+distinguishedName: CN=416,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Brazilian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Brazilian
+name: 416
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=416
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Romanian Display-Templates
+#
+dn: CN=418,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 418
+distinguishedName: CN=418,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Romanian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Romanian
+name: 418
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=418
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Russian Display-Templates
+#
+dn: CN=419,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 419
+distinguishedName: CN=419,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Russian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Russian
+name: 419
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=419
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Croatian Display-Templates
+#
+dn: CN=41a,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41a
+distinguishedName: CN=41a,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Croatian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Croatian
+name: 41a
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41a
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Slovak Display-Templates
+#
+dn: CN=41b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41b
+distinguishedName: CN=41b,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Slovak
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Slovak
+name: 41b
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41b
+objectCategory: CN=Container,${SCHEMADN}
+
+
+
+#
+# Swedish Display-Templates
+#
+dn: CN=41d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41d
+distinguishedName: CN=41d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Swedish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Swedish
+name: 41d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41d
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Thai Display-Templates
+#
+dn: CN=41e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41e
+distinguishedName: CN=41e,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Thai
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Thai
+name: 41e
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41e
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Turkish Display-Templates
+#
+dn: CN=41f,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 41f
+distinguishedName: CN=41f,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Turkish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Turkish
+name: 41f
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=41f
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Ukrainian Display-Templates
+#
+dn: CN=422,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 422
+distinguishedName: CN=422,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Ukrainian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Ukrainian
+name: 422
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=422
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Slovenian Display-Templates
+#
+dn: CN=424,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 424
+distinguishedName: CN=424,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Slovenian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Slovenian
+name: 424
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=424
+objectCategory: CN=Container,${SCHEMADN}
+
+
+
+#
+# Estonian Display-Templates
+#
+dn: CN=425,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 425
+distinguishedName: CN=425,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Estonian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Estonian
+name: 425
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=425
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Latvian Display-Templates
+#
+dn: CN=426,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 426
+distinguishedName: CN=426,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Latvian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Latvian
+name: 426
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=426
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Lithuanian Display-Templates
+#
+dn: CN=427,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 427
+distinguishedName: CN=427,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Lithuanian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Lithuanian
+name: 427
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=427
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Basque Display-Templates
+#
+dn: CN=42d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 42d
+distinguishedName: CN=42d,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Basque
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Basque
+name: 42d
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=42d
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Chinese Simplified Display-Templates
+#
+dn: CN=804,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 804
+distinguishedName: CN=804,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Chinese Simplified
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Chinese Simplified
+name: 804
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=804
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Portuguese Display-Templates
+#
+dn: CN=816,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 816
+distinguishedName: CN=816,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Portuguese
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Portuguese
+name: 816
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=816
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Serbian Display-Templates
+#
+dn: CN=81A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: 81A
+distinguishedName: CN=81A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Serbian
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Serbian
+name: 81A
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=81A
+objectCategory: CN=Container,${SCHEMADN}
+
+
+#
+# Spanish Display-Templates
+#
+dn: CN=C0A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+objectClass: top
+objectClass: container
+cn: C0A
+distinguishedName: CN=C0A,CN=Display-Templates,CN=Addressing,${FIRSTORGDN}
+instanceType: 4
+displayName: Spanish
+showInAdvancedViewOnly: TRUE
+adminDisplayName: Spanish
+name: C0A
+legacyExchangeDN: /o=${FIRSTORG}/CN=Configuration/CN=Addressing/CN=Display-Templates/CN=C0A
+objectCategory: CN=Container,${SCHEMADN}

Added: trunk/openchange/setup/AD/oc_provision_schema.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema.ldif	                        (rev 0)
+++ trunk/openchange/setup/AD/oc_provision_schema.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,29804 @@
+##############################################################################
+# Classes added
+##############################################################################
+
+
+
+
+
+#
+# ms-Exch-Active-Directory-Connector
+# Represents the service that synchronizes information between the
+# Exchange Server 5.5 directory and Active Directory.
+#
+dn: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Active-Directory-Connector
+distinguishedName: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN}
+possSuperiors: organizationalUnit
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.4
+mayContain: versionNumberHi
+mayContain: versionNumber
+mayContain: msExchServer2SchemaMap
+mayContain: msExchServer1SchemaMap
+mayContain: msExchChildSyncAgreements
+mayContain: displayName
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Active-Directory-Connector
+adminDescription: ms-Exch-Active-Directory-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchActiveDirectoryConnector
+name: ms-Exch-Active-Directory-Connector
+schemaIDGUID: e605672c-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Active-Directory-Connector,${SCHEMADN}
+
+
+
+dn: CN=ms-Exch-Addressing-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Addressing-Policy
+distinguishedName: CN=ms-Exch-Addressing-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50008
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchProxyGenServer
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+mayContain: gatewayProxy
+mayContain: disabledGatewayProxy
+mayContain: msExchAliasGenUniqueness
+mayContain: msExchAliasGenType
+mayContain: msExchAliasGenFormat
+rDNAttID: cn
+uSNChanged: 16956
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Addressing-Policy
+adminDescription: ms-Exch-Addressing-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAddressingPolicy
+name: ms-Exch-Addressing-Policy
+schemaIDGUID: e7211f02-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Addressing-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Address-List-Service
+# Domain-wide configuration object for the Address List Service.
+#
+dn: CN=ms-Exch-Address-List-Service,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Address-List-Service
+distinguishedName: CN=ms-Exch-Address-List-Service,${SCHEMADN}
+possSuperiors: exchangeAdminService
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.2
+mayContain: msExchMinAdminVersion
+mayContain: msExchDomainLocalGroupSid
+mayContain: msExchDomainLocalGroupGuid
+mayContain: msExchDomainGlobalGroupSid
+mayContain: msExchDomainGlobalGroupGuid
+mayContain: msExchProcessedSids
+mayContain: gatewayProxy
+mayContain: msExchEncryptedPassword
+mayContain: msExchServer2LastUpdateTime
+mayContain: msExchServer2HighestUSNVector
+mayContain: msExchServer2HighestUSN
+mayContain: msExchServer2Flags
+mayContain: msExchServer1HighestUSNVector
+mayContain: msExchServer1AuthenticationPassword
+mayContain: msExchServer1AuthenticationCredentials
+mayContain: msExchMasterServiceBL
+mayContain: exportContainers
+mayContain: msExchServer1SearchFilter
+mayContain: msExchServer1NetworkAddress
+mayContain: msExchServer1PageSize
+mayContain: msExchServer1LastUpdateTime
+mayContain: msExchServer1HighestUSN
+mayContain: msExchServer1Flags
+mayContain: msExchReplicateNow
+mayContain: msExchPollInterval
+mayContain: msExchDomainLink
+mayContain: msExchDoFullReplication
+mayContain: msExchAddressListServiceLink
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Address-List-Service
+adminDescription: ms-Exch-Address-List-Service
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAddressListService
+name: ms-Exch-Address-List-Service
+schemaIDGUID: e6a2c260-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Address-List-Service,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Address-List-Service-Container 
+# Container for Recipient Update Service (RUS) objects
+#
+dn: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Address-List-Service-Container
+distinguishedName: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN}
+possSuperiors: msExchContainer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.13
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Address-List-Service-Container
+adminDescription: ms-Exch-Address-List-Service-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAddressListServiceContainer
+name: ms-Exch-Address-List-Service-Container
+schemaIDGUID: b1fce95a-1d44-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Address-List-Service-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Addr-Type
+# Specifies an EMS Address type, such as SMTP, MHS, or PROFS.
+#
+dn: CN=ms-Exch-Addr-Type,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Addr-Type
+distinguishedName: CN=ms-Exch-Addr-Type,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.57
+mustContain: proxyGeneratorDLL
+mustContain: fileVersion
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: proxyGenerationEnabled
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Addr-Type
+adminDescription: ms-Exch-Addr-Type
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: addrType
+name: ms-Exch-Addr-Type
+schemaIDGUID: a8df74ab-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Addr-Type,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Add-In
+#
+dn: CN=ms-Exch-Add-In,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Add-In
+distinguishedName: CN=ms-Exch-Add-In,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.36
+mustContain: computerName
+mustContain: cn
+mayContain: owner
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Add-In
+adminDescription: ms-Exch-Add-In
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: addIn
+name: ms-Exch-Add-In
+schemaIDGUID: a8df74aa-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Add-In,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Extension
+# Specifies a remote X.400 message transfer agent (MTA).
+#
+dn: CN=ms-Exch-Admin-Extension,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Admin-Extension
+distinguishedName: CN=ms-Exch-Admin-Extension,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.21
+mustContain: fileVersion
+mustContain: adminExtensionDLL
+mustContain: cn
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Extension
+adminDescription: ms-Exch-Admin-Extension
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: adminExtension
+name: ms-Exch-Admin-Extension
+schemaIDGUID: a8df74ac-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Admin-Extension,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Group
+# objectCategory for cn=First Administrative Group
+# description: An administrative group.
+#
+dn: CN=ms-Exch-Admin-Group,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Admin-Group
+distinguishedName: CN=ms-Exch-Admin-Group,${SCHEMADN}
+possSuperiors: msExchAdminGroupContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50011
+mayContain: msExchMinAdminVersion
+mayContain: domainDefAltRecip
+mayContain: msExchPfCreation
+mayContain: msExchEncryptedPassword
+mayContain: msExchAdmins
+mayContain: msExchPFDefaultAdminACL
+mayContain: msExchLegacyPW
+mayContain: msExchLegacyDomain
+mayContain: msExchLegacyAccount
+mayContain: siteFolderServer
+mayContain: siteFolderGUID
+mayContain: msExchDefaultAdminGroup
+mayContain: msExchAdminGroupMode
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Group
+adminDescription: ms-Exch-Admin-Group
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAdminGroup
+name: ms-Exch-Admin-Group
+schemaIDGUID: e768a58e-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Admin-Group,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Group-Container
+# description: An administrative group container. Used for extended rights and roles.
+#
+dn: CN=ms-Exch-Admin-Group-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Admin-Group-Container
+distinguishedName: CN=ms-Exch-Admin-Group-Container,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50019
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Group-Container
+adminDescription: ms-Exch-Admin-Group-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAdminGroupContainer
+name: ms-Exch-Admin-Group-Container
+schemaIDGUID: e7a44058-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Admin-Group-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Role
+#
+dn: CN=ms-Exch-Admin-Role,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Admin-Role
+distinguishedName: CN=ms-Exch-Admin-Role,${SCHEMADN}
+possSuperiors: msExchContainer
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50017
+mustContain: msExchRoleRights
+mayContain: msExchRoleLocalizedNames
+mayContain: msExchRoleIncludes
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Role
+adminDescription: ms-Exch-Admin-Role
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAdminRole
+name: ms-Exch-Admin-Role
+schemaIDGUID: e7f2edf2-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Admin-Role,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Advanced-Security-Container
+# A container object to hold the Encryption Configuration and Key
+# Manager objects
+#
+dn: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Advanced-Security-Container
+distinguishedName: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.13001
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Advanced-Security-Container
+adminDescription: ms-Exch-Advanced-Security-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchAdvancedSecurityContainer
+name: ms-Exch-Advanced-Security-Container
+schemaIDGUID: 8cc8fb0e-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Advanced-Security-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Base-Class
+# description: The base auxiliary class that is applied to all classes 
+# that are extended by CDO for Exchange 2000 Server (CDOEX) and the base 
+# Microsoft Windows classes that are used.
+#
+dn: CN=ms-Exch-Base-Class,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Base-Class
+distinguishedName: CN=ms-Exch-Base-Class,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.14
+mayContain: msExchInconsistentState
+mayContain: heuristics
+mayContain: msExchALObjectVersion
+mayContain: msExchUnmergedAttsPt
+mayContain: showInAddressBook
+mayContain: unmergedAtts
+mayContain: replicationSignature
+mayContain: replicatedObjectVersion
+mayContain: msExchHideFromAddressLists
+mayContain: msExchADCGlobalNames
+mayContain: legacyExchangeDN
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Base-Class
+adminDescription: ms-Exch-Base-Class
+objectClassCategory: 3
+lDAPDisplayName: msExchBaseClass
+schemaIDGUID: d8782c34-46ca-11d3-aa72-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+defaultObjectCategory: CN=ms-Exch-Base-Class,${SCHEMADN}
+
+
+#
+# ms-Exch-Calendar-Connector
+# The calendar connector
+#
+dn: CN=ms-Exch-Calendar-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Calendar-Connector
+distinguishedName: CN=ms-Exch-Calendar-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1007
+mayContain: msExchNotesNotesServer
+mayContain: msExchNotesNotesINI
+mayContain: msExchEncryptedPassword
+mayContain: msExchGWiseAPIGateway
+mayContain: msExchCalConTargetSiteDN
+mayContain: msExchCalConRefreshInterval
+mayContain: msExchCalConQueryWindow
+mayContain: msExchCalConProviders
+mayContain: msExchCalConClientWait
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Calendar-Connector
+adminDescription: ms-Exch-Calendar-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchCalendarConnector
+name: ms-Exch-Calendar-Connector
+schemaIDGUID: 922180da-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Calendar-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ccMail-Connector
+# The ccMail connector
+#
+dn: CN=ms-Exch-ccMail-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-ccMail-Connector
+distinguishedName: CN=ms-Exch-ccMail-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1001
+mayContain: msExchccMailPassword
+mayContain: msExchccMailConnectAsUserid
+mayContain: msExchccMailConnectAsPassword
+mayContain: objViewContainers
+mayContain: msExchccMailPOPath
+mayContain: msExchccMailPOName
+mayContain: msExchccMailKeepForwardHistory
+mayContain: msExchccMailImportExportVersion
+mayContain: msExchccMailFilterType
+mayContain: msExchccMailADEProp
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-Connector
+adminDescription: ms-Exch-ccMail-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchccMailConnector
+name: ms-Exch-ccMail-Connector
+schemaIDGUID: e85710b6-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-ccMail-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Certificate-Information
+# The auxiliary class of users and contacts that contains all
+# certificates and certificate information. Users publish their
+# certificates to attributes located on this object.
+#
+dn: CN=ms-Exch-Certificate-Information,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Certificate-Information
+distinguishedName: CN=ms-Exch-Certificate-Information,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.7
+mayContain: userCertificate
+mayContain: userSMIMECertificate
+mayContain: userCert
+mayContain: supportedAlgorithms
+mayContain: attributeCertificate
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Certificate-Information
+adminDescription: ms-Exch-Certificate-Information
+objectClassCategory: 3
+lDAPDisplayName: msExchCertificateInformation
+name: ms-Exch-Certificate-Information
+schemaIDGUID: e8977034-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Certificate-Information,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Ban
+# A Chat Service Ban Object
+#
+dn: CN=ms-Exch-Chat-Ban,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-Ban
+distinguishedName: CN=ms-Exch-Chat-Ban,${SCHEMADN}
+possSuperiors: msExchChatVirtualNetwork
+possSuperiors: msExchChatNetwork
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.8004
+mayContain: msExchChatStartTime
+mayContain: msExchChatDuration
+mayContain: msExchChatBanReason
+mayContain: msExchChatBanMask
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Ban
+adminDescription: ms-Exch-Chat-Ban
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatBan
+name: ms-Exch-Chat-Ban
+schemaIDGUID: e8d0a8a4-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-Ban,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel
+# A Chat Service channel (room) object
+#
+dn: CN=ms-Exch-Chat-Channel,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-Channel
+distinguishedName: CN=ms-Exch-Chat-Channel,${SCHEMADN}
+possSuperiors: msExchChatVirtualNetwork
+possSuperiors: msExchChatNetwork
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.8003
+mayContain: msExchChatAccess
+mayContain: msExchChatChannelTopic
+mayContain: msExchChatChannelSubject
+mayContain: msExchChatChannelPICS
+mayContain: msExchChatChannelPartMessage
+mayContain: msExchChatChannelOwnerKey
+mayContain: msExchChatChannelName
+mayContain: msExchChatChannelMode
+mayContain: msExchChatChannelLimit
+mayContain: msExchChatChannelLCID
+mayContain: msExchChatChannelLanguage
+mayContain: msExchChatChannelKey
+mayContain: msExchChatChannelJoinMessage
+mayContain: msExchChatChannelHostKey
+mayContain: msExchChatChannelFlags
+mayContain: msExchChatChannelAutoCreate
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel
+adminDescription: ms-Exch-Chat-Channel
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatChannel
+name: ms-Exch-Chat-Channel
+schemaIDGUID: e902ba06-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-Channel,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Network
+# A Chat Service community object.
+#
+dn: CN=ms-Exch-Chat-Network,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-Network
+distinguishedName: CN=ms-Exch-Chat-Network,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.8001
+mayContain: msExchBasicAuthenticationDomain
+mayContain: msExchAuthenticationFlags
+mayContain: msExchChatNetworkMode
+mayContain: msExchChatAccess
+mayContain: msExchChatTitle
+mayContain: msExchChatMOTD
+mayContain: msExchChatMaxMemberships
+mayContain: msExchChatMaxConnections
+mayContain: msExchChatMaxAnonymous
+mayContain: msExchChatEnableAuthenticated
+mayContain: msExchChatEnableAnonymous
+mayContain: msExchChatDNSReverseMode
+mayContain: msExchChatClientPort
+mayContain: msExchChatChannelMode
+mayContain: msExchChatChannelLimit
+mayContain: msExchChatChannelLCID
+mayContain: msExchChatChannelLanguage
+mayContain: msExchChatAdminMessage
+mayContain: Enabled
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Network
+adminDescription: ms-Exch-Chat-Network
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatNetwork
+name: ms-Exch-Chat-Network
+schemaIDGUID: e934cb68-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-Network,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Protocol
+# A Chat Service user class.
+#
+dn: CN=ms-Exch-Chat-Protocol,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-Protocol
+distinguishedName: CN=ms-Exch-Chat-Protocol,${SCHEMADN}
+possSuperiors: protocolCfgSharedServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.8005
+mayContain: msExchServerBindings
+mayContain: msExchChatServerPort
+mayContain: msExchChatBroadcastAddress
+mayContain: msExchChatAccess
+mayContain: msExchChatNetworkName
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Protocol
+adminDescription: ms-Exch-Chat-Protocol
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatProtocol
+name: ms-Exch-Chat-Protocol
+schemaIDGUID: e9621816-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-Protocol,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-User-Class
+#
+dn: CN=ms-Exch-Chat-User-Class,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-User-Class
+distinguishedName: CN=ms-Exch-Chat-User-Class,${SCHEMADN}
+possSuperiors: msExchChatVirtualNetwork
+possSuperiors: msExchChatProtocol
+possSuperiors: msExchChatNetwork
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.8006
+mayContain: msExchChatMaxOctetsToMask
+mayContain: msExchChatMaxConnectionsPerIP
+mayContain: msExchChatClassScopeType
+mayContain: msExchChatClassRestrictions
+mayContain: msExchChatStartTime
+mayContain: msExchChatProtectionLevel
+mayContain: msExchChatPingDelay
+mayContain: msExchChatOutputSaturation
+mayContain: msExchChatNickDelay
+mayContain: msExchChatMessageLag
+mayContain: msExchChatMaxMemberships
+mayContain: msExchChatMaxConnections
+mayContain: msExchChatInputFloodLimit
+mayContain: msExchChatEnableAuthenticated
+mayContain: msExchChatEnableAnonymous
+mayContain: msExchChatDuration
+mayContain: msExchChatClassIP
+mayContain: msExchChatClassIdentMask
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-User-Class
+adminDescription: ms-Exch-Chat-User-Class
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatUserClass
+name: ms-Exch-Chat-User-Class
+schemaIDGUID: e9a0153a-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-User-Class,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Virtual-Network
+# An instance of a Chat community on a physical server.
+#
+dn: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Chat-Virtual-Network
+distinguishedName: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN}
+possSuperiors: msExchChatProtocol
+possSuperiors: msExchChatNetwork
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.8002
+mayContain: msExchChatExtensions
+mayContain: msExchServerBindings
+mayContain: msExchChatTitle
+mayContain: msExchChatMaxConnections
+mayContain: msExchChatClientPort
+mayContain: Enabled
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Virtual-Network
+adminDescription: ms-Exch-Chat-Virtual-Network
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchChatVirtualNetwork
+name: ms-Exch-Chat-Virtual-Network
+schemaIDGUID: ea5ed15a-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Chat-Virtual-Network,${SCHEMADN}
+
+
+# 
+# ms-Exch-Computer-Policy
+#
+dn: CN=ms-Exch-Computer-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Computer-Policy
+distinguishedName: CN=ms-Exch-Computer-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: computer
+governsID: 1.2.840.113556.1.5.7000.62.50007
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Computer-Policy
+adminDescription: ms-Exch-Computer-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchComputerPolicy
+name: ms-Exch-Computer-Policy
+schemaIDGUID: ed2c752c-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Computer-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Conference-Container  
+# A conferencing container. Used for extended rights and
+# roles. CN=Exchange Conferencing.
+#
+dn: CN=ms-Exch-Conference-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Conference-Container
+distinguishedName: CN=ms-Exch-Conference-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.9005
+mayContain: objectCount
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Container
+adminDescription: ms-Exch-Conference-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchConferenceContainer
+name: ms-Exch-Conference-Container
+schemaIDGUID: ed7fe77a-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;CI;LCLORPRC;;;WD)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Conference-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Conference-Site
+# An Exchange Conferencing-Zone Configuration Interface Class.
+#
+dn: CN=ms-Exch-Conference-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Conference-Site
+distinguishedName: CN=ms-Exch-Conference-Site,${SCHEMADN}
+possSuperiors: msExchConferenceContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.9001
+mayContain: msExchConferenceMailbox
+mayContain: msExchConferenceZone
+mayContain: displayName
+mayContain: wWWHomePage
+mayContain: serverName
+mayContain: objectCount
+mayContain: msExchGracePeriodPrior
+mayContain: msExchGracePeriodAfter
+mayContain: msExchAvailableServers
+mayContain: msExchAuditFlags
+mayContain: msExchAllowTimeExtensions
+mayContain: msExchAllowAdditionalResources
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Site
+adminDescription: ms-Exch-Conference-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchConferenceSite
+name: ms-Exch-Conference-Site
+schemaIDGUID: eddce330-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Conference-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Connection-Agreement
+# Used to store synchronization information.
+#
+dn: CN=ms-Exch-Connection-Agreement,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Connection-Agreement
+distinguishedName: CN=ms-Exch-Connection-Agreement,${SCHEMADN}
+possSuperiors: organizationalUnit
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.3
+mayContain: msExchIsConfigCA
+mayContain: msExchInterOrgAddressType
+mayContain: msExchMoveToLSA
+mayContain: msExchServer2HighestUSNVector
+mayContain: msExchServer1HighestUSNVector
+mayContain: msExchExchangeSite
+mayContain: msExchADCObjectType
+mayContain: msExchServer2IsBridgehead
+mayContain: msExchServer1IsBridgehead
+mayContain: versionNumber
+mayContain: msExchSynchronizationDirection
+mayContain: msExchServer2Type
+mayContain: msExchServer2SSLPort
+mayContain: msExchServer2SearchFilter
+mayContain: msExchServer2SchemaMap
+mayContain: msExchServer2Port
+mayContain: msExchServer2PageSize
+mayContain: msExchServer2NTAccountDomain
+mayContain: msExchServer2NetworkAddress
+mayContain: msExchServer2LastUpdateTime
+mayContain: msExchServer2ImportContainer
+mayContain: msExchServer2HighestUSN
+mayContain: msExchServer2Flags
+mayContain: msExchServer2ExportContainers
+mayContain: msExchServer2DeletionOption
+mayContain: msExchServer2AuthenticationType
+mayContain: msExchServer2AuthenticationPassword
+mayContain: msExchServer2AuthenticationCredentials
+mayContain: msExchServer2AlwaysCreateAs
+mayContain: msExchServer1Type
+mayContain: msExchServer1SSLPort
+mayContain: msExchServer1SearchFilter
+mayContain: msExchServer1SchemaMap
+mayContain: msExchServer1Port
+mayContain: msExchServer1PageSize
+mayContain: msExchServer1NTAccountDomain
+mayContain: msExchServer1NetworkAddress
+mayContain: msExchServer1LastUpdateTime
+mayContain: msExchServer1ImportContainer
+mayContain: msExchServer1HighestUSN
+mayContain: msExchServer1Flags
+mayContain: msExchServer1ExportContainers
+mayContain: msExchServer1DeletionOption
+mayContain: msExchServer1AuthenticationType
+mayContain: msExchServer1AuthenticationPassword
+mayContain: msExchServer1AuthenticationCredentials
+mayContain: msExchServer1AlwaysCreateAs
+mayContain: msExchReplicateNow
+mayContain: msExchRemoteServerList
+mayContain: msExchRemotePrivateISList
+mayContain: msExchNtdsImportContainer
+mayContain: msExchNtdsExportContainers
+mayContain: msExchNTAccountOptions
+mayContain: msExchIsBridgeheadSite
+mayContain: msExchHomeSyncService
+mayContain: msExchHomeServerName
+mayContain: msExchDoFullReplication
+mayContain: msExchDereferenceAliases
+mayContain: msExchCorrelationAttribute
+mayContain: msExchCASchemaPolicy
+mayContain: msExchAdditionalDNMap
+mayContain: msExchADCOptions
+mayContain: activationStyle
+mayContain: activationSchedule
+mayContain: displayName
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connection-Agreement
+adminDescription: ms-Exch-Connection-Agreement
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchConnectionAgreement
+name: ms-Exch-Connection-Agreement
+schemaIDGUID: ee64c93a-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Connection-Agreement,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Connector
+#
+dn: CN=ms-Exch-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Connector
+distinguishedName: CN=ms-Exch-Connector,${SCHEMADN}
+possSuperiors: msExchConnectors
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.12004
+mayContain: msExchMinAdminVersion
+mayContain: msExchInconsistentState
+mayContain: delivContLength
+mayContain: msExchNoPFConnection
+mayContain: versionNumber
+mayContain: msExchMasterAccountSid
+mayContain: msExchMailboxSecurityDescriptor
+mayContain: msExchMailboxGuid
+mayContain: msExchRoutingDisallowPriority
+mayContain: unauthOrig
+mayContain: msExchTargetBridgeheadServersDN
+mayContain: msExchSourceBridgeheadServersDN
+mayContain: msExchRoutingTriggeredStyle
+mayContain: msExchRoutingTriggeredSchedule
+mayContain: msExchRoutingOversizedStyle
+mayContain: msExchRoutingOversizedSchedule
+mayContain: routingList
+mayContain: messageSizeLimit
+mayContain: dLMemSubmitPerms
+mayContain: dLMemRejectPerms
+mayContain: dLMemDefault
+mayContain: msExchDestinationRGDN
+mayContain: msExchConnectorType
+mayContain: connectedDomains
+mayContain: authOrig
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connector
+adminDescription: ms-Exch-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchConnector
+name: ms-Exch-Connector
+schemaIDGUID: 89652316-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Connectors
+# Container used to hold connection objects.
+#
+dn: CN=ms-Exch-Connectors,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Connectors
+distinguishedName: CN=ms-Exch-Connectors,${SCHEMADN}
+possSuperiors: msExchRoutingGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.12003
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connectors
+adminDescription: ms-Exch-Connectors
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchConnectors
+name: ms-Exch-Connectors
+schemaIDGUID: eee325dc-a980-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Connectors,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Container
+# An Exchange container. Used for extended rights and roles.
+#
+dn: CN=ms-Exch-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Container
+distinguishedName: CN=ms-Exch-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50010
+mayContain: msExchMinAdminVersion
+mayContain: msExchAdminGroupMode
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Container
+adminDescription: ms-Exch-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchContainer
+name: ms-Exch-Container
+schemaIDGUID: 006c91da-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Content-Config-Container
+#
+dn: CN=ms-Exch-Content-Config-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Content-Config-Container
+distinguishedName: CN=ms-Exch-Content-Config-Container,${SCHEMADN}
+possSuperiors: container
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50026
+mayContain: msExchMinAdminVersion
+mayContain: msExchMimeTypes
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Content-Config-Container
+adminDescription: ms-Exch-Content-Config-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchContentConfigContainer
+name: ms-Exch-Content-Config-Container
+schemaIDGUID: ab3a1acc-1df5-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Content-Config-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP
+# An Exchange conference technology provider (CTP)
+# template. CN=Exchange Data Conferencing Service.
+#
+dn: CN=ms-Exch-CTP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-CTP
+distinguishedName: CN=ms-Exch-CTP,${SCHEMADN}
+possSuperiors: msExchConferenceSite
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.9002
+mayContain: objectCount
+mayContain: msExchCTPSnapinGUID
+mayContain: msExchCTPRequireCMSAuthentication
+mayContain: msExchCTPProviderName
+mayContain: msExchCTPProviderGUID
+mayContain: msExchCTPPropertySchema
+mayContain: msExchCTPFrameHint
+mayContain: msExchCTPClassGUID
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP
+adminDescription: ms-Exch-CTP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchCTP
+name: ms-Exch-CTP
+schemaIDGUID: 00aa8efe-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-CTP,${SCHEMADN}
+
+
+#
+# ms-Exch-Custom-Attributes
+# The auxiliary class for objects that require custom attributes.
+#
+dn: CN=ms-Exch-Custom-Attributes,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Custom-Attributes
+distinguishedName: CN=ms-Exch-Custom-Attributes,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.6
+mayContain: extensionAttribute9
+mayContain: extensionAttribute8
+mayContain: extensionAttribute7
+mayContain: extensionAttribute6
+mayContain: extensionAttribute5
+mayContain: extensionAttribute4
+mayContain: extensionAttribute3
+mayContain: extensionAttribute2
+mayContain: extensionAttribute15
+mayContain: extensionAttribute14
+mayContain: extensionAttribute13
+mayContain: extensionAttribute12
+mayContain: extensionAttribute11
+mayContain: extensionAttribute10
+mayContain: extensionAttribute1
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Custom-Attributes
+adminDescription: ms-Exch-Custom-Attributes
+objectClassCategory: 3
+lDAPDisplayName: msExchCustomAttributes
+name: ms-Exch-Custom-Attributes
+schemaIDGUID: 00e629c8-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Custom-Attributes,${SCHEMADN}
+
+
+#
+# ms-Exch-Domain-Content-Config
+#
+dn: CN=ms-Exch-Domain-Content-Config,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Domain-Content-Config
+distinguishedName: CN=ms-Exch-Domain-Content-Config,${SCHEMADN}
+possSuperiors: msExchContentConfigContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50027
+mayContain: msExchMinAdminVersion
+mayContain: versionNumber
+mayContain: msExchRoutingAcceptMessageType
+mayContain: msExchResolveP2
+mayContain: msExchNonMIMECharacterSet
+mayContain: msExchEncodeSMTPRelay
+mayContain: sendTNEF
+mayContain: msExchRoutingDisplaySenderEnabled
+mayContain: lineWrap
+mayContain: domainName
+mayContain: contentType
+mayContain: characterSet
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Content-Config
+adminDescription: ms-Exch-Domain-Content-Config
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchDomainContentConfig
+name: ms-Exch-Domain-Content-Config
+schemaIDGUID: ab3a1ad1-1df5-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Domain-Content-Config,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Site-Server
+# The hub for all of the directory exchange agent (DXA) server
+# connections.  
+#
+dn: CN=ms-Exch-DXA-Site-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-DXA-Site-Server
+distinguishedName: CN=ms-Exch-DXA-Site-Server,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.60
+mustContain: cn
+mayContain: versionNumber
+mayContain: assocRemoteDXA
+mayContain: responsibleLocalDXA
+mayContain: dXALocalAdmin
+mayContain: dXAAdminForward
+mayContain: dXAAdminCopy
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Site-Server
+adminDescription: ms-Exch-DXA-Site-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: dXASiteServer
+name: ms-Exch-DXA-Site-Server
+schemaIDGUID: a8df74b0-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-DXA-Site-Server,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-DX-Requestor
+# The remote directory exchange agent (DXA) requestor.
+#
+dn: CN=ms-Exch-DX-Requestor,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-DX-Requestor
+distinguishedName: CN=ms-Exch-DX-Requestor,${SCHEMADN}
+possSuperiors: container
+subClassOf: remoteDXA
+governsID: 1.2.840.113556.1.3.19
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DX-Requestor
+adminDescription: ms-Exch-DX-Requestor
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: dXRequestor
+name: ms-Exch-DX-Requestor
+schemaIDGUID: a8df74ae-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-DX-Requestor,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-DX-Server-Conn
+# The remote directory exchange agent (DXA) server.
+#
+dn: CN=ms-Exch-DX-Server-Conn,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-DX-Server-Conn
+distinguishedName: CN=ms-Exch-DX-Server-Conn,${SCHEMADN}
+possSuperiors: dXASiteServer
+subClassOf: remoteDXA
+governsID: 1.2.840.113556.1.3.20
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DX-Server-Conn
+adminDescription: ms-Exch-DX-Server-Conn
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: dXServerConn
+name: ms-Exch-DX-Server-Conn
+schemaIDGUID: a8df74af-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-DX-Server-Conn,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dynamic-Distribution-List
+#
+dn: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Dynamic-Distribution-List
+distinguishedName: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN}
+possSuperiors: organizationalUnit
+possSuperiors: domainDNS
+possSuperiors: builtinDomain
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.12006
+mayContain: msExchPurportedSearchUI
+mayContain: msExchDynamicDLFilter
+mayContain: msExchDynamicDLBaseDN
+mayContain: managedBy
+mayContain: reportToOwner
+mayContain: reportToOriginator
+mayContain: oOFReplyToOriginator
+mayContain: msExchMemberFilter
+mayContain: msExchMemberBaseDN
+mayContain: hideDLMembership
+mayContain: mail
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dynamic-Distribution-List
+adminDescription: ms-Exch-Dynamic-Distribution-List
+auxiliaryClass: msExchCustomAttributes
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: msExchDynamicDistributionList
+name: ms-Exch-Dynamic-Distribution-List
+schemaIDGUID: 018849b0-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;RP;;;AU)
+defaultHidingValue: FALSE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Dynamic-Distribution-List,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Encryption-Cfg
+# Contains attributes that configure security policies for each
+# Administrative group.
+#
+dn: CN=ms-Exch-Encryption-Cfg,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Encryption-Cfg
+distinguishedName: CN=ms-Exch-Encryption-Cfg,${SCHEMADN}
+possSuperiors: msExchAdvancedSecurityContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.16
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: sMIMEAlgSelectedOther
+mayContain: sMIMEAlgSelectedNA
+mayContain: sMIMEAlgListOther
+mayContain: sMIMEAlgListNA
+mayContain: kMServer
+mayContain: encryptAlgSelectedOther
+mayContain: encryptAlgSelectedNA
+mayContain: encryptAlgListOther
+mayContain: encryptAlgListNA
+mayContain: defaultMessageFormat
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encryption-Cfg
+adminDescription: ms-Exch-Encryption-Cfg
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: encryptionCfg
+name: ms-Exch-Encryption-Cfg
+schemaIDGUID: a8df74b1-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;RP;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Encryption-Cfg,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Exchange-Admin-Service
+# The MAD process.
+#
+dn: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Exchange-Admin-Service
+distinguishedName: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN}
+possSuperiors: msExchExchangeServer
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.62
+mustContain: deliveryMechanism
+mayContain: msExchMinAdminVersion
+mayContain: diagnosticRegKey
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Exchange-Admin-Service
+adminDescription: ms-Exch-Exchange-Admin-Service
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: exchangeAdminService
+name: ms-Exch-Exchange-Admin-Service
+schemaIDGUID: a8df74b2-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Exchange-Admin-Service,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Exchange-Server
+# A representation of an Exchange server object.
+#
+dn: CN=ms-Exch-Exchange-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Exchange-Server
+distinguishedName: CN=ms-Exch-Exchange-Server,${SCHEMADN}
+possSuperiors: msExchServersContainer
+subClassOf: server
+governsID: 1.2.840.113556.1.5.7000.62.50009
+mayContain: msExchMinAdminVersion
+mayContain: msExchFolderAffinityList
+mayContain: msExchFolderAffinityCustom
+mayContain: msExchHomeRoutingGroupDNBL
+mayContain: msExchHomeRoutingGroup
+mayContain: msExchVPIMConvertOutbound
+mayContain: msExchVPIMConvertInbound
+mayContain: msExchServerPublicKey
+mayContain: msExchMonitoringResources
+mayContain: msExchMonitoringPollingRate
+mayContain: msExchMonitoringNotificationRate
+mayContain: msExchMonitoringMode
+mayContain: msExchMailboxManagerReportRecipient
+mayContain: msExchMailboxManagerAdminMode
+mayContain: msExchMailboxManagerActivationStyle
+mayContain: msExchMailboxManagerActivationSchedule
+mayContain: msExchResponsibleMTAServer
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyList
+mayContain: msExchMonitoringResponses
+mayContain: msExchMonitoringQueuePollingInterval
+mayContain: msExchMonitoringQueuePollingFrequency
+mayContain: msExchMonitoringMonitoredServices
+mayContain: msExchMonitoringDiskSpace
+mayContain: monitoredServices
+mayContain: msExchInstalledComponents
+mayContain: msExchDataPath
+mayContain: msExchServerRole
+mayContain: msExchMessageTrackLogFilter
+mayContain: versionNumber
+mayContain: serverRole
+mayContain: serialNumber
+mayContain: msExchTrkLogCleaningInterval
+mayContain: messageTrackingEnabled
+mayContain: msExchLocales
+mayContain: msExchInstallPath
+mayContain: heuristics
+mayContain: msExchComputerLink
+mayContain: msExchAddressListServiceBL
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Exchange-Server
+adminDescription: ms-Exch-Exchange-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchExchangeServer
+name: ms-Exch-Exchange-Server
+schemaIDGUID: 01a9aa9c-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;RP;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Exchange-Server,${SCHEMADN}
+
+
+
+#
+# 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.
+#
+dn: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Exchange-Server-Policy
+distinguishedName: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: msExchExchangeServer
+governsID: 1.2.840.113556.1.5.7000.62.50025
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Exchange-Server-Policy
+adminDescription: ms-Exch-Exchange-Server-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchExchangeServerPolicy
+name: ms-Exch-Exchange-Server-Policy
+schemaIDGUID: e497942f-1d42-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Exchange-Server-Policy,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Generic-Policy
+#
+dn: CN=ms-Exch-Generic-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Generic-Policy
+distinguishedName: CN=ms-Exch-Generic-Policy,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50022
+mayContain: purportedSearch
+mayContain: msExchPurportedSearchUI
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Generic-Policy
+adminDescription: ms-Exch-Generic-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchGenericPolicy
+name: ms-Exch-Generic-Policy
+schemaIDGUID: e32977cd-1d31-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Generic-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Generic-Policy-Container
+#
+dn: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Generic-Policy-Container
+distinguishedName: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50021
+mayContain: msExchADCOptions
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Generic-Policy-Container
+adminDescription: ms-Exch-Generic-Policy-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchGenericPolicyContainer
+name: ms-Exch-Generic-Policy-Container
+schemaIDGUID: e32977c3-1d31-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Generic-Policy-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-GroupWise-Connector	 
+# The GroupWise Connector.
+#
+dn: CN=ms-Exch-GroupWise-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-GroupWise-Connector
+distinguishedName: CN=ms-Exch-GroupWise-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1005
+mayContain: msExchGWiseUserId
+mayContain: msExchGWisePassword
+mayContain: msExchGWiseForeignDomain
+mayContain: msExchGWiseFilterType
+mayContain: msExchGWiseAPIGatewayPath
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GroupWise-Connector
+adminDescription: ms-Exch-GroupWise-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchGroupWiseConnector
+name: ms-Exch-GroupWise-Connector
+schemaIDGUID: 91eaaac4-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-GroupWise-Connector,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-IM-Firewall	
+# The Instant Messaging representation of firewalls.
+#
+dn: CN=ms-Exch-IM-Firewall,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-IM-Firewall
+distinguishedName: CN=ms-Exch-IM-Firewall,${SCHEMADN}
+possSuperiors: msExchIMGlobalSettingsContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.7015
+mustContain: msExchIMFirewallType
+mayContain: portNumber
+mayContain: msExchIMProxy
+mayContain: msExchIMIPRange
+mayContain: flags
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Firewall
+adminDescription: ms-Exch-IM-Firewall
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchIMFirewall
+name: ms-Exch-IM-Firewall
+schemaIDGUID: 9f116ebe-284e-11d3-aa68-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-IM-Firewall,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Global-Settings-Container	
+# A container for global objects.
+#
+dn: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-IM-Global-Settings-Container
+distinguishedName: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN}
+possSuperiors: container
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.7014
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Global-Settings-Container
+adminDescription: ms-Exch-IM-Global-Settings-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchIMGlobalSettingsContainer
+name: ms-Exch-IM-Global-Settings-Container
+schemaIDGUID: 9f116eb8-284e-11d3-aa68-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-IM-Global-Settings-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Recipient	
+# The auxiliary class for all objects that will be enabled for Instant
+# Messaging.
+#
+dn: CN=ms-Exch-IM-Recipient,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-IM-Recipient
+distinguishedName: CN=ms-Exch-IM-Recipient,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.7008
+mayContain: msExchIMVirtualServer
+mayContain: msExchIMAddress
+mayContain: msExchIMPhysicalURL
+mayContain: msExchIMMetaPhysicalURL
+mayContain: msExchIMACL
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Recipient
+adminDescription: ms-Exch-IM-Recipient
+objectClassCategory: 3
+lDAPDisplayName: msExchIMRecipient
+name: ms-Exch-IM-Recipient
+schemaIDGUID: 028502f4-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-IM-Recipient,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Information-Store	    
+# The Information Store configuration.
+#
+dn: CN=ms-Exch-Information-Store,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Information-Store
+distinguishedName: CN=ms-Exch-Information-Store,${SCHEMADN}
+possSuperiors: msExchExchangeServer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.11001
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: msExchMaxRestoreStorageGroups
+mayContain: msExchRecovery
+mayContain: msExchESEParamZeroDatabaseDuringBackup
+mayContain: msExchESEParamPageTempDBMin
+mayContain: msExchESEParamPageFragment
+mayContain: msExchESEParamLogFileSize
+mayContain: msExchESEParamLogCheckpointPeriod
+mayContain: msExchESEParamLogBuffers
+mayContain: msExchESEParamGlobalMinVerPages
+mayContain: msExchESEParamEventSource
+mayContain: msExchESEParamEnableSortedRetrieveColumns
+mayContain: msExchESEParamEnableOnlineDefrag
+mayContain: msExchESEParamEnableIndexChecking
+mayContain: msExchESEParamDbExtensionSize
+mayContain: msExchESEParamCommitDefault
+mayContain: msExchESEParamCircularLog
+mayContain: msExchESEParamCacheSizeMin
+mayContain: msExchESEParamBaseName
+mayContain: msExchESEParamAssertAction
+mayContain: msExchESEParamStopFlushThreshold
+mayContain: msExchESEParamStartFlushThreshold
+mayContain: msExchQueuingMDB
+mayContain: msExchOwningOrg
+mayContain: msExchMinimumThreads
+mayContain: msExchMaxThreads
+mayContain: msExchMaxStoresPerGroup
+mayContain: msExchMaxStorageGroups
+mayContain: msExchMaxPoolThreads
+mayContain: msExchIFSPublicName
+mayContain: msExchIFSPublicEnabled
+mayContain: msExchIFSPrivateName
+mayContain: msExchIFSPrivateEnabled
+mayContain: msExchESEParamCacheSizeMax
+mayContain: msExchESEParamCacheSize
+mayContain: msExchDatabaseSessionIncrement
+mayContain: msExchDatabaseSessionAddend
+mayContain: msExchBackgroundThreads
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Information-Store
+adminDescription: ms-Exch-Information-Store
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchInformationStore
+name: ms-Exch-Information-Store
+schemaIDGUID: 031b371a-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Information-Store,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Ip-Conf-Container	
+# The Exchange Video Conferencing container.
+#
+dn: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Ip-Conf-Container
+distinguishedName: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN}
+possSuperiors: msExchConferenceSite
+subClassOf: msExchCTP
+governsID: 1.2.840.113556.1.5.7000.62.9006
+mayContain: msExchMaxParticipants
+mayContain: msExchMaxExtensionTime
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Ip-Conf-Container
+adminDescription: ms-Exch-Ip-Conf-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchIpConfContainer
+name: ms-Exch-Ip-Conf-Container
+schemaIDGUID: 99f5866d-12e8-11d3-aa58-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Ip-Conf-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Key-Management-Server	
+# Holds configuration attributes for each Key Management Service.
+#
+dn: CN=ms-Exch-Key-Management-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Key-Management-Server
+distinguishedName: CN=ms-Exch-Key-Management-Server,${SCHEMADN}
+possSuperiors: msExchAdvancedSecurityContainer
+subClassOf: certificationAuthority
+governsID: 1.2.840.113556.1.5.7000.62.13002
+mayContain: sendEMailMessage
+mayContain: securityPolicy
+mayContain: kMServer
+mayContain: kCCStatus
+mayContain: expirationTime
+mayContain: enableCompatibility
+mayContain: dXAPrevTypes
+mayContain: dXAAdminForward
+mayContain: domainDefAltRecip
+mayContain: crossCertificateCRL
+mayContain: compromisedKeyList
+mayContain: certificateRevocationListV3
+mayContain: certificateRevocationListV1
+mayContain: certificateChainV3
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Key-Management-Server
+adminDescription: ms-Exch-Key-Management-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchKeyManagementServer
+name: ms-Exch-Key-Management-Server
+schemaIDGUID: 8ce334ec-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;RP;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Key-Management-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-DXA 	
+# Represents the directory exchange agent (DXA) process.
+#
+dn: CN=ms-Exch-Local-DXA,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Local-DXA
+distinguishedName: CN=ms-Exch-Local-DXA,${SCHEMADN}
+possSuperiors: msExchExchangeServer
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.1
+mustContain: deliveryMechanism
+mayContain: msExchServer1NetworkAddress
+mayContain: msExchServer1AlwaysCreateAs
+mayContain: delivEITs
+mayContain: dXATemplateTimeStamp
+mayContain: dXAOutTemplateMap
+mayContain: dXAInTemplateMap
+mayContain: dXAAdminUpdate
+mayContain: diagnosticRegKey
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-DXA
+adminDescription: ms-Exch-Local-DXA
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: localDXA
+name: ms-Exch-Local-DXA
+schemaIDGUID: a8df74b5-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Local-DXA,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Policy
+#
+dn: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Mailbox-Manager-Policy
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50033
+mayContain: msExchMailboxManagerUserMessageHeader
+mayContain: msExchMailboxManagerUserMessageFooter
+mayContain: msExchMailboxManagerUserMessageBody
+mayContain: msExchMailboxManagerSizeLimitEnabled
+mayContain: msExchMailboxManagerSizeLimit
+mayContain: msExchMailboxManagerSendUserNotificationMail
+mayContain: msExchMailboxManagerMode
+mayContain: msExchMailboxManagerKeepMessageClasses
+mayContain: msExchMailboxManagerFolderSettings
+mayContain: msExchMailboxManagerCustomMessage
+mayContain: msExchMailboxManagerAgeLimit
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Policy
+adminDescription: ms-Exch-Mailbox-Manager-Policy
+objectClassCategory: 3
+lDAPDisplayName: msExchMailboxManagerPolicy
+name: ms-Exch-Mailbox-Manager-Policy
+schemaIDGUID: 36f94fcc-ebbb-4a32-b721-1cae42b2dbab
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Mailbox-Manager-Policy,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Mail-Connector    
+# The Microsoft Mail Connector object.
+#
+dn: CN=ms-Exch-Mail-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Mail-Connector
+distinguishedName: CN=ms-Exch-Mail-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.3.61
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mail-Connector
+adminDescription: ms-Exch-Mail-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mailConnector
+name: ms-Exch-Mail-Connector
+schemaIDGUID: a8df74b6-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Mail-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mail-Gateway    
+# The main Gateway class.
+#
+dn: CN=ms-Exch-Mail-Gateway,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Mail-Gateway
+distinguishedName: CN=ms-Exch-Mail-Gateway,${SCHEMADN}
+possSuperiors: container
+subClassOf: msExchConnector
+governsID: 1.2.840.113556.1.3.51
+mustContain: homeMTA
+mustContain: deliveryMechanism
+mustContain: cn
+mayContain: msExchBarMessageClass
+mayContain: msExchEncryptedPassword2
+mayContain: msExchEncryptedPassword
+mayContain: msExchServer1NetworkAddress
+mayContain: msExchMaintenanceStyle
+mayContain: msExchMaintenanceSchedule
+mayContain: msExchImportContainerLinked
+mayContain: msExchExportContainersLinked
+mayContain: msExchServer1AlwaysCreateAs
+mayContain: msExchDirsyncStyle
+mayContain: msExchDirsyncSchedule
+mayContain: supportedApplicationContext
+mayContain: translationTableUsed
+mayContain: transferTimeoutUrgent
+mayContain: transferTimeoutNormal
+mayContain: transferTimeoutNonUrgent
+mayContain: transferRetryInterval
+mayContain: msExchSourceBHAddress
+mayContain: replicationSensitivity
+mayContain: pRMD
+mayContain: msExchPartnerLanguage
+mayContain: msExchPartnerCP
+mayContain: mDBUnreadLimit
+mayContain: mDBStorageQuota
+mayContain: mDBMsgTimeOutPeriod
+mayContain: mDBBackoffInterval
+mayContain: lineWrap
+mayContain: importContainer
+mayContain: homeMDB
+mayContain: msExchExportDLs
+mayContain: exportCustomRecipients
+mayContain: exportContainers
+mayContain: encapsulationMethod
+mayContain: msExchDirsyncFilters
+mayContain: diagnosticRegKey
+mayContain: msExchDestinationRGDN
+mayContain: msExchDestBHAddress
+mayContain: msExchDeliveryOrder
+mayContain: delivExtContTypes
+mayContain: delivEITs
+mayContain: delivContLength
+mayContain: msExchConnectorType
+mayContain: computerName
+mayContain: canPreserveDNs
+mayContain: msExchAdminMailbox
+mayContain: aDMD
+mayContain: c
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mail-Gateway
+adminDescription: ms-Exch-Mail-Gateway
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mailGateway
+name: ms-Exch-Mail-Gateway
+schemaIDGUID: a8df74b7-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Mail-Gateway,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mail-Storage 	
+# The auxiliary class for objects that require store-specific information.
+#
+dn: CN=ms-Exch-Mail-Storage,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Mail-Storage
+distinguishedName: CN=ms-Exch-Mail-Storage,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5
+mayContain: msExchPfRootUrl
+mayContain: msExchMailboxUrl
+mayContain: msExchUseOAB
+mayContain: msExchMailboxGuid
+mayContain: mDBUseDefaults
+mayContain: mDBStorageQuota
+mayContain: mDBOverQuotaLimit
+mayContain: mDBOverHardQuotaLimit
+mayContain: msExchHomeServerName
+mayContain: homeMDB
+mayContain: deletedItemFlags
+mayContain: autoReply
+mayContain: garbageCollPeriod
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mail-Storage
+adminDescription: ms-Exch-Mail-Storage
+objectClassCategory: 3
+lDAPDisplayName: msExchMailStorage
+name: ms-Exch-Mail-Storage
+schemaIDGUID: 03652000-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Mail-Storage,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MCU    
+# The Exchange Conferencing Multipoint Control Unit (MCU) Configuration
+# Interface . CN=MachineName.
+#
+dn: CN=ms-Exch-MCU,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MCU
+distinguishedName: CN=ms-Exch-MCU,${SCHEMADN}
+possSuperiors: msExchMCUContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.9004
+mayContain: msExchMCUHostsSites
+mayContain: msExchVisibilityMask
+mayContain: msExchScopeMask
+mayContain: msExchProxyName
+mayContain: msExchLocalName
+mayContain: msExchInternetName
+mayContain: enabledConnection
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MCU
+adminDescription: ms-Exch-MCU
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchMCU
+name: ms-Exch-MCU
+schemaIDGUID: 038680ec-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MCU,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MCU-Container 	     
+# The Exchange Data Conference Service class. CN=Exchange Data
+# Conferencing Service.
+#
+dn: CN=ms-Exch-MCU-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MCU-Container
+distinguishedName: CN=ms-Exch-MCU-Container,${SCHEMADN}
+possSuperiors: msExchConferenceSite
+subClassOf: msExchCTP
+governsID: 1.2.840.113556.1.5.7000.62.9003
+mayContain: rangeUpper
+mayContain: rangeLower
+mayContain: msExchMaxConnections
+mayContain: msExchListPublic
+mayContain: msExchCertificate
+mayContain: msExchAuditFlags
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MCU-Container
+adminDescription: ms-Exch-MCU-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchMCUContainer
+name: ms-Exch-MCU-Container
+schemaIDGUID: 03aa4432-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MCU-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MDB  
+# Used for generic database configuration.
+#
+dn: CN=ms-Exch-MDB,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MDB
+distinguishedName: CN=ms-Exch-MDB,${SCHEMADN}
+possSuperiors: msExchStorageGroup
+possSuperiors: msExchExchangeServer
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.11002
+mustContain: deliveryMechanism
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: msExchPatchMDB
+mayContain: msExchDatabaseCreated
+mayContain: msExchDatabaseBeingRestored
+mayContain: msExchAllowEnhancedSecurity
+mayContain: msExchMaxCachedViews
+mayContain: msExchCIUpdateStyle
+mayContain: msExchCIUpdateSchedule
+mayContain: msExchCIRebuildStyle
+mayContain: msExchCIRebuildSchedule
+mayContain: msExchCILocation
+mayContain: msExchCIAvailable
+mayContain: msExchAgingKeepTime
+mayContain: homeMDBBL
+mayContain: msExchTrackDuplicates
+mayContain: msExchSLVFile
+mayContain: quotaNotificationStyle
+mayContain: quotaNotificationSchedule
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyList
+mayContain: msExchOwningServer
+mayContain: messageTrackingEnabled
+mayContain: mDBStorageQuota
+mayContain: mDBOverQuotaLimit
+mayContain: mDBOverHardQuotaLimit
+mayContain: maximumObjectID
+mayContain: msExchEDBOffline
+mayContain: msExchEDBFile
+mayContain: msExchDownGradeMultipartSigned
+mayContain: diagnosticRegKey
+mayContain: deletedItemFlags
+mayContain: msExchConvertToFixedFont
+mayContain: msExchCatalog
+mayContain: activationStyle
+mayContain: activationSchedule
+mayContain: garbageCollPeriod
+mayContain: displayName
+mayContain: description
+mayContain: adminDisplayName
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB
+adminDescription: ms-Exch-MDB
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchMDB
+name: ms-Exch-MDB
+schemaIDGUID: 03d069d2-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MDB,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Message-Delivery-Config
+#
+dn: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Message-Delivery-Config
+distinguishedName: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50028
+mayContain: msExchMinAdminVersion
+mayContain: msExchTurfListAction
+mayContain: submissionContLength
+mayContain: msExchRecipLimit
+mayContain: msExchLocalDomains
+mayContain: delivContLength
+mayContain: msExchAdminMailbox
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Message-Delivery-Config
+adminDescription: ms-Exch-Message-Delivery-Config
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchMessageDeliveryConfig
+name: ms-Exch-Message-Delivery-Config
+schemaIDGUID: ab3a1ad7-1df5-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Message-Delivery-Config,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MHS-Link-Monitoring-Config     
+# The EMS saved Linked Monitoring configuration.
+#
+dn: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MHS-Link-Monitoring-Config
+distinguishedName: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN}
+possSuperiors: container
+subClassOf: mHSMonitoringConfig
+governsID: 1.2.840.113556.1.3.12
+mayContain: monitoringWarningUnits
+mayContain: monitoringWarningDelay
+mayContain: monitoringRecipientsNDR
+mayContain: monitoringRecipients
+mayContain: monitoringAlertUnits
+mayContain: monitoringAlertDelay
+mayContain: monitorServers
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MHS-Link-Monitoring-Config
+adminDescription: ms-Exch-MHS-Link-Monitoring-Config
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mHSLinkMonitoringConfig
+name: ms-Exch-MHS-Link-Monitoring-Config
+schemaIDGUID: a8df74b9-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MHS-Link-Monitoring-Config,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MHS-Monitoring-Config 	
+# The EMS saved Monitoring configuration.
+#
+dn: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MHS-Monitoring-Config
+distinguishedName: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.6
+mustContain: cn
+mayContain: runsOn
+mayContain: monitoringNormalPollUnits
+mayContain: monitoringNormalPollInterval
+mayContain: monitoringHotsitePollUnits
+mayContain: monitoringHotsitePollInterval
+mayContain: monitoringEscalationProcedure
+mayContain: monitoringAvailabilityWindow
+mayContain: monitoringAvailabilityStyle
+mayContain: monitoredServers
+mayContain: logFilename
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MHS-Monitoring-Config
+adminDescription: ms-Exch-MHS-Monitoring-Config
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mHSMonitoringConfig
+name: ms-Exch-MHS-Monitoring-Config
+schemaIDGUID: a8df74bb-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MHS-Monitoring-Config,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MHS-Server-Monitoring-Config	
+# The EMS saved Server Monitoring configuration.
+#
+dn: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MHS-Server-Monitoring-Config
+distinguishedName: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN}
+possSuperiors: container
+subClassOf: mHSMonitoringConfig
+governsID: 1.2.840.113556.1.3.7
+mayContain: serviceRestartMessage
+mayContain: serviceRestartDelay
+mayContain: serviceActionSecond
+mayContain: serviceActionOther
+mayContain: serviceActionFirst
+mayContain: monitorServices
+mayContain: monitorClock
+mayContain: clockWarningRepair
+mayContain: clockWarningOffset
+mayContain: clockAlertRepair
+mayContain: clockAlertOffset
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MHS-Server-Monitoring-Config
+adminDescription: ms-Exch-MHS-Server-Monitoring-Config
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mHSServerMonitoringConfig
+name: ms-Exch-MHS-Server-Monitoring-Config
+schemaIDGUID: a8df74bd-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MHS-Server-Monitoring-Config,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitors-Container	
+# A container used to hold monitors. Used for extended rights and roles.
+#
+dn: CN=ms-Exch-Monitors-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Monitors-Container
+distinguishedName: CN=ms-Exch-Monitors-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50012
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitors-Container
+adminDescription: ms-Exch-Monitors-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchMonitorsContainer
+name: ms-Exch-Monitors-Container
+schemaIDGUID: 03f68f72-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Monitors-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MS-Mail-Connector	   
+# The Microsoft Mail Connector object.
+#
+dn: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MS-Mail-Connector
+distinguishedName: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.3.31
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MS-Mail-Connector
+adminDescription: ms-Exch-MS-Mail-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mSMailConnector
+name: ms-Exch-MS-Mail-Connector
+schemaIDGUID: a8df74be-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MS-Mail-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MTA  
+# Represents the message transfer agent (MTA) process on the computer.
+#
+dn: CN=ms-Exch-MTA,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MTA
+distinguishedName: CN=ms-Exch-MTA,${SCHEMADN}
+possSuperiors: msExchExchangeServer
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.49
+mustContain: transTimeoutMins
+mustContain: transRetryMins
+mustContain: mTALocalDesig
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: msExchEncryptedPassword
+mayContain: msExchResponsibleMTAServerBL
+mayContain: msExchMTADatabasePath
+mayContain: xMITTimeoutUrgent
+mayContain: xMITTimeoutNormal
+mayContain: xMITTimeoutNonUrgent
+mayContain: transportExpeditedData
+mayContain: transferTimeoutUrgent
+mayContain: transferTimeoutNormal
+mayContain: transferTimeoutNonUrgent
+mayContain: transferRetryInterval
+mayContain: tempAssocThreshold
+mayContain: sessionDisconnectTimer
+mayContain: rTSWindowSize
+mayContain: rTSRecoveryTimeout
+mayContain: rTSCheckpointSize
+mayContain: openRetryInterval
+mayContain: numOfTransferRetries
+mayContain: numOfOpenRetries
+mayContain: messageTrackingEnabled
+mayContain: domainDefAltRecip
+mayContain: associationLifetime
+mayContain: mTALocalCred
+mayContain: msExchHomeRoutingGroupDNBL
+mayContain: expandDLsLocally
+mayContain: diagnosticRegKey
+mayContain: delivExtContTypes
+mayContain: delivEITs
+mayContain: delivContLength
+mayContain: msExchBridgeheadedRemoteConnectorsDNBL
+mayContain: msExchBridgeheadedLocalConnectorsDNBL
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MTA
+adminDescription: ms-Exch-MTA
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mTA
+name: ms-Exch-MTA
+schemaIDGUID: a8df74a7-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MTA,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MTA-Cfg  
+#
+dn: CN=ms-Exch-MTA-Cfg,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-MTA-Cfg
+distinguishedName: CN=ms-Exch-MTA-Cfg,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.3
+mustContain: cn
+mayContain: xMITTimeoutUrgent
+mayContain: xMITTimeoutNormal
+mayContain: xMITTimeoutNonUrgent
+mayContain: transportExpeditedData
+mayContain: transferTimeoutUrgent
+mayContain: transferTimeoutNormal
+mayContain: transferTimeoutNonUrgent
+mayContain: transferRetryInterval
+mayContain: tempAssocThreshold
+mayContain: sessionDisconnectTimer
+mayContain: rTSWindowSize
+mayContain: rTSRecoveryTimeout
+mayContain: rTSCheckpointSize
+mayContain: openRetryInterval
+mayContain: numOfTransferRetries
+mayContain: numOfOpenRetries
+mayContain: messageTrackingEnabled
+mayContain: domainDefAltRecip
+mayContain: associationLifetime
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MTA-Cfg
+adminDescription: ms-Exch-MTA-Cfg
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: mTACfg
+name: ms-Exch-MTA-Cfg
+schemaIDGUID: a8df74a8-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-MTA-Cfg,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Multi-Media-User
+# Contains attributes for voice mailbox configuration. The attributes
+# can be updated by the mailbox owner.
+#
+dn: CN=ms-Exch-Multi-Media-User,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Multi-Media-User
+distinguishedName: CN=ms-Exch-Multi-Media-User,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.17002
+mayContain: msExchVoiceMailboxID
+mayContain: msExchTUIVolume
+mayContain: msExchTUISpeed
+mayContain: msExchTUIPassword
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Multi-Media-User
+adminDescription: ms-Exch-Multi-Media-User
+objectClassCategory: 3
+lDAPDisplayName: msExchMultiMediaUser
+name: ms-Exch-Multi-Media-User
+schemaIDGUID: 1529cf7a-2fdb-11d3-aa6d-00c04f8eedd8
+systemOnly: FALSE
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Multi-Media-User,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Connector 
+# The Lotus Notes Connector object.
+#
+dn: CN=ms-Exch-Notes-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Notes-Connector
+distinguishedName: CN=ms-Exch-Notes-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1002
+mayContain: msExchNotesPassword
+mayContain: msExchNotesTargetBooks
+mayContain: msExchNotesTargetBook
+mayContain: msExchNotesSourceBooks
+mayContain: msExchNotesRtrMailbox
+mayContain: msExchNotesRoutableDomains
+mayContain: msExchNotesNotesServer
+mayContain: msExchNotesNotesLinks
+mayContain: msExchNotesNotesINI
+mayContain: msExchNotesLetterhead
+mayContain: msExchNotesForeignDomain
+mayContain: msExchNotesExportGroups
+mayContain: msExchNotesExcludeGroups
+mayContain: msExchNotesConnectorMailbox
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Connector
+adminDescription: ms-Exch-Notes-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchNotesConnector
+name: ms-Exch-Notes-Connector
+schemaIDGUID: 04c85e62-a981-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Notes-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-OAB	  
+# The offline address book (OAB) configuration object.
+#
+dn: CN=ms-Exch-OAB,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-OAB
+distinguishedName: CN=ms-Exch-OAB,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.9
+mustContain: offLineABStyle
+mustContain: offLineABServer
+mustContain: offLineABSchedule
+mustContain: offLineABContainers
+mustContain: msExchOABFolder
+mustContain: doOABVersion
+mayContain: siteFolderServer
+mayContain: siteFolderGUID
+mayContain: msExchUseOABBL
+mayContain: msExchOABDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OAB
+adminDescription: ms-Exch-OAB
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchOAB
+name: ms-Exch-OAB
+schemaIDGUID: 3686cdd4-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-OAB,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Carrier      
+# Contains wireless carrier information.
+#
+dn: CN=ms-Exch-Oma-Carrier,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Carrier
+distinguishedName: CN=ms-Exch-Oma-Carrier,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.37
+mayContain: msExchMinAdminVersion
+mayContain: msExchOmaTranslator
+mayContain: msExchOmaExtendedProperties
+mayContain: msExchOmaDeliveryProviderDN
+mayContain: msExchOmaConfiguration
+mayContain: msExchOmaCarrierUrl
+mayContain: msExchOmaCarrierType
+mayContain: msExchOmaCarrierAddress
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Carrier
+adminDescription: ms-Exch-Oma-Carrier
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaCarrier
+name: ms-Exch-Oma-Carrier
+schemaIDGUID: 8712d34c-27e5-41b2-976e-482ad8c954e7
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Carrier,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Configuration-Container	
+# The parent container for all OMA configuration data.
+#
+dn: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Configuration-Container
+distinguishedName: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.32
+mayContain: msExchMinAdminVersion
+mayContain: msExchOmaExtendedProperties
+mayContain: msExchOmaAdminWirelessEnable
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Configuration-Container
+adminDescription: ms-Exch-Oma-Configuration-Container
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaConfigurationContainer
+name: ms-Exch-Oma-Configuration-Container
+schemaIDGUID: db0f9abb-0770-4f09-ba64-7993d91517b7
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Configuration-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Connector  
+#
+dn: CN=ms-Exch-Oma-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Connector
+distinguishedName: CN=ms-Exch-Oma-Connector,${SCHEMADN}
+subClassOf: msExchConnector
+governsID: 1.2.840.113556.1.6.20.2.39
+mayContain: msExchSourceBridgeheadServersDN
+mayContain: msExchOmaCarrierUrl
+mayContain: deliveryMechanism
+mayContain: legacyExchangeDN
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Connector
+adminDescription: ms-Exch-Oma-Connector
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaConnector
+name: ms-Exch-Oma-Connector
+schemaIDGUID: 4dc9d0b1-594c-407e-a7d2-426e6c20dabb
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Container  
+# The parent container for OMA device types.
+#
+dn: CN=ms-Exch-Oma-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Container
+distinguishedName: CN=ms-Exch-Oma-Container,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.38
+mayContain: msExchMinAdminVersion
+mayContain: msExchOmaExtendedProperties
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Container
+adminDescription: ms-Exch-Oma-Container
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaContainer
+name: ms-Exch-Oma-Container
+schemaIDGUID: 863dab20-fb40-43a4-a5e1-825b2071050f
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Data-Source	    
+# Contains information about business logic that can validate a push
+# notification.
+#
+dn: CN=ms-Exch-Oma-Data-Source,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Data-Source
+distinguishedName: CN=ms-Exch-Oma-Data-Source,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.35
+mayContain: msExchOmaValidater
+mayContain: msExchOmaExtendedProperties
+mayContain: msExchOmaDeviceCapabilityDN
+mayContain: msExchOmaDeliveryProviderDN
+mayContain: msExchOmaConfiguration
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Data-Source
+adminDescription: ms-Exch-Oma-Data-Source
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaDataSource
+name: ms-Exch-Oma-Data-Source
+schemaIDGUID: dda38a4d-972a-44a2-9244-0acb4b1d34d1
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Data-Source,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Delivery-Provider 
+# Contains delivery protocol information.
+#
+dn: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Delivery-Provider
+distinguishedName: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.36
+mayContain: msExchOmaExtendedProperties
+mayContain: msExchOmaDeviceCapabilityDN
+mayContain: msExchOmaDeliverer
+mayContain: msExchOmaConfiguration
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Delivery-Provider
+adminDescription: ms-Exch-Oma-Delivery-Provider
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaDeliveryProvider
+name: ms-Exch-Oma-Delivery-Provider
+schemaIDGUID: cdbf130d-c7e2-4572-94b0-fc9be7eef953
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Delivery-Provider,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Device-Capability	
+# Device support for an application (such as SMS Text).
+#
+dn: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Device-Capability
+distinguishedName: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.34
+mayContain: msExchOmaFormatter
+mayContain: msExchOmaExtendedProperties
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Device-Capability
+adminDescription: ms-Exch-Oma-Device-Capability
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaDeviceCapability
+name: ms-Exch-Oma-Device-Capability
+schemaIDGUID: df7af4df-f318-4e2c-ac43-be5b4894711c
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Device-Capability,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Device-Type	  
+# Contains the make and model of a wireless device with
+# characteristics.
+#
+dn: CN=ms-Exch-Oma-Device-Type,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-Device-Type
+distinguishedName: CN=ms-Exch-Oma-Device-Type,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.6.20.2.33
+mayContain: msExchOmaExtendedProperties
+mayContain: msExchOmaDeviceCapabilityDN
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Device-Type
+adminDescription: ms-Exch-Oma-Device-Type
+objectClassCategory: 1
+lDAPDisplayName: msExchOmaDeviceType
+name: ms-Exch-Oma-Device-Type
+schemaIDGUID: ca7a8fb3-21d0-4ea7-af3f-d15c6df7c094
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LCLORPRC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-Device-Type,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-User	    
+# Extends the Active Directory User.
+#
+dn: CN=ms-Exch-Oma-User,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Oma-User
+distinguishedName: CN=ms-Exch-Oma-User,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.6.20.2.31
+mayContain: msExchOmaAdminWirelessEnable
+mayContain: msExchOmaAdminExtendedSettings
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-User
+adminDescription: ms-Exch-Oma-User
+objectClassCategory: 3
+lDAPDisplayName: msExchOmaUser
+name: ms-Exch-Oma-User
+schemaIDGUID: 36a0a976-dd8d-4aad-81fd-a1b5d4016ca8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Oma-User,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Organization-Container	
+# An organization container. Used for extended rights and roles.
+#
+dn: CN=ms-Exch-Organization-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Organization-Container
+distinguishedName: CN=ms-Exch-Organization-Container,${SCHEMADN}
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50020
+mayContain: msExchMinAdminVersion
+mayContain: heuristics
+mayContain: msExchDisableUDGConversion
+mayContain: msExchServerLocalGroups
+mayContain: msExchServerGroups
+mayContain: msExchServerGlobalGroups
+mayContain: msExchAdmins
+mayContain: msExchAdminGroupsEnabled
+mayContain: msExchWebAccessName
+mayContain: submissionContLength
+mayContain: msExchMixedMode
+mayContain: msExchMimeTypes
+mayContain: delivContLength
+mayContain: msExchRoutingEnabled
+mayContain: msExchRecipLimit
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Organization-Container
+adminDescription: ms-Exch-Organization-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchOrganizationContainer
+name: ms-Exch-Organization-Container
+schemaIDGUID: 366a319c-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Organization-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-OVVM-Connector	
+# The OVVM Connector.
+#
+dn: CN=ms-Exch-OVVM-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-OVVM-Connector
+distinguishedName: CN=ms-Exch-OVVM-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1004
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OVVM-Connector
+adminDescription: ms-Exch-OVVM-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchOVVMConnector
+name: ms-Exch-OVVM-Connector
+schemaIDGUID: 91ce0e8c-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-OVVM-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-PF-Tree	
+#
+dn: CN=ms-Exch-PF-Tree,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-PF-Tree
+distinguishedName: CN=ms-Exch-PF-Tree,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.11003
+mayContain: msExchMinAdminVersion
+mayContain: msExchPfCreation
+mayContain: msExchAllowEnhancedSecurity
+mayContain: msExchOwningPFTreeBL
+mayContain: msExchPFDefaultAdminACL
+mayContain: msExchPFTreeType
+mayContain: msExchPFDSContainer
+mayContain: displayName
+mayContain: description
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PF-Tree
+adminDescription: ms-Exch-PF-Tree
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPFTree
+name: ms-Exch-PF-Tree
+schemaIDGUID: 364d9564-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-PF-Tree,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policies-Container 
+# A container used to hold policies. Used for extended rights and
+# roles.
+#
+dn: CN=ms-Exch-Policies-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Policies-Container
+distinguishedName: CN=ms-Exch-Policies-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50014
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policies-Container
+adminDescription: ms-Exch-Policies-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPoliciesContainer
+name: ms-Exch-Policies-Container
+schemaIDGUID: 3630f92c-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Policies-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Private-MDB	   
+# A private database configuration.
+#
+dn: CN=ms-Exch-Private-MDB,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Private-MDB
+distinguishedName: CN=ms-Exch-Private-MDB,${SCHEMADN}
+possSuperiors: container
+possSuperiors: computer
+subClassOf: msExchMDB
+governsID: 1.2.840.113556.1.5.7000.62.11004
+mayContain: msExchRestore
+mayContain: msExchOrigMDB
+mayContain: msExchMessageJournalRecipient
+mayContain: msExchUseOAB
+mayContain: msExchMailboxRetentionPeriod
+mayContain: msExchMaximumRecurringInstancesMonths
+mayContain: msExchMaximumRecurringInstances
+mayContain: msExchHomePublicMDB
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Private-MDB
+adminDescription: ms-Exch-Private-MDB
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPrivateMDB
+name: ms-Exch-Private-MDB
+schemaIDGUID: 36145cf4-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Private-MDB,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Private-MDB-Policy	
+#
+dn: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Private-MDB-Policy
+distinguishedName: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: msExchPrivateMDB
+governsID: 1.2.840.113556.1.5.7000.62.50003
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Private-MDB-Policy
+adminDescription: ms-Exch-Private-MDB-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPrivateMDBPolicy
+name: ms-Exch-Private-MDB-Policy
+schemaIDGUID: 35db2484-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Private-MDB-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Private-MDB-Proxy
+#
+dn: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Private-MDB-Proxy
+distinguishedName: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN}
+possSuperiors: msExchContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.11007
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Private-MDB-Proxy
+adminDescription: ms-Exch-Private-MDB-Proxy
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: msExchPrivateMDBProxy
+name: ms-Exch-Private-MDB-Proxy
+schemaIDGUID: b8d47e54-4b78-11d3-aa75-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Private-MDB-Proxy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg		
+#
+dn: CN=ms-Exch-Protocol-Cfg,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg
+distinguishedName: CN=ms-Exch-Protocol-Cfg,${SCHEMADN}
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.68
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: msExchDS2MBOptions
+mayContain: heuristics
+mayContain: useSiteValues
+mayContain: sendTNEF
+mayContain: requireSSL
+mayContain: preserveInternetContent
+mayContain: portNumber
+mayContain: incomingMsgSizeLimit
+mayContain: enabledProtocolCfg
+mayContain: enabledAuthorizationPackages
+mayContain: diagnosticRegKey
+mayContain: contentType
+mayContain: clientAccessEnabled
+mayContain: characterSet
+mayContain: associationLifetime
+mayContain: anonymousAccess
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg
+adminDescription: ms-Exch-Protocol-Cfg
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfg
+name: ms-Exch-Protocol-Cfg
+schemaIDGUID: a8df74c0-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.3.79
+mustContain: hTTPPubGAL
+mayContain: hTTPServers
+mayContain: hTTPPubPF
+mayContain: hTTPPubGALLimit
+mayContain: hTTPPubABAttributes
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP
+adminDescription: ms-Exch-Protocol-Cfg-HTTP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgHTTP
+name: ms-Exch-Protocol-Cfg-HTTP
+schemaIDGUID: a8df74c1-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Container  
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN}
+subClassOf: msExchProtocolCfgSharedContainer
+governsID: 1.2.840.113556.1.5.7000.62.14001
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Container
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgHTTPContainer
+name: ms-Exch-Protocol-Cfg-HTTP-Container
+schemaIDGUID: 9432cae6-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Filter	   
+# The Exchange HTTP service filters.
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Filter
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN}
+possSuperiors: msExchProtocolCfgHTTPFilters
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.15003
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Filter
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Filter
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgHTTPFilter
+name: ms-Exch-Protocol-Cfg-HTTP-Filter
+schemaIDGUID: 8c7588c0-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Filter,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Filters	
+# The Exchange HTTP service filters container.
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Filters
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN}
+possSuperiors: protocolCfgSharedServer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.15002
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Filters
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Filters
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgHTTPFilters
+name: ms-Exch-Protocol-Cfg-HTTP-Filters
+schemaIDGUID: 8c58ec88-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Filters,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Server	
+# The Exchange HTTP virtual server configuration.
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgHTTPContainer
+subClassOf: protocolCfgHTTP
+governsID: 1.2.840.113556.1.3.80
+mayContain: msExchEncryptedAnonymousPassword
+mayContain: msExchDefaultLoadFile
+mayContain: msExchAuthorizationPersistence
+mayContain: msExchServerAutoStart
+mayContain: msExchServerRole
+mayContain: msExchDiscussionFolder
+mayContain: msExchDefaultDomain
+mayContain: msExchUNCUsername
+mayContain: msExchUNCPassword
+mayContain: msExchServerBindings
+mayContain: msExchSecureBindings
+mayContain: msExchMaxIncomingConnections
+mayContain: msExchLogonMethod
+mayContain: msExchLogType
+mayContain: msExchIncomingConnectionTimeout
+mayContain: folderPathname
+mayContain: msExchDirBrowseFlags
+mayContain: msExchDefaultLogonDomain
+mayContain: msExchBasicAuthenticationDomain
+mayContain: msExchAuthenticationFlags
+mayContain: anonymousAccount
+mayContain: msExchAccessFlags
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Server
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgHTTPServer
+name: ms-Exch-Protocol-Cfg-HTTP-Server
+schemaIDGUID: a8df74c2-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Site	
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+subClassOf: protocolCfgHTTP
+governsID: 1.2.840.113556.1.3.81
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Site
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgHTTPSite
+name: ms-Exch-Protocol-Cfg-HTTP-Site
+schemaIDGUID: a8df74c3-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory	
+# The Exchange HTTP virtual directory configuration.
+#
+dn: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory
+distinguishedName: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN}
+possSuperiors: protocolCfgHTTPServer
+subClassOf: protocolCfgHTTPServer
+governsID: 1.2.840.113556.1.5.7000.62.15001
+mayContain: msExchBackEndVDirURL
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory
+adminDescription: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgHTTPVirtualDirectory
+name: ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory
+schemaIDGUID: 8c3c5050-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-HTTP-Virtual-Directory,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IM	    
+#
+dn: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IM
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.5.7000.62.7012
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IM
+adminDescription: ms-Exch-Protocol-Cfg-IM
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIM
+name: ms-Exch-Protocol-Cfg-IM
+schemaIDGUID: 9f116ea7-284e-11d3-aa68-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP	      
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.3.84
+mayContain: msExchLogonACL
+mayContain: msExchServerBindings
+mayContain: msExchSecureBindings
+mayContain: returnExactMsgSize
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyList
+mayContain: oWAServer
+mayContain: listPublicFolders
+mayContain: formData
+mayContain: folderPathname
+mayContain: delegateUser
+mayContain: anonymousAccount
+mayContain: helpData32
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP
+adminDescription: ms-Exch-Protocol-Cfg-IMAP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgIMAP
+name: ms-Exch-Protocol-Cfg-IMAP
+schemaIDGUID: a8df74c4-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP-Container  
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN}
+subClassOf: msExchProtocolCfgSharedContainer
+governsID: 1.2.840.113556.1.5.7000.62.3001
+mayContain: msExchSASLMechanisms
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Container
+adminDescription: ms-Exch-Protocol-Cfg-IMAP-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIMAPContainer
+name: ms-Exch-Protocol-Cfg-IMAP-Container
+schemaIDGUID: 93da93e4-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP-Policy	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP-Policy
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: protocolCfgIMAP
+governsID: 1.2.840.113556.1.5.7000.62.50004
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Policy
+adminDescription: ms-Exch-Protocol-Cfg-IMAP-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIMAPPolicy
+name: ms-Exch-Protocol-Cfg-IMAP-Policy
+schemaIDGUID: 35f7c0bc-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP-Server	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgIMAPContainer
+subClassOf: protocolCfgIMAP
+governsID: 1.2.840.113556.1.3.85
+mayContain: msExchOtherAuthenticationFlags
+mayContain: msExchServerRole
+mayContain: msExchDefaultLogonDomain
+mayContain: msExchServerBindings
+mayContain: msExchServerAutoStart
+mayContain: msExchSecureBindings
+mayContain: msExchNTAuthenticationProviders
+mayContain: msExchMaxIncomingConnections
+mayContain: msExchLogType
+mayContain: msExchIPSecurity
+mayContain: msExchIncomingConnectionTimeout
+mayContain: msExchDefaultDomain
+mayContain: msExchBasicAuthenticationDomain
+mayContain: msExchAuthenticationFlags
+mayContain: msExchAdminACL
+mayContain: msExchAccessSSLFlags
+mayContain: msExchAccessFlags
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Server
+adminDescription: ms-Exch-Protocol-Cfg-IMAP-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgIMAPServer
+name: ms-Exch-Protocol-Cfg-IMAP-Server
+schemaIDGUID: a8df74c5-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP-Sessions   
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP-Sessions
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN}
+possSuperiors: protocolCfgIMAPServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.3002
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Sessions
+adminDescription: ms-Exch-Protocol-Cfg-IMAP-Sessions
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIMAPSessions
+name: ms-Exch-Protocol-Cfg-IMAP-Sessions
+schemaIDGUID: 99f58672-12e8-11d3-aa58-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Sessions,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IMAP-Site  
+#
+dn: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IMAP-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+subClassOf: protocolCfgIMAP
+governsID: 1.2.840.113556.1.3.86
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IMAP-Site
+adminDescription: ms-Exch-Protocol-Cfg-IMAP-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgIMAPSite
+name: ms-Exch-Protocol-Cfg-IMAP-Site
+schemaIDGUID: a8df74c6-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IMAP-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IM-Container	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IM-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN}
+subClassOf: msExchProtocolCfgSharedContainer
+governsID: 1.2.840.113556.1.5.7000.62.7011
+mayContain: msExchIMDBPath
+mayContain: msExchIMDBLogPath
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IM-Container
+adminDescription: ms-Exch-Protocol-Cfg-IM-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIMContainer
+name: ms-Exch-Protocol-Cfg-IM-Container
+schemaIDGUID: 9f116ea3-284e-11d3-aa68-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-IM-Virtual-Server	
+# Contains the attributes that represent an Instant Messaging virtual
+# server.
+#
+dn: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-IM-Virtual-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgIMContainer
+subClassOf: msExchProtocolCfgIM
+governsID: 1.2.840.113556.1.5.7000.62.7013
+mustContain: msExchIMServerIISId
+mayContain: msExchIMHostName
+mayContain: flags
+mayContain: msExchIMServerName
+mayContain: msExchIMServerHostsUsers
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-IM-Virtual-Server
+adminDescription: ms-Exch-Protocol-Cfg-IM-Virtual-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgIMVirtualServer
+name: ms-Exch-Protocol-Cfg-IM-Virtual-Server
+schemaIDGUID: 9f116eb4-284e-11d3-aa68-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-IM-Virtual-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-LDAP	       
+#
+dn: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-LDAP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.3.75
+mayContain: outgoingMsgSizeLimit
+mayContain: lDAPSearchCfg
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-LDAP
+adminDescription: ms-Exch-Protocol-Cfg-LDAP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgLDAP
+name: ms-Exch-Protocol-Cfg-LDAP
+schemaIDGUID: a8df74c7-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-LDAP-Server	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-LDAP-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgProtocolContainer
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfgLDAP
+governsID: 1.2.840.113556.1.3.77
+mayContain: referralList
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-LDAP-Server
+adminDescription: ms-Exch-Protocol-Cfg-LDAP-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgLDAPServer
+name: ms-Exch-Protocol-Cfg-LDAP-Server
+schemaIDGUID: a8df74c8-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-LDAP-Site  
+#
+dn: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-LDAP-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+subClassOf: protocolCfgLDAP
+governsID: 1.2.840.113556.1.3.76
+mayContain: referralList
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-LDAP-Site
+adminDescription: ms-Exch-Protocol-Cfg-LDAP-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgLDAPSite
+name: ms-Exch-Protocol-Cfg-LDAP-Site
+schemaIDGUID: a8df74c9-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-LDAP-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-NNTP	      
+#
+dn: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-NNTP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.3.72
+mayContain: usenetSiteName
+mayContain: supportSMIMESignatures
+mayContain: rootNewsgroupsFolderID
+mayContain: iNSAdmin
+mayContain: controlMsgRules
+mayContain: controlMsgFolderID
+mayContain: availableDistributions
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-NNTP
+adminDescription: ms-Exch-Protocol-Cfg-NNTP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgNNTP
+name: ms-Exch-Protocol-Cfg-NNTP
+schemaIDGUID: a8df74ca-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-NNTP-Container  
+#
+dn: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-NNTP-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN}
+subClassOf: msExchProtocolCfgSharedContainer
+governsID: 1.2.840.113556.1.5.7000.62.6001
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Container
+adminDescription: ms-Exch-Protocol-Cfg-NNTP-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgNNTPContainer
+name: ms-Exch-Protocol-Cfg-NNTP-Container
+schemaIDGUID: 94162eae-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-NNTP-Server	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-NNTP-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgNNTPContainer
+subClassOf: protocolCfgNNTP
+governsID: 1.2.840.113556.1.3.74
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Server
+adminDescription: ms-Exch-Protocol-Cfg-NNTP-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgNNTPServer
+name: ms-Exch-Protocol-Cfg-NNTP-Server
+schemaIDGUID: a8df74cb-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-NNTP-Site  
+#
+dn: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-NNTP-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+subClassOf: protocolCfgNNTP
+governsID: 1.2.840.113556.1.3.73
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-NNTP-Site
+adminDescription: ms-Exch-Protocol-Cfg-NNTP-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgNNTPSite
+name: ms-Exch-Protocol-Cfg-NNTP-Site
+schemaIDGUID: a8df74cc-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-NNTP-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-POP 
+#
+dn: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-POP
+distinguishedName: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+possSuperiors: protocolCfgSharedServer
+subClassOf: protocolCfg
+governsID: 1.2.840.113556.1.3.69
+mayContain: msExchLogonACL
+mayContain: msExchServerBindings
+mayContain: msExchSecureBindings
+mayContain: oWAServer
+mayContain: formData
+mayContain: folderPathname
+mayContain: helpData32
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-POP
+adminDescription: ms-Exch-Protocol-Cfg-POP
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgPOP
+name: ms-Exch-Protocol-Cfg-POP
+schemaIDGUID: a8df74cd-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-POP,${SCHEMADN}
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Container	
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN}
+subClassOf: msExchProtocolCfgSharedContainer
+governsID: 1.2.840.113556.1.5.7000.62.5010
+mayContain: versionNumber
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Container
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgSMTPContainer
+name: ms-Exch-Protocol-Cfg-SMTP-Container
+schemaIDGUID: 93bb9552-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Domain	   
+# Contains domain level settings under an SMTP virtual server.
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Domain
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN}
+possSuperiors: protocolCfgSMTPDomainContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5006
+mayContain: msExchEncryptedPassword
+mayContain: msExchSecurityPassword
+mayContain: msExchSmtpSmartHost
+mayContain: msExchSmtpOutboundSecurityUserName
+mayContain: msExchSmtpOutboundSecurityPassword
+mayContain: msExchSmtpOutboundSecurityFlag
+mayContain: msExchSmtpDropDirectory
+mayContain: msExchSmtpDomainString
+mayContain: msExchSmtpAuthorizedTRNAccounts
+mayContain: sendTNEF
+mayContain: msExchRoutingDisplaySenderEnabled
+mayContain: msExchRoutingAcceptMessageType
+mayContain: msExchDefaultDomain
+mayContain: contentType
+mayContain: characterSet
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Domain
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Domain
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPDomain
+name: ms-Exch-Protocol-Cfg-SMTP-Domain
+schemaIDGUID: 33d82894-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Domain,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Domain-Container     
+# Contains superior domain level settings under an SMTP virtual
+# server.
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Domain-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN}
+possSuperiors: protocolCfgSMTPServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5004
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Domain-Container
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Domain-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPDomainContainer
+name: ms-Exch-Protocol-Cfg-SMTP-Domain-Container
+schemaIDGUID: 33bb8c5c-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Domain-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-IP-Address    
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-IP-Address
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN}
+possSuperiors: msExchProtocolCfgSMTPIPAddressContainer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5009
+mayContain: msExchTurfList
+mayContain: msExchIPAddress
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-IP-Address
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-IP-Address
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgSMTPIPAddress
+name: ms-Exch-Protocol-Cfg-SMTP-IP-Address
+schemaIDGUID: 8b7b31d6-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container	
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN}
+possSuperiors: protocolCfgSMTPServer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.5008
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgSMTPIPAddressContainer
+name: ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container
+schemaIDGUID: 8b2c843c-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-IP-Address-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Policy	   
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Policy
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: protocolCfgSMTP
+governsID: 1.2.840.113556.1.5.7000.62.50006
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Policy
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchProtocolCfgSMTPPolicy
+name: ms-Exch-Protocol-Cfg-SMTP-Policy
+schemaIDGUID: 359f89ba-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Routing-Sources	
+# Contains information about the unused sources for routing outbound
+# mail.
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN}
+possSuperiors: protocolCfgSMTPServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5005
+mayContain: msExchMinAdminVersion
+mayContain: msExchSmtpRoutingTableType
+mayContain: msExchSmtpLdapSchemaType
+mayContain: msExchSmtpLdapPassword
+mayContain: msExchSmtpLdapNamingContext
+mayContain: msExchSmtpLdapBindType
+mayContain: msExchSmtpLdapAccount
+mayContain: msExchSmtpEnableLdapRouting
+mayContain: msExchSmtpDsPort
+mayContain: msExchSmtpDsHost
+mayContain: msExchSmtpDsFlags
+mayContain: msExchSmtpDsDomain
+mayContain: msExchSmtpDsDefaultMailRoot
+mayContain: msExchSmtpDsDataDirectory
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPRoutingSources
+name: ms-Exch-Protocol-Cfg-SMTP-Routing-Sources
+schemaIDGUID: 3397c916-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Routing-Sources,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Server	      
+# Contains the settings for an SMTP virtual server.
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Server
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN}
+possSuperiors: msExchProtocolCfgSMTPContainer
+subClassOf: protocolCfgSMTP
+governsID: 1.2.840.113556.1.5.7000.62.5002
+mayContain: msExchSubmitRelaySD
+mayContain: msExchServerBindingsFiltering
+mayContain: msExchAuthMailDisposition
+mayContain: msExchSmtpExternalDNSServers
+mayContain: msExchEncryptedPassword
+mayContain: msExchAppliesToSmtpVSBL
+mayContain: msExchSmtpEnableVRFY
+mayContain: msExchSmtpEnableEXPN
+mayContain: msExchServerBindingsTurflist
+mayContain: msExchSecurityPassword
+mayContain: msExchAlternateServer
+mayContain: msExchSmtpSmartHostType
+mayContain: msExchSmtpSmartHost
+mayContain: msExchSmtpSendNDRTo
+mayContain: msExchSmtpSendBadmailTo
+mayContain: msExchSmtpRemoteQueueRetries
+mayContain: msExchSmtpRemoteQueueExpirationTimeout
+mayContain: msExchSmtpRemoteQueueDelayNotification
+mayContain: msExchSmtpRelayIpList
+mayContain: msExchSmtpRelayForAuth
+mayContain: msExchSmtpQueueDirectory
+mayContain: msExchSmtpPickupDirectory
+mayContain: msExchSmtpPerformReverseDnsLookup
+mayContain: msExchSmtpOutgoingSecurePort
+mayContain: msExchSmtpOutgoingPort
+mayContain: msExchSmtpOutgoingConnectionTimeout
+mayContain: msExchSmtpOutboundSecurityUserName
+mayContain: msExchSmtpOutboundSecurityPassword
+mayContain: msExchSmtpOutboundSecurityFlag
+mayContain: msExchSmtpMaxSessionSize
+mayContain: msExchSmtpMaxRecipients
+mayContain: msExchSmtpMaxOutgoingConnectionsPerDomain
+mayContain: msExchSmtpMaxOutgoingConnections
+mayContain: msExchSmtpMaxOutboundMsgPerDomainFlag
+mayContain: msExchSmtpMaxOutboundMsgPerDomain
+mayContain: msExchSmtpMaxMessageSize
+mayContain: msExchSmtpMaxHopCount
+mayContain: msExchSmtpMasqueradeDomain
+mayContain: msExchSmtpLocalQueueExpirationTimeout
+mayContain: msExchSmtpLocalQueueDelayNotification
+mayContain: msExchSmtpInboundCommandSupportOptions
+mayContain: msExchSmtpFullyQualifiedDomainName
+mayContain: msExchSmtpDropDirectory
+mayContain: msExchSmtpDoMasquerade
+mayContain: msExchSmtpBadMailDirectory
+mayContain: msExchServerBindings
+mayContain: msExchServerAutoStart
+mayContain: msExchSecureBindings
+mayContain: msExchSaslLogonDomain
+mayContain: msExchNTAuthenticationProviders
+mayContain: msExchMaxIncomingConnections
+mayContain: msExchLogType
+mayContain: msExchIPSecurity
+mayContain: msExchIncomingConnectionTimeout
+mayContain: msExchHomeRoutingGroupDNBL
+mayContain: msExchDefaultDomain
+mayContain: msExchBridgeheadedRemoteConnectorsDNBL
+mayContain: msExchBridgeheadedLocalConnectorsDNBL
+mayContain: msExchAuthenticationFlags
+mayContain: msExchAdminACL
+mayContain: msExchAccessSSLFlags
+mayContain: msExchAccessFlags
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Server
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Server
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPServer
+name: ms-Exch-Protocol-Cfg-SMTP-Server
+schemaIDGUID: 3378ca84-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Server,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Sessions  
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Sessions
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN}
+possSuperiors: protocolCfgSMTPServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.5007
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Sessions
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Sessions
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPSessions
+name: ms-Exch-Protocol-Cfg-SMTP-Sessions
+schemaIDGUID: 8ef628c6-b093-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Sessions,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Cfg-SMTP-Site  
+# Contains settings for legacy site SMTP settings.
+#
+dn: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Protocol-Cfg-SMTP-Site
+distinguishedName: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN}
+possSuperiors: protocolCfgSharedSite
+subClassOf: protocolCfgSMTP
+governsID: 1.2.840.113556.1.5.7000.62.5003
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Cfg-SMTP-Site
+adminDescription: ms-Exch-Protocol-Cfg-SMTP-Site
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: protocolCfgSMTPSite
+name: ms-Exch-Protocol-Cfg-SMTP-Site
+schemaIDGUID: 32f0e47a-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Protocol-Cfg-SMTP-Site,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Pseudo-PF	     
+# Used internally by the store.
+#
+dn: CN=ms-Exch-Pseudo-PF,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Pseudo-PF
+distinguishedName: CN=ms-Exch-Pseudo-PF,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50030
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Pseudo-PF
+adminDescription: ms-Exch-Pseudo-PF
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPseudoPF
+name: ms-Exch-Pseudo-PF
+schemaIDGUID: cec4472b-22ae-11d3-aa62-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Pseudo-PF,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Pseudo-PF-Admin	
+# Used internally by the store.
+#
+dn: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Pseudo-PF-Admin
+distinguishedName: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN}
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50029
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Pseudo-PF-Admin
+adminDescription: ms-Exch-Pseudo-PF-Admin
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPseudoPFAdmin
+name: ms-Exch-Pseudo-PF-Admin
+schemaIDGUID: 9ae2fa1b-22b0-11d3-aa62-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Pseudo-PF-Admin,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-Folder	
+# A representation of a public folder.
+#
+dn: CN=ms-Exch-Public-Folder,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Public-Folder
+distinguishedName: CN=ms-Exch-Public-Folder,${SCHEMADN}
+possSuperiors: msExchSystemObjectsContainer
+possSuperiors: organizationalUnit
+possSuperiors: domainDNS
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.15
+mayContain: pFContacts
+mayContain: msExchPFTreeType
+mayContain: title
+mayContain: co
+mayContain: st
+mayContain: physicalDeliveryOfficeName
+mayContain: l
+mayContain: department
+mayContain: company
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-Folder
+adminDescription: ms-Exch-Public-Folder
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: msExchCustomAttributes
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: publicFolder
+name: ms-Exch-Public-Folder
+schemaIDGUID: f0f8ffac-1191-11d0-a060-00aa006c33ed
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(OA;;RP;59ba2f42-79a2-11d0-9020-00c04fc2d3cf;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Public-Folder,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-Folder-Tree-Container	
+# A container used to hold public folders. Used for extended rights and
+# roles.
+#
+dn: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Public-Folder-Tree-Container
+distinguishedName: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50015
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-Folder-Tree-Container
+adminDescription: ms-Exch-Public-Folder-Tree-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPublicFolderTreeContainer
+name: ms-Exch-Public-Folder-Tree-Container
+schemaIDGUID: 3582ed82-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Public-Folder-Tree-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-MDB 
+# A public database configuration.
+#
+dn: CN=ms-Exch-Public-MDB,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Public-MDB
+distinguishedName: CN=ms-Exch-Public-MDB,${SCHEMADN}
+possSuperiors: container
+possSuperiors: computer
+subClassOf: msExchMDB
+governsID: 1.2.840.113556.1.5.7000.62.11005
+mayContain: msExchPreferredBackfillSource
+mayContain: messageSizeLimit
+mayContain: msExchOverallAgeLimit
+mayContain: msExchReplicationStyle
+mayContain: msExchReplicationSchedule
+mayContain: msExchReplicationMsgSize
+mayContain: msExchPollInterval
+mayContain: msExchOwningPFTree
+mayContain: msExchFirstInstance
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-MDB
+adminDescription: ms-Exch-Public-MDB
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: msExchPublicMDB
+name: ms-Exch-Public-MDB
+schemaIDGUID: 3568b3a4-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Public-MDB,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-MDB-Policy	
+#
+dn: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Public-MDB-Policy
+distinguishedName: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN}
+possSuperiors: container
+subClassOf: msExchPublicMDB
+governsID: 1.2.840.113556.1.5.7000.62.50002
+mayContain: msExchPolicyLastAppliedTime
+mayContain: msExchPolicyOptionList
+mayContain: msExchPolicyLockDown
+mayContain: msExchPolicyListBL
+mayContain: msExchPolicyDefault
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-MDB-Policy
+adminDescription: ms-Exch-Public-MDB-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchPublicMDBPolicy
+name: ms-Exch-Public-MDB-Policy
+schemaIDGUID: 354c176c-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Public-MDB-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RAS-Stack	   
+# The Remote Access Service (RAS) Transport Stack for the MTA.
+#
+dn: CN=ms-Exch-RAS-Stack,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-RAS-Stack
+distinguishedName: CN=ms-Exch-RAS-Stack,${SCHEMADN}
+possSuperiors: mTA
+possSuperiors: container
+possSuperiors: computer
+subClassOf: transportStack
+governsID: 1.2.840.113556.1.3.26
+mayContain: rASCallbackNumber
+mayContain: encrypt
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-Stack
+adminDescription: ms-Exch-RAS-Stack
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: rASStack
+name: ms-Exch-RAS-Stack
+schemaIDGUID: a8df74d3-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-RAS-Stack,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-RAS-X400-Link	
+# Specifies a remote X.400 MTA using a RAS Transport.
+#
+dn: CN=ms-Exch-RAS-X400-Link,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-RAS-X400-Link
+distinguishedName: CN=ms-Exch-RAS-X400-Link,${SCHEMADN}
+possSuperiors: container
+subClassOf: x400Link
+governsID: 1.2.840.113556.1.3.34
+mayContain: rASRemoteSRVRName
+mayContain: rASPhonebookEntryName
+mayContain: rASPhoneNumber
+mayContain: rASCallbackNumber
+mayContain: authorizedUser
+mayContain: authorizedPassword
+mayContain: authorizedDomain
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-X400-Link
+adminDescription: ms-Exch-RAS-X400-Link
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: rASX400Link
+name: ms-Exch-RAS-X400-Link
+schemaIDGUID: a8df74d4-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-RAS-X400-Link,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Recipient-Policy
+#
+dn: CN=ms-Exch-Recipient-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Recipient-Policy
+distinguishedName: CN=ms-Exch-Recipient-Policy,${SCHEMADN}
+possSuperiors: msExchRecipientPolicyContainer
+subClassOf: msExchGenericPolicy
+governsID: 1.2.840.113556.1.5.7000.62.50024
+mayContain: msExchMinAdminVersion
+mayContain: msExchAddressListOU
+mayContain: msExchNonAuthoritativeDomains
+mayContain: msExchAppliesToSmtpVS
+mayContain: msExchProxyGenOptions
+mayContain: msExchPolicyOrder
+mayContain: gatewayProxy
+mayContain: disabledGatewayProxy
+mayContain: msExchAssociatedAG
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recipient-Policy
+adminDescription: ms-Exch-Recipient-Policy
+auxiliaryClass: msExchMailboxManagerPolicy
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: msExchCustomAttributes
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: msExchRecipientPolicy
+name: ms-Exch-Recipient-Policy
+schemaIDGUID: e32977d8-1d31-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Recipient-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Recipient-Policy-Container
+#
+dn: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Recipient-Policy-Container
+distinguishedName: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN}
+possSuperiors: msExchOrganizationContainer
+subClassOf: msExchGenericPolicyContainer
+governsID: 1.2.840.113556.1.5.7000.62.50023
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recipient-Policy-Container
+adminDescription: ms-Exch-Recipient-Policy-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchRecipientPolicyContainer
+name: ms-Exch-Recipient-Policy-Container
+schemaIDGUID: e32977d2-1d31-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Recipient-Policy-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Remote-DXA	   
+# The remote directory Exchange objects (requester and server).
+#
+dn: CN=ms-Exch-Remote-DXA,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Remote-DXA
+distinguishedName: CN=ms-Exch-Remote-DXA,${SCHEMADN}
+possSuperiors: dXASiteServer
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.2
+mustContain: exportCustomRecipients
+mustContain: dXARemoteClient
+mustContain: cn
+mayContain: versionNumber
+mayContain: msExchServer1AlwaysCreateAs
+mayContain: msExchPrevExportDLs
+mayContain: msExchImportContainerLinked
+mayContain: msExchExportDLs
+mayContain: msExchExportContainersLinked
+mayContain: assocRemoteDXA
+mayContain: deletedItemFlags
+mayContain: responsibleLocalDXA
+mayContain: reqSeq
+mayContain: replicationSensitivity
+mayContain: messageSizeLimit
+mayContain: importContainer
+mayContain: exportContainers
+mayContain: dXAUnConfContainerList
+mayContain: dXATypes
+mayContain: dXATemplateOptions
+mayContain: dXASvrSeqUSN
+mayContain: dXASvrSeqTime
+mayContain: dXASvrSeq
+mayContain: dXAReqName
+mayContain: dXAReqSeqUSN
+mayContain: dXAReqSeqTime
+mayContain: dXAReqSeq
+mayContain: dXARecipientCP
+mayContain: dXAPrevTypes
+mayContain: dXAPrevTemplateOptions
+mayContain: dXAPrevReplicationSensitivity
+mayContain: dXAPrevRemoteEntries
+mayContain: dXAPrevInExchangeSensitivity
+mayContain: dXAPrevExportNativeOnly
+mayContain: dXAPrevExchangeOptions
+mayContain: dXAPassword
+mayContain: dXANativeAddressType
+mayContain: dXALocalAdmin
+mayContain: dXAImportNow
+mayContain: dXAImpSeqUSN
+mayContain: dXAImpSeqTime
+mayContain: dXAImpSeq
+mayContain: dXAExportNow
+mayContain: dXAExchangeOptions
+mayContain: dXAConfSeqUSN
+mayContain: dXAConfSeq
+mayContain: dXAConfReqTime
+mayContain: dXAConfContainerList
+mayContain: dXAAppendReqCN
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-DXA
+adminDescription: ms-Exch-Remote-DXA
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: remoteDXA
+name: ms-Exch-Remote-DXA
+schemaIDGUID: a8df74d5-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Remote-DXA,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replication-Connector   
+#
+dn: CN=ms-Exch-Replication-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Replication-Connector
+distinguishedName: CN=ms-Exch-Replication-Connector,${SCHEMADN}
+possSuperiors: msExchReplicationConnectorContainer
+subClassOf: msExchConnector
+governsID: 1.2.840.113556.1.5.7000.62.11
+mayContain: trustLevel
+mayContain: replicationStagger
+mayContain: replicationMailMsgSize
+mayContain: remoteSite
+mayContain: remoteBridgeHeadAddress
+mayContain: remoteBridgeHead
+mayContain: outboundSites
+mayContain: localBridgeHeadAddress
+mayContain: localBridgeHead
+mayContain: kCCStatus
+mayContain: inboundSites
+mayContain: activationStyle
+mayContain: activationSchedule
+mayContain: addressType
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Connector
+adminDescription: ms-Exch-Replication-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchReplicationConnector
+name: ms-Exch-Replication-Connector
+schemaIDGUID: 99f58682-12e8-11d3-aa58-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Replication-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replication-Connector-Container	
+#
+dn: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Replication-Connector-Container
+distinguishedName: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.12
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Connector-Container
+adminDescription: ms-Exch-Replication-Connector-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchReplicationConnectorContainer
+name: ms-Exch-Replication-Connector-Container
+schemaIDGUID: 99f5867e-12e8-11d3-aa58-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Replication-Connector-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RFC1006-Stack    
+# The RFC 1006 (TCP/IP) Transport Stack for the MTA.
+#
+dn: CN=ms-Exch-RFC1006-Stack,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-RFC1006-Stack
+distinguishedName: CN=ms-Exch-RFC1006-Stack,${SCHEMADN}
+possSuperiors: mTA
+subClassOf: transportStack
+governsID: 1.2.840.113556.1.3.24
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RFC1006-Stack
+adminDescription: ms-Exch-RFC1006-Stack
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: rFC1006Stack
+name: ms-Exch-RFC1006-Stack
+schemaIDGUID: a8df74d7-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-RFC1006-Stack,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RFC1006-X400-Link	
+# Specifies a remote X.400 MTA using an RFC 1006 (TCP/IP) Transport.
+#
+dn: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-RFC1006-X400-Link
+distinguishedName: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN}
+subClassOf: x400Link
+governsID: 1.2.840.113556.1.3.32
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RFC1006-X400-Link
+adminDescription: ms-Exch-RFC1006-X400-Link
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: rFC1006X400Link
+name: ms-Exch-RFC1006-X400-Link
+schemaIDGUID: a8df74d8-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-RFC1006-X400-Link,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Routing-Group  
+# Container used to hold routing group information.
+#
+dn: CN=ms-Exch-Routing-Group,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Routing-Group
+distinguishedName: CN=ms-Exch-Routing-Group,${SCHEMADN}
+possSuperiors: msExchRoutingGroupContainer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.12002
+mayContain: msExchMinAdminVersion
+mayContain: msExchRoutingGroupMembersBL
+mayContain: msExchInconsistentState
+mayContain: msExchRoutingMasterDN
+mayContain: msExchRoutingGroupMembersDN
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Group
+adminDescription: ms-Exch-Routing-Group
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchRoutingGroup
+name: ms-Exch-Routing-Group
+schemaIDGUID: 35154156-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Routing-Group,${SCHEMADN}
+
+#
+# ms-Exch-Routing-Group-Connector
+#
+dn: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Routing-Group-Connector
+distinguishedName: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN}
+possSuperiors: msExchConnectors
+subClassOf: msExchConnector
+governsID: 1.2.840.113556.1.5.7000.62.12007
+mayContain: msExchEncryptedPassword
+mayContain: targetMTAs
+mayContain: homeMTA
+mayContain: domainName
+mayContain: authorizedUser
+mayContain: authorizedPassword
+mayContain: authorizedDomain
+mayContain: cost
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Group-Connector
+adminDescription: ms-Exch-Routing-Group-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchRoutingGroupConnector
+name: ms-Exch-Routing-Group-Connector
+schemaIDGUID: 899e5b86-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Routing-Group-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Group-Container
+# Container used to hold routing groups.
+#
+dn: CN=ms-Exch-Routing-Group-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Routing-Group-Container
+distinguishedName: CN=ms-Exch-Routing-Group-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.12001
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Group-Container
+adminDescription: ms-Exch-Routing-Group-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchRoutingGroupContainer
+name: ms-Exch-Routing-Group-Container
+schemaIDGUID: 34de6b40-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Routing-Group-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-SMTP-Connector
+#
+dn: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Routing-SMTP-Connector
+distinguishedName: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN}
+possSuperiors: msExchConnectors
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.12008
+mayContain: msExchSmtpTRNSmartHost
+mayContain: msExchSecurityPassword
+mayContain: msExchRoutingETRNDomains
+mayContain: msExchSmtpSmartHost
+mayContain: msExchSmtpOutboundSecurityUserName
+mayContain: msExchSmtpOutboundSecurityPassword
+mayContain: msExchSmtpOutboundSecurityFlag
+mayContain: msExchSmtpAuthorizedTRNAccounts
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-SMTP-Connector
+adminDescription: ms-Exch-Routing-SMTP-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchRoutingSMTPConnector
+name: ms-Exch-Routing-SMTP-Connector
+schemaIDGUID: 89baf7be-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Routing-SMTP-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Schedule-Plus-Connector
+#
+dn: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Schedule-Plus-Connector
+distinguishedName: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: exchangeAdminService
+governsID: 1.2.840.113556.1.5.7000.62.1008
+mayContain: computerName
+mayContain: transferRetryInterval
+mayContain: msExchSchedPlusSchedist
+mayContain: msExchSchedPlusFullUpdate
+mayContain: msExchSchedPlusAGOnly
+mayContain: msExchAdminMailbox
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Schedule-Plus-Connector
+adminDescription: ms-Exch-Schedule-Plus-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSchedulePlusConnector
+name: ms-Exch-Schedule-Plus-Connector
+schemaIDGUID: b1fce946-1d44-11d3-aa5e-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Schedule-Plus-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Schema-Map-Policy	      
+# The policy object for connection agreements.
+#
+dn: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Schema-Map-Policy
+distinguishedName: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN}
+possSuperiors: organizationalUnit
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.1
+mayContain: msExchADCObjectType
+mayContain: versionNumber
+mayContain: msExchServer2SchemaMap
+mayContain: msExchServer2ObjectMatch
+mayContain: msExchServer2Flags
+mayContain: msExchServer1SchemaMap
+mayContain: msExchServer1ObjectMatch
+mayContain: msExchServer1Flags
+mayContain: msExchSchemaPolicyConsumers
+mayContain: msExchAccessControlMap
+mayContain: displayName
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Schema-Map-Policy
+adminDescription: ms-Exch-Schema-Map-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSchemaMapPolicy
+name: ms-Exch-Schema-Map-Policy
+schemaIDGUID: 348af8f2-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Schema-Map-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Servers-Container	 
+# A container used to hold servers. Used for extended rights and roles.
+#
+dn: CN=ms-Exch-Servers-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Servers-Container
+distinguishedName: CN=ms-Exch-Servers-Container,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50013
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Servers-Container
+adminDescription: ms-Exch-Servers-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchServersContainer
+name: ms-Exch-Servers-Container
+schemaIDGUID: 346e5cba-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;LC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Servers-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Site-Addressing	  
+# Represents the messaging domain.
+#
+dn: CN=ms-Exch-Site-Addressing,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Site-Addressing
+distinguishedName: CN=ms-Exch-Site-Addressing,${SCHEMADN}
+possSuperiors: msExchAdminGroup
+possSuperiors: container
+subClassOf: top
+governsID: 1.2.840.113556.1.3.0
+mustContain: cn
+mayContain: spaceLastComputed
+mayContain: siteProxySpace
+mayContain: routingList
+mayContain: ridServer
+mayContain: gWARTLastModified
+mayContain: gatewayRoutingTree
+mayContain: gatewayProxy
+mayContain: filterLocalAddresses
+mayContain: disabledGatewayProxy
+mayContain: activationStyle
+mayContain: activationSchedule
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Addressing
+adminDescription: ms-Exch-Site-Addressing
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: siteAddressing
+name: ms-Exch-Site-Addressing
+schemaIDGUID: a8df74d9-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Site-Addressing,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Site-Connector	
+# A symbolic link to another domain's message transfer agents (MTAs).
+#
+dn: CN=ms-Exch-Site-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Site-Connector
+distinguishedName: CN=ms-Exch-Site-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: msExchConnector
+governsID: 1.2.840.113556.1.3.50
+mustContain: cn
+mayContain: targetMTAs
+mayContain: msExchTargetBridgeheadServersDN
+mayContain: msExchSourceBridgeheadServersDN
+mayContain: msExchSourceBHAddress
+mayContain: routingList
+mayContain: homeMTA
+mayContain: domainName
+mayContain: msExchDestinationRGDN
+mayContain: msExchDestBHAddress
+mayContain: msExchConnectorType
+mayContain: bridgeheadServers
+mayContain: authorizedUser
+mayContain: authorizedPassword
+mayContain: authorizedDomain
+mayContain: cost
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Connector
+adminDescription: ms-Exch-Site-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: siteConnector
+name: ms-Exch-Site-Connector
+schemaIDGUID: a8df74da-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Site-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Site-Replication-Service	    
+#
+dn: CN=ms-Exch-Site-Replication-Service,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Site-Replication-Service
+distinguishedName: CN=ms-Exch-Site-Replication-Service,${SCHEMADN}
+possSuperiors: msExchExchangeServer
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.10
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Replication-Service
+adminDescription: ms-Exch-Site-Replication-Service
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: mailRecipient
+objectClassCategory: 1
+lDAPDisplayName: msExchSiteReplicationService
+name: ms-Exch-Site-Replication-Service
+schemaIDGUID: 99f5867b-12e8-11d3-aa58-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Site-Replication-Service,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List	   
+# Contains the attributes for Accept and Deny Internet Protocol (IP)
+# lists.
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Smtp-Connection-Turf-List
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN}
+possSuperiors: msExchSMTPTurfList
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.12010
+mayContain: msExchSMTPGlobalIPDenyList
+mayContain: msExchSMTPGlobalIPAcceptList
+mayContain: msExchMinAdminVersion
+mayContain: msExchSmtpConnectionWhitelist
+mayContain: msExchSmtpConnectionRulesPriority
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List
+adminDescription: ms-Exch-Smtp-Connection-Turf-List
+objectClassCategory: 1
+lDAPDisplayName: msExchSmtpConnectionTurfList
+name: ms-Exch-Smtp-Connection-Turf-List
+schemaIDGUID: 7eea7de9-319e-408a-8460-e35e2c9da389
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Smtp-Connection-Turf-List,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-Rule
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-Rule
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN}
+possSuperiors: msExchSmtpConnectionTurfList
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.12011
+mayContain: msExchSmtpConnectionTurfListResponse
+mayContain: msExchSmtpConnectionTurfListOptions
+mayContain: msExchSmtpConnectionTurfListMask
+mayContain: msExchSmtpConnectionTurfListDNS
+mayContain: msExchSmtpConnectionTurfListDisplay
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Rule
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-Rule
+objectClassCategory: 1
+lDAPDisplayName: msExchSmtpConnectionTurfListRule
+name: ms-Exch-Smtp-Connection-Turf-List-Rule
+schemaIDGUID: 6abadfad-e2f6-4ddb-9820-0da9c47da32c
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Smtp-Connection-Turf-List-Rule,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SMTP-Turf-List
+#
+dn: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-SMTP-Turf-List
+distinguishedName: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN}
+possSuperiors: msExchMessageDeliveryConfig
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.12009
+mayContain: msExchMinAdminVersion
+mayContain: msExchRecipTurfListOptions
+mayContain: msExchRecipTurfListNames
+mayContain: msExchTurfListOptions
+mayContain: versionNumber
+mayContain: msExchTurfListNames
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMTP-Turf-List
+adminDescription: ms-Exch-SMTP-Turf-List
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSMTPTurfList
+name: ms-Exch-SMTP-Turf-List
+schemaIDGUID: 0b836da5-3b20-11d3-aa6f-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-SMTP-Turf-List,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SNADS-Connector	       
+# The SNA Distribution System (SNADS) Connector.
+#
+dn: CN=ms-Exch-SNADS-Connector,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-SNADS-Connector
+distinguishedName: CN=ms-Exch-SNADS-Connector,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.5.7000.62.1003
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SNADS-Connector
+adminDescription: ms-Exch-SNADS-Connector
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSNADSConnector
+name: ms-Exch-SNADS-Connector
+schemaIDGUID: 91b17254-b09e-11d2-aa06-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-SNADS-Connector,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Storage-Group 
+# The list of stores for this Microsoft Jet instance.
+#
+dn: CN=ms-Exch-Storage-Group,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Storage-Group
+distinguishedName: CN=ms-Exch-Storage-Group,${SCHEMADN}
+possSuperiors: computer
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.11006
+mustContain: cn
+mayContain: msExchMinAdminVersion
+mayContain: msExchESEParamCachedClosedTables
+mayContain: msExchRestore
+mayContain: msExchESEParamPageTempDBMin
+mayContain: msExchESEParamPageFragment
+mayContain: msExchESEParamMaxTemporaryTables
+mayContain: msExchESEParamMaxCursors
+mayContain: msExchESEParamEnableOnlineDefrag
+mayContain: msExchESEParamEnableIndexChecking
+mayContain: msExchESEParamDbExtensionSize
+mayContain: msExchESEParamCommitDefault
+mayContain: msExchESEParamCheckpointDepthMax
+mayContain: msExchESEParamBaseName
+mayContain: msExchRecovery
+mayContain: msExchESEParamZeroDatabaseDuringBackup
+mayContain: msExchESEParamWaitLogFlush
+mayContain: msExchESEParamTempPath
+mayContain: msExchESEParamSystemPath
+mayContain: msExchESEParamPreferredVerPages
+mayContain: msExchESEParamPreferredMaxOpenTables
+mayContain: msExchESEParamMaxVerPages
+mayContain: msExchESEParamMaxSessions
+mayContain: msExchESEParamMaxOpenTables
+mayContain: msExchESEParamLogWaitingUserMax
+mayContain: msExchESEParamLogFileSize
+mayContain: msExchESEParamLogFilePath
+mayContain: msExchESEParamLogCheckpointPeriod
+mayContain: msExchESEParamLogBuffers
+mayContain: msExchESEParamEventSource
+mayContain: msExchESEParamCircularLog
+mayContain: displayName
+mayContain: description
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Storage-Group
+adminDescription: ms-Exch-Storage-Group
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchStorageGroup
+name: ms-Exch-Storage-Group
+schemaIDGUID: 3435244a-a982-11d2-a9ff-00c04f8eedd8
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Storage-Group,${SCHEMADN}
+
+
+
+#
+# ms-Exch-System-Objects-Container	  
+# The Exchange container for system-related objects, such as public
+# folder proxies.
+#
+dn: CN=ms-Exch-System-Objects-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-System-Objects-Container
+distinguishedName: CN=ms-Exch-System-Objects-Container,${SCHEMADN}
+possSuperiors: domainDNS
+subClassOf: container
+governsID: 1.2.840.113556.1.5.7000.62.50034
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-System-Objects-Container
+adminDescription: ms-Exch-System-Objects-Container
+objectClassCategory: 1
+lDAPDisplayName: msExchSystemObjectsContainer
+name: ms-Exch-System-Objects-Container
+schemaIDGUID: 0bffa04c-7d8e-44cd-968a-b2cac11d17e1
+systemOnly: FALSE
+defaultSecurityDescriptor: D:(A;;RPLCLORC;;;AU)
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-System-Objects-Container,${SCHEMADN}
+
+
+
+#
+# ms-Exch-System-Policy		  
+# The internal system policy.
+#
+dn: CN=ms-Exch-System-Policy,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-System-Policy
+distinguishedName: CN=ms-Exch-System-Policy,${SCHEMADN}
+possSuperiors: msExchSystemPolicyContainer
+subClassOf: msExchGenericPolicy
+governsID: 1.2.840.113556.1.5.7000.62.16
+mayContain: msExchMinAdminVersion
+mayContain: heuristics
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-System-Policy
+adminDescription: ms-Exch-System-Policy
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSystemPolicy
+name: ms-Exch-System-Policy
+schemaIDGUID: ba085a33-8807-4c6c-9522-2cf5a2a5e9c2
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-System-Policy,${SCHEMADN}
+
+
+
+#
+# ms-Exch-System-Policy-Container
+#
+dn: CN=ms-Exch-System-Policy-Container,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-System-Policy-Container
+distinguishedName: CN=ms-Exch-System-Policy-Container,${SCHEMADN}
+possSuperiors: msExchOrganizationContainer
+subClassOf: msExchGenericPolicyContainer
+governsID: 1.2.840.113556.1.5.7000.62.15
+mayContain: msExchMinAdminVersion
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-System-Policy-Container
+adminDescription: ms-Exch-System-Policy-Container
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: msExchSystemPolicyContainer
+name: ms-Exch-System-Policy-Container
+schemaIDGUID: 32412a7a-22af-479c-a444-624c0137122e
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-System-Policy-Container,${SCHEMADN}
+
+
+#
+# ms-Exch-TP4-Stack	
+# The TP4 Transport Stack for the MTA.
+#
+dn: CN=ms-Exch-TP4-Stack,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-TP4-Stack
+distinguishedName: CN=ms-Exch-TP4-Stack,${SCHEMADN}
+possSuperiors: mTA
+possSuperiors: container
+possSuperiors: computer
+subClassOf: transportStack
+governsID: 1.2.840.113556.1.3.25
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-TP4-Stack
+adminDescription: ms-Exch-TP4-Stack
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: tP4Stack
+name: ms-Exch-TP4-Stack
+schemaIDGUID: a8df74db-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-TP4-Stack,${SCHEMADN}
+
+
+#
+# ms-Exch-TP4-X400-Link 
+# Specifies a remote X.400 MTA using a TP4 Transport.
+#
+dn: CN=ms-Exch-TP4-X400-Link,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-TP4-X400-Link
+distinguishedName: CN=ms-Exch-TP4-X400-Link,${SCHEMADN}
+possSuperiors: container
+subClassOf: x400Link
+governsID: 1.2.840.113556.1.3.33
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-TP4-X400-Link
+adminDescription: ms-Exch-TP4-X400-Link
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: tP4X400Link
+name: ms-Exch-TP4-X400-Link
+schemaIDGUID: a8df74dc-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-TP4-X400-Link,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Transport-Stack	   
+# Represents the X.400 Transport Stacks.
+#
+dn: CN=ms-Exch-Transport-Stack,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Transport-Stack
+distinguishedName: CN=ms-Exch-Transport-Stack,${SCHEMADN}
+possSuperiors: mTA
+possSuperiors: container
+possSuperiors: computer
+subClassOf: top
+governsID: 1.2.840.113556.1.3.18
+mustContain: cn
+mayContain: supportingStackBL
+mayContain: x400SelectorSyntax
+mayContain: tSelector
+mayContain: sSelector
+mayContain: pSelector
+mayContain: nAddressType
+mayContain: nAddress
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transport-Stack
+adminDescription: ms-Exch-Transport-Stack
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: transportStack
+name: ms-Exch-Transport-Stack
+schemaIDGUID: a8df74dd-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Transport-Stack,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Uce    
+# Reserved.
+#
+dn: CN=ms-Exch-Uce,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-Uce
+distinguishedName: CN=ms-Exch-Uce,${SCHEMADN}
+possSuperiors: msExchMessageDeliveryConfig
+subClassOf: top
+governsID: 1.2.840.113556.1.5.7000.62.50037
+mayContain: msExchUceStoreActionThreshold
+mayContain: msExchUceEnabled
+mayContain: msExchUceBlockThreshold
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Uce
+adminDescription: ms-Exch-Uce
+objectClassCategory: 1
+lDAPDisplayName: msExchUce
+name: ms-Exch-Uce
+schemaIDGUID: c5ccdce1-b399-405f-8ab7-bc6434d2e422
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-Uce,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-Stack	
+# The X.25 Transport Stack for the MTA.
+#
+dn: CN=ms-Exch-X25-Stack,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-X25-Stack
+distinguishedName: CN=ms-Exch-X25-Stack,${SCHEMADN}
+possSuperiors: mTA
+possSuperiors: container
+possSuperiors: computer
+subClassOf: transportStack
+governsID: 1.2.840.113556.1.3.27
+mustContain: x25LeasedLinePort
+mayContain: x25LeasedOrSwitched
+mayContain: x25FacilitiesDataIncoming
+mayContain: x25CallUserDataIncoming
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Stack
+adminDescription: ms-Exch-X25-Stack
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: x25Stack
+name: ms-Exch-X25-Stack
+schemaIDGUID: a8df74de-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-X25-Stack,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-X400-Link  
+# Specifies a remote X.400 MTA using an X.25 Transport.
+#
+dn: CN=ms-Exch-X25-X400-Link,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-X25-X400-Link
+distinguishedName: CN=ms-Exch-X25-X400-Link,${SCHEMADN}
+possSuperiors: container
+subClassOf: x400Link
+governsID: 1.2.840.113556.1.3.35
+mayContain: x25RemoteMTAPhone
+mayContain: x25FacilitiesDataOutgoing
+mayContain: x25FacilitiesDataIncoming
+mayContain: x25CallUserDataOutgoing
+mayContain: x25CallUserDataIncoming
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-X400-Link
+adminDescription: ms-Exch-X25-X400-Link
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: x25X400Link
+name: ms-Exch-X25-X400-Link
+schemaIDGUID: a8df74df-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-X25-X400-Link,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X400-Link	 
+# Specifies a remote X.400 MTA.
+#
+dn: CN=ms-Exch-X400-Link,${SCHEMADN}
+objectClass: top
+objectClass: classSchema
+cn: ms-Exch-X400-Link
+distinguishedName: CN=ms-Exch-X400-Link,${SCHEMADN}
+possSuperiors: container
+subClassOf: mailGateway
+governsID: 1.2.840.113556.1.3.29
+mayContain: x400SelectorSyntax
+mayContain: x400AttachmentType
+mayContain: twoWayAlternateFacility
+mayContain: turnRequestThreshold
+mayContain: transportExpeditedData
+mayContain: tempAssocThreshold
+mayContain: tSelector
+mayContain: supportingStack
+mayContain: sessionDisconnectTimer
+mayContain: sSelectorInbound
+mayContain: sSelector
+mayContain: rTSWindowSize
+mayContain: rTSRecoveryTimeout
+mayContain: rTSCheckpointSize
+mayContain: pSelectorInbound
+mayContain: pSelector
+mayContain: openRetryInterval
+mayContain: numOfTransferRetries
+mayContain: numOfOpenRetries
+mayContain: nAddressType
+mayContain: nAddress
+mayContain: mTALocalDesig
+mayContain: mTALocalCred
+mayContain: localInitialTurn
+mayContain: gatewayLocalDesig
+mayContain: gatewayLocalCred
+mayContain: associationLifetime
+rDNAttID: cn
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X400-Link
+adminDescription: ms-Exch-X400-Link
+auxiliaryClass: msExchBaseClass
+objectClassCategory: 1
+lDAPDisplayName: x400Link
+name: ms-Exch-X400-Link
+schemaIDGUID: a8df74e0-c5ea-11d1-bbcb-0080c76670c0
+systemOnly: FALSE
+defaultSecurityDescriptor: D:S:
+defaultHidingValue: TRUE
+objectCategory: CN=Class-Schema,${SCHEMADN}
+defaultObjectCategory: CN=ms-Exch-X400-Link,${SCHEMADN}
+
+
+
+##############################################################################
+# AttributeSchema added
+##############################################################################
+
+
+
+
+# 
+# msExch-Proxy-Gen-Options
+#
+dn: CN=msExch-Proxy-Gen-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: msExch-Proxy-Gen-Options
+distinguishedName: CN=msExch-Proxy-Gen-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50044
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: msExch-Proxy-Gen-Options
+adminDescription: msExch-Proxy-Gen-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchProxyGenOptions
+name: msExch-Proxy-Gen-Options
+schemaIDGUID: 974c9a02-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Access-Control-Map	
+# Contains the mapping for the access controls.
+#
+dn: CN=ms-Exch-Access-Control-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Access-Control-Map
+distinguishedName: CN=ms-Exch-Access-Control-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.64
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Access-Control-Map
+adminDescription: ms-Exch-Access-Control-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAccessControlMap
+name: ms-Exch-Access-Control-Map
+schemaIDGUID: 8ff54464-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Access-Flags	    
+# The authentication method to use.
+#
+dn: CN=ms-Exch-Access-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Access-Flags
+distinguishedName: CN=ms-Exch-Access-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Access-Flags
+adminDescription: ms-Exch-Access-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAccessFlags
+name: ms-Exch-Access-Flags
+schemaIDGUID: 901b6a04-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Access-SSL-Flags	
+# The type of encrypted channel that this resource supports.
+#
+dn: CN=ms-Exch-Access-SSL-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Access-SSL-Flags
+distinguishedName: CN=ms-Exch-Access-SSL-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Access-SSL-Flags
+adminDescription: ms-Exch-Access-SSL-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAccessSSLFlags
+name: ms-Exch-Access-SSL-Flags
+schemaIDGUID: 903f2d4a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Activation-Schedule	
+# This is the schedule if "scheduled times" is selected.
+#
+dn: CN=ms-Exch-Activation-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Activation-Schedule
+distinguishedName: CN=ms-Exch-Activation-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.213
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+mAPIID: 32837
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Activation-Schedule
+adminDescription: ms-Exch-Activation-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: activationSchedule
+name: ms-Exch-Activation-Schedule
+schemaIDGUID: bf967916-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Activation-Style
+#
+dn: CN=ms-Exch-Activation-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Activation-Style
+distinguishedName: CN=ms-Exch-Activation-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.73
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32838
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Activation-Style
+adminDescription: ms-Exch-Activation-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: activationStyle
+name: ms-Exch-Activation-Style
+schemaIDGUID: bf967917-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ADC-Global-Names 
+#
+dn: CN=ms-Exch-ADC-Global-Names,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ADC-Global-Names
+distinguishedName: CN=ms-Exch-ADC-Global-Names,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.63
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ADC-Global-Names
+adminDescription: ms-Exch-ADC-Global-Names
+oMSyntax: 64
+searchFlags: 1
+lDAPDisplayName: msExchADCGlobalNames
+name: ms-Exch-ADC-Global-Names
+schemaIDGUID: 9062f090-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ADC-Object-Type     
+# A bit used to distinguish the type of connection agreement.
+#
+dn: CN=ms-Exch-ADC-Object-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ADC-Object-Type
+distinguishedName: CN=ms-Exch-ADC-Object-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.84
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ADC-Object-Type
+adminDescription: ms-Exch-ADC-Object-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchADCObjectType
+name: ms-Exch-ADC-Object-Type
+schemaIDGUID: 4859fb55-1924-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ADC-Options 
+# The options bitstring.
+#
+dn: CN=ms-Exch-ADC-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ADC-Options
+distinguishedName: CN=ms-Exch-ADC-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.41
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ADC-Options
+adminDescription: ms-Exch-ADC-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchADCOptions
+name: ms-Exch-ADC-Options
+schemaIDGUID: 90891630-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Additional-DN-Map	
+# Additional source-target pairs for straight distinguished name (DN)
+# mapping.
+#
+dn: CN=ms-Exch-Additional-DN-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Additional-DN-Map
+distinguishedName: CN=ms-Exch-Additional-DN-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.42
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Additional-DN-Map
+adminDescription: ms-Exch-Additional-DN-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAdditionalDNMap
+name: ms-Exch-Additional-DN-Map
+schemaIDGUID: 90a814c2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Address-List-OU
+#
+dn: CN=ms-Exch-Address-List-OU,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Address-List-OU
+distinguishedName: CN=ms-Exch-Address-List-OU,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.112
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Address-List-OU
+adminDescription: ms-Exch-Address-List-OU
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAddressListOU
+name: ms-Exch-Address-List-OU
+schemaIDGUID: f4b93a0d-f30c-44ff-aa47-e74806dbced2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Address-List-Service-BL   
+# 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}
+
+
+
+
+#
+# ms-Exch-Address-List-Service-Link	 
+# A link from the address list service to the Exchange server it
+# should be running on.
+#
+dn: CN=ms-Exch-Address-List-Service-Link,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Address-List-Service-Link
+distinguishedName: CN=ms-Exch-Address-List-Service-Link,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.75
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1016
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Address-List-Service-Link
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Address-List-Service-Link
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchAddressListServiceLink
+name: ms-Exch-Address-List-Service-Link
+schemaIDGUID: 9b6e9584-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Add-Groups-To-Token
+#
+dn: CN=ms-Exch-Add-Groups-To-Token,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Add-Groups-To-Token
+distinguishedName: CN=ms-Exch-Add-Groups-To-Token,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.95
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Add-Groups-To-Token
+adminDescription: ms-Exch-Add-Groups-To-Token
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchAddGroupsToToken
+name: ms-Exch-Add-Groups-To-Token
+schemaIDGUID: 9c4d7592-ef4a-4c69-8f30-6f18ca1ec370
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ADMD	    
+# Used by the message transfer agent (MTA) to determine if Internal
+# Trace Information should be stripped.
+dn: CN=ms-Exch-ADMD,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ADMD
+distinguishedName: CN=ms-Exch-ADMD,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.232
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 32841
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ADMD
+adminDescription: ms-Exch-ADMD
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: aDMD
+name: ms-Exch-ADMD
+schemaIDGUID: a8df7390-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Admins     
+# A link to all Exchange administrators within the organization along
+# with the appropriate permissions.
+#
+dn: CN=ms-Exch-Admins,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admins
+distinguishedName: CN=ms-Exch-Admins,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50064
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admins
+adminDescription: ms-Exch-Admins
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAdmins
+name: ms-Exch-Admins
+schemaIDGUID: b644c27a-a419-40b6-a62e-180930df5610
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Admin-ACL	      
+# The access control list (ACL).
+#
+dn: CN=ms-Exch-Admin-ACL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admin-ACL
+distinguishedName: CN=ms-Exch-Admin-ACL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2011
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-ACL
+adminDescription: ms-Exch-Admin-ACL
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAdminACL
+name: ms-Exch-Admin-ACL
+schemaIDGUID: 90c975ae-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Extension-DLL
+#
+dn: CN=ms-Exch-Admin-Extension-DLL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admin-Extension-DLL
+distinguishedName: CN=ms-Exch-Admin-Extension-DLL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.95
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 255
+mAPIID: 32844
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Extension-DLL
+adminDescription: ms-Exch-Admin-Extension-DLL
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: adminExtensionDLL
+name: ms-Exch-Admin-Extension-DLL
+schemaIDGUID: a8df7391-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Admin-Groups-Enabled	
+# Used by the user interface (UI) to determine whether to display
+# Administrator Groups.
+#
+dn: CN=ms-Exch-Admin-Groups-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admin-Groups-Enabled
+distinguishedName: CN=ms-Exch-Admin-Groups-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50026
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Groups-Enabled
+adminDescription: ms-Exch-Admin-Groups-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchAdminGroupsEnabled
+name: ms-Exch-Admin-Groups-Enabled
+schemaIDGUID: e32977ae-1d31-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Admin-Group-Mode 
+# The type of servers that are in the Administrator Group.
+#
+dn: CN=ms-Exch-Admin-Group-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admin-Group-Mode
+distinguishedName: CN=ms-Exch-Admin-Group-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50014
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Group-Mode
+adminDescription: ms-Exch-Admin-Group-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAdminGroupMode
+name: ms-Exch-Admin-Group-Mode
+schemaIDGUID: 90ead69a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Admin-Mailbox	
+# A link to the administrator mailbox of the cc:Mail Connector.
+#
+dn: CN=ms-Exch-Admin-Mailbox,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Admin-Mailbox
+distinguishedName: CN=ms-Exch-Admin-Mailbox,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1034
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Admin-Mailbox
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Admin-Mailbox
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchAdminMailbox
+name: ms-Exch-Admin-Mailbox
+schemaIDGUID: 94e9a76c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Aging-Keep-Time   
+# The time value used to determine when to remove indexes, views, and
+# categorizations. The default is 8 days.
+#
+dn: CN=ms-Exch-Aging-Keep-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Aging-Keep-Time
+distinguishedName: CN=ms-Exch-Aging-Keep-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11059
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Aging-Keep-Time
+adminDescription: ms-Exch-Aging-Keep-Time
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAgingKeepTime
+name: ms-Exch-Aging-Keep-Time
+schemaIDGUID: 5872299f-123a-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Alias-Gen-Format    
+# The time/date that this policy was applied.
+#
+dn: CN=ms-Exch-Alias-Gen-Format,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alias-Gen-Format
+distinguishedName: CN=ms-Exch-Alias-Gen-Format,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50010
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alias-Gen-Format
+adminDescription: ms-Exch-Alias-Gen-Format
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchAliasGenFormat
+name: ms-Exch-Alias-Gen-Format
+schemaIDGUID: 912b3618-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Alias-Gen-Type   
+# The time/date that this policy was applied.
+#
+dn: CN=ms-Exch-Alias-Gen-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alias-Gen-Type
+distinguishedName: CN=ms-Exch-Alias-Gen-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50011
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alias-Gen-Type
+adminDescription: ms-Exch-Alias-Gen-Type
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchAliasGenType
+name: ms-Exch-Alias-Gen-Type
+schemaIDGUID: 914ef95e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Alias-Gen-Uniqueness	
+# The time/date that this policy was applied.
+#
+dn: CN=ms-Exch-Alias-Gen-Uniqueness,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alias-Gen-Uniqueness
+distinguishedName: CN=ms-Exch-Alias-Gen-Uniqueness,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50012
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alias-Gen-Uniqueness
+adminDescription: ms-Exch-Alias-Gen-Uniqueness
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchAliasGenUniqueness
+name: ms-Exch-Alias-Gen-Uniqueness
+schemaIDGUID: 91705a4a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Allow-Additional-Resources	
+# Allows conference resource extension requests.
+#
+dn: CN=ms-Exch-Allow-Additional-Resources,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Allow-Additional-Resources
+distinguishedName: CN=ms-Exch-Allow-Additional-Resources,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9006
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Allow-Additional-Resources
+adminDescription: ms-Exch-Allow-Additional-Resources
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchAllowAdditionalResources
+name: ms-Exch-Allow-Additional-Resources
+schemaIDGUID: 91941d90-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Allow-Enhanced-Security
+#
+dn: CN=ms-Exch-Allow-Enhanced-Security,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Allow-Enhanced-Security
+distinguishedName: CN=ms-Exch-Allow-Enhanced-Security,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11087
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Allow-Enhanced-Security
+adminDescription: ms-Exch-Allow-Enhanced-Security
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchAllowEnhancedSecurity
+name: ms-Exch-Allow-Enhanced-Security
+schemaIDGUID: 63b79cf2-1f4b-4766-ba5b-814b6077640f
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Allow-Time-Extensions		
+# Allows conference time extension requests.
+#
+dn: CN=ms-Exch-Allow-Time-Extensions,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Allow-Time-Extensions
+distinguishedName: CN=ms-Exch-Allow-Time-Extensions,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9005
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Allow-Time-Extensions
+adminDescription: ms-Exch-Allow-Time-Extensions
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchAllowTimeExtensions
+name: ms-Exch-Allow-Time-Extensions
+schemaIDGUID: 91b7e0d6-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Alternate-Server	
+# Contains the host name of an alternate server that accepts mail for
+# the default domain.
+dn: CN=ms-Exch-Alternate-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alternate-Server
+distinguishedName: CN=ms-Exch-Alternate-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12532
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alternate-Server
+adminDescription: ms-Exch-Alternate-Server
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: msExchAlternateServer
+name: ms-Exch-Alternate-Server
+schemaIDGUID: 974c99f9-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+# 
+# ms-Exch-Alt-Recipient	       
+# Delivers to this recipient if a specified recipient cannot be
+# delivered to.
+#
+dn: CN=ms-Exch-Alt-Recipient,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alt-Recipient
+distinguishedName: CN=ms-Exch-Alt-Recipient,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.126
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32846
+linkID: 12
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alt-Recipient
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Alt-Recipient
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: altRecipient
+name: ms-Exch-Alt-Recipient
+schemaIDGUID: bf96791e-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Alt-Recipient-BL	  
+# A backlink to ms-Exch-Alt-Recipient.
+#
+dn: CN=ms-Exch-Alt-Recipient-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Alt-Recipient-BL
+distinguishedName: CN=ms-Exch-Alt-Recipient-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.294
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32847
+linkID: 13
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Alt-Recipient-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Alt-Recipient-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: altRecipientBL
+name: ms-Exch-Alt-Recipient-BL
+schemaIDGUID: bf96791f-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-AL-Object-Version
+#
+dn: CN=ms-Exch-AL-Object-Version,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-AL-Object-Version
+distinguishedName: CN=ms-Exch-AL-Object-Version,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.59
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-AL-Object-Version
+adminDescription: ms-Exch-AL-Object-Version
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchALObjectVersion
+name: ms-Exch-AL-Object-Version
+schemaIDGUID: 910c3786-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Anonymous-Access  
+# Determines whether or not anonymous access is allowed via this
+# protocol.
+#
+dn: CN=ms-Exch-Anonymous-Access,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Anonymous-Access
+distinguishedName: CN=ms-Exch-Anonymous-Access,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.482
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33159
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Anonymous-Access
+adminDescription: ms-Exch-Anonymous-Access
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: anonymousAccess
+name: ms-Exch-Anonymous-Access
+schemaIDGUID: a8df7392-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Anonymous-Account
+#
+dn: CN=ms-Exch-Anonymous-Account,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Anonymous-Account
+distinguishedName: CN=ms-Exch-Anonymous-Account,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.561
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 35878
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Anonymous-Account
+adminDescription: ms-Exch-Anonymous-Account
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: anonymousAccount
+name: ms-Exch-Anonymous-Account
+schemaIDGUID: a8df7393-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Applies-To-Smtp-VS
+#
+dn: CN=ms-Exch-Applies-To-Smtp-VS,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Applies-To-Smtp-VS
+distinguishedName: CN=ms-Exch-Applies-To-Smtp-VS,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5058
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1034
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Applies-To-Smtp-VS
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Applies-To-Smtp-VS
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchAppliesToSmtpVS
+name: ms-Exch-Applies-To-Smtp-VS
+schemaIDGUID: 2925413e-fa41-4d01-945d-a15b5d6bb965
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Applies-To-Smtp-VS-BL	
+#
+dn: CN=ms-Exch-Applies-To-Smtp-VS-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Applies-To-Smtp-VS-BL
+distinguishedName: CN=ms-Exch-Applies-To-Smtp-VS-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5059
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1035
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Applies-To-Smtp-VS-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Applies-To-Smtp-VS-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchAppliesToSmtpVSBL
+name: ms-Exch-Applies-To-Smtp-VS-BL
+schemaIDGUID: f7d091b1-1ced-446a-b521-563a01eaf22c
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Assistant-Name
+#
+#dn: CN=ms-Exch-Assistant-Name,${SCHEMADN}
+#objectClass: top
+#objectClass: attributeSchema
+#cn: ms-Exch-Assistant-Name
+#distinguishedName: CN=ms-Exch-Assistant-Name,${SCHEMADN}
+#attributeID: 1.2.840.113556.1.2.444
+#attributeSyntax: 2.5.5.12
+#isSingleValued: TRUE
+#rangeLower: 1
+#rangeUpper: 256
+#mAPIID: 14896
+#adminDisplayName: ms-Exch-Assistant-Name
+#adminDescription: ms-Exch-Assistant-Name
+#oMSyntax: 64
+#searchFlags: 0
+#lDAPDisplayName: msExchAssistantName
+#name: ms-Exch-Assistant-Name
+#schemaIDGUID: a8df7394-c5ea-11d1-bbcb-0080c76670c0
+#attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+#objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Associated-AG
+#
+dn: CN=ms-Exch-Associated-AG,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Associated-AG
+distinguishedName: CN=ms-Exch-Associated-AG,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50031
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Associated-AG
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Associated-AG
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchAssociatedAG
+name: ms-Exch-Associated-AG
+schemaIDGUID: e5971321-1d3e-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Association-Lifetime	  
+# The length of time a connection can be idle before it is closed.
+#
+dn: CN=ms-Exch-Association-Lifetime,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Association-Lifetime
+distinguishedName: CN=ms-Exch-Association-Lifetime,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.149
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 32850
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Association-Lifetime
+adminDescription: ms-Exch-Association-Lifetime
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: associationLifetime
+name: ms-Exch-Association-Lifetime
+schemaIDGUID: a8df7396-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Assoc-Remote-DXA
+#
+dn: CN=ms-Exch-Assoc-Remote-DXA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Assoc-Remote-DXA
+distinguishedName: CN=ms-Exch-Assoc-Remote-DXA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.299
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32849
+linkID: 123
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Assoc-Remote-DXA
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Assoc-Remote-DXA
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: assocRemoteDXA
+name: ms-Exch-Assoc-Remote-DXA
+schemaIDGUID: 16775789-47f3-11d1-a9c3-0000f80367c1
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Attribute-Certificate
+#
+dn: CN=ms-Exch-Attribute-Certificate,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Attribute-Certificate
+distinguishedName: CN=ms-Exch-Attribute-Certificate,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.587
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 32767
+mAPIID: 35909
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Attribute-Certificate
+adminDescription: ms-Exch-Attribute-Certificate
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: attributeCertificate
+name: ms-Exch-Attribute-Certificate
+schemaIDGUID: 1677578b-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Audit-Flags 
+# A bitmap indicating the events to log.
+#
+dn: CN=ms-Exch-Audit-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Audit-Flags
+distinguishedName: CN=ms-Exch-Audit-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9004
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Audit-Flags
+adminDescription: ms-Exch-Audit-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAuditFlags
+name: ms-Exch-Audit-Flags
+schemaIDGUID: 91d47d0e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Authentication-Flags	
+# Indicates which type of authentication this resource accepts.
+#
+dn: CN=ms-Exch-Authentication-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Authentication-Flags
+distinguishedName: CN=ms-Exch-Authentication-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2003
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Authentication-Flags
+adminDescription: ms-Exch-Authentication-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAuthenticationFlags
+name: ms-Exch-Authentication-Flags
+schemaIDGUID: 91f5ddfa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-AuthMailDisposition
+#
+dn: CN=ms-Exch-AuthMailDisposition,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-AuthMailDisposition
+distinguishedName: CN=ms-Exch-AuthMailDisposition,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.5061
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-AuthMailDisposition
+adminDescription: ms-Exch-AuthMailDisposition
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAuthMailDisposition
+name: ms-Exch-AuthMailDisposition
+schemaIDGUID: 57cfb6f7-1e2c-4d3e-96df-40208624baff
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Authorization-Persistence
+#
+dn: CN=ms-Exch-Authorization-Persistence,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Authorization-Persistence
+distinguishedName: CN=ms-Exch-Authorization-Persistence,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15011
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Authorization-Persistence
+adminDescription: ms-Exch-Authorization-Persistence
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchAuthorizationPersistence
+name: ms-Exch-Authorization-Persistence
+schemaIDGUID: d6ae616b-16c5-44ce-b272-8b923aebe335
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Authorized-Domain
+# The domain name of the authentication account to be used when
+# connecting to the other side of the connector.
+#
+dn: CN=ms-Exch-Authorized-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Authorized-Domain
+distinguishedName: CN=ms-Exch-Authorized-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.202
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 15
+mAPIID: 32852
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Authorized-Domain
+adminDescription: ms-Exch-Authorized-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: authorizedDomain
+name: ms-Exch-Authorized-Domain
+schemaIDGUID: a8df739a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Authorized-Password 
+# The password of the authentication account to be used when connecting
+# to the other side of the connector.
+#
+dn: CN=ms-Exch-Authorized-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Authorized-Password
+distinguishedName: CN=ms-Exch-Authorized-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.193
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 512
+mAPIID: 32853
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Authorized-Password
+adminDescription: ms-Exch-Authorized-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: authorizedPassword
+name: ms-Exch-Authorized-Password
+schemaIDGUID: a8df739b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Authorized-User  
+# The user name of the authentication account to be used when connecting
+# to the other side of the connector.
+#
+dn: CN=ms-Exch-Authorized-User,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Authorized-User
+distinguishedName: CN=ms-Exch-Authorized-User,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.276
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 512
+mAPIID: 32854
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Authorized-User
+adminDescription: ms-Exch-Authorized-User
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: authorizedUser
+name: ms-Exch-Authorized-User
+schemaIDGUID: a8df739d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Auth-Orig	    
+# The users who are allowed to send mail to this recipient.
+#
+dn: CN=ms-Exch-Auth-Orig,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Auth-Orig
+distinguishedName: CN=ms-Exch-Auth-Orig,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.129
+attributeSyntax: 2.5.5.7
+isSingleValued: FALSE
+linkID: 110
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Auth-Orig
+oMObjectClass:: VgYBAgULHQ==
+adminDescription: ms-Exch-Auth-Orig
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: authOrig
+name: ms-Exch-Auth-Orig
+schemaIDGUID: a8df7397-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Auth-Orig-BL	  
+# A backlink to ms-Exch-Auth-Orig.
+#
+dn: CN=ms-Exch-Auth-Orig-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Auth-Orig-BL
+distinguishedName: CN=ms-Exch-Auth-Orig-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.290
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32851
+linkID: 111
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Auth-Orig-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Auth-Orig-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: authOrigBL
+name: ms-Exch-Auth-Orig-BL
+schemaIDGUID: a8df7398-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-AutoReply
+#
+dn: CN=ms-Exch-AutoReply,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-AutoReply
+distinguishedName: CN=ms-Exch-AutoReply,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.286
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32779
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-AutoReply
+adminDescription: ms-Exch-AutoReply
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: autoReply
+name: ms-Exch-AutoReply
+schemaIDGUID: bf967929-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-AutoReply-Message 
+# Contains Internet Locator Service (ILS) settings in the form
+# SERVER/ACCOUNT.
+#
+dn: CN=ms-Exch-AutoReply-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-AutoReply-Message
+distinguishedName: CN=ms-Exch-AutoReply-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.287
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32778
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-AutoReply-Message
+adminDescription: ms-Exch-AutoReply-Message
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: autoReplyMessage
+name: ms-Exch-AutoReply-Message
+schemaIDGUID: bf96792a-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Available-Authorization-Packages
+#
+dn: CN=ms-Exch-Available-Authorization-Packages,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Available-Authorization-Packages
+distinguishedName: CN=ms-Exch-Available-Authorization-Packages,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.476
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 512
+mAPIID: 33153
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Available-Authorization-Packages
+adminDescription: ms-Exch-Available-Authorization-Packages
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: availableAuthorizationPackages
+name: ms-Exch-Available-Authorization-Packages
+schemaIDGUID: a8df739e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Available-Distributions
+#
+dn: CN=ms-Exch-Available-Distributions,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Available-Distributions
+distinguishedName: CN=ms-Exch-Available-Distributions,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.486
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 10240
+mAPIID: 33163
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Available-Distributions
+adminDescription: ms-Exch-Available-Distributions
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: availableDistributions
+name: ms-Exch-Available-Distributions
+schemaIDGUID: a8df739f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Available-Servers		    
+# The installed conferencing servers.
+#
+dn: CN=ms-Exch-Available-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Available-Servers
+distinguishedName: CN=ms-Exch-Available-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9020
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Available-Servers
+adminDescription: ms-Exch-Available-Servers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchAvailableServers
+name: ms-Exch-Available-Servers
+schemaIDGUID: 923b022c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-BackEnd-VDir-URL
+#
+dn: CN=ms-Exch-BackEnd-VDir-URL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-BackEnd-VDir-URL
+distinguishedName: CN=ms-Exch-BackEnd-VDir-URL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15012
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-BackEnd-VDir-URL
+adminDescription: ms-Exch-BackEnd-VDir-URL
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchBackEndVDirURL
+name: ms-Exch-BackEnd-VDir-URL
+schemaIDGUID: b4b283b6-0c3f-4a59-9e50-be9026228231
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Background-Threads
+# The maximum number of background threads per server.
+#
+dn: CN=ms-Exch-Background-Threads,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Background-Threads
+distinguishedName: CN=ms-Exch-Background-Threads,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11038
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Background-Threads
+adminDescription: ms-Exch-Background-Threads
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchBackgroundThreads
+name: ms-Exch-Background-Threads
+schemaIDGUID: 93d051f0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Bar-Message-Class
+#
+dn: CN=ms-Exch-Bar-Message-Class,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Bar-Message-Class
+distinguishedName: CN=ms-Exch-Bar-Message-Class,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1064
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Bar-Message-Class
+adminDescription: ms-Exch-Bar-Message-Class
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchBarMessageClass
+name: ms-Exch-Bar-Message-Class
+schemaIDGUID: cf43e549-2ae1-410f-b896-02e40b934373
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Basic-Authentication-Domain	  
+# The default domain name for incoming basic authentication.
+#
+dn: CN=ms-Exch-Basic-Authentication-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Basic-Authentication-Domain
+distinguishedName: CN=ms-Exch-Basic-Authentication-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2010
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Basic-Authentication-Domain
+adminDescription: ms-Exch-Basic-Authentication-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchBasicAuthenticationDomain
+name: ms-Exch-Basic-Authentication-Domain
+schemaIDGUID: 94262698-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Bridgeheaded-Local-Connectors-DN-BL	
+# A list of connectors (in the VSI's routing group) that this VSI is
+# the bridgehead for.
+#
+dn: CN=ms-Exch-Bridgeheaded-Local-Connectors-DN-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL
+distinguishedName: CN=ms-Exch-Bridgeheaded-Local-Connectors-DN-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12515
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1003
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchBridgeheadedLocalConnectorsDNBL
+name: ms-Exch-Bridgeheaded-Local-Connectors-DN-BL
+schemaIDGUID: 944c4c38-b093-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+# 
+# ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL
+# A list of connectors (in a remote routing group) that this VSI is
+# the bridgehead for.
+#
+dn: CN=ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL
+distinguishedName: CN=ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12516
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1005
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchBridgeheadedRemoteConnectorsDNBL
+name: ms-Exch-Bridgeheaded-Remote-Connectors-DN-BL
+schemaIDGUID: 946dad24-b093-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Bridgehead-Servers	  
+#
+dn: CN=ms-Exch-Bridgehead-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Bridgehead-Servers
+distinguishedName: CN=ms-Exch-Bridgehead-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.463
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33140
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Bridgehead-Servers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Bridgehead-Servers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: bridgeheadServers
+name: ms-Exch-Bridgehead-Servers
+schemaIDGUID: a8df73a0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Business-Roles
+#
+dn: CN=ms-Exch-Business-Roles,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Business-Roles
+distinguishedName: CN=ms-Exch-Business-Roles,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.105
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 4096
+mAPIID: 32803
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Business-Roles
+adminDescription: ms-Exch-Business-Roles
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: businessRoles
+name: ms-Exch-Business-Roles
+schemaIDGUID: f0f8ff87-1191-11d0-a060-00aa006c33ed
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CalCon-Client-Wait
+#
+dn: CN=ms-Exch-CalCon-Client-Wait,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CalCon-Client-Wait
+distinguishedName: CN=ms-Exch-CalCon-Client-Wait,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1043
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CalCon-Client-Wait
+adminDescription: ms-Exch-CalCon-Client-Wait
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCalConClientWait
+name: ms-Exch-CalCon-Client-Wait
+schemaIDGUID: 75447978-3752-4256-a89f-b4dfebae9a32
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CalCon-Providers	  
+#
+dn: CN=ms-Exch-CalCon-Providers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CalCon-Providers
+distinguishedName: CN=ms-Exch-CalCon-Providers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1042
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CalCon-Providers
+adminDescription: ms-Exch-CalCon-Providers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCalConProviders
+name: ms-Exch-CalCon-Providers
+schemaIDGUID: 73b41a3e-68b0-45a1-9e30-697b6d19aee6
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CalCon-Query-Window	  
+# 
+dn: CN=ms-Exch-CalCon-Query-Window,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CalCon-Query-Window
+distinguishedName: CN=ms-Exch-CalCon-Query-Window,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1040
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CalCon-Query-Window
+adminDescription: ms-Exch-CalCon-Query-Window
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCalConQueryWindow
+name: ms-Exch-CalCon-Query-Window
+schemaIDGUID: 5ebb881a-19d4-4526-b6f7-cc46d9aa1869
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CalCon-Refresh-Interval 
+# 
+dn: CN=ms-Exch-CalCon-Refresh-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CalCon-Refresh-Interval
+distinguishedName: CN=ms-Exch-CalCon-Refresh-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1041
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CalCon-Refresh-Interval
+adminDescription: ms-Exch-CalCon-Refresh-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCalConRefreshInterval
+name: ms-Exch-CalCon-Refresh-Interval
+schemaIDGUID: 22bf39b6-7528-412c-b277-aa268db43960
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CalCon-Target-SiteDN	  
+# 
+dn: CN=ms-Exch-CalCon-Target-SiteDN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CalCon-Target-SiteDN
+distinguishedName: CN=ms-Exch-CalCon-Target-SiteDN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1044
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CalCon-Target-SiteDN
+adminDescription: ms-Exch-CalCon-Target-SiteDN
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCalConTargetSiteDN
+name: ms-Exch-CalCon-Target-SiteDN
+schemaIDGUID: 33b45526-8e8b-4679-97c3-4eeff39c7fbd
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Can-Preserve-DNs	  
+# 
+dn: CN=ms-Exch-Can-Preserve-DNs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Can-Preserve-DNs
+distinguishedName: CN=ms-Exch-Can-Preserve-DNs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.455
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32864
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Can-Preserve-DNs
+adminDescription: ms-Exch-Can-Preserve-DNs
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: canPreserveDNs
+name: ms-Exch-Can-Preserve-DNs
+schemaIDGUID: a8df73a9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Catalog		  
+# The globally unique identifier (GUID) of the catalog for this message
+# database (MDB).
+#
+dn: CN=ms-Exch-Catalog,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Catalog
+distinguishedName: CN=ms-Exch-Catalog,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11052
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Catalog
+adminDescription: ms-Exch-Catalog
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchCatalog
+name: ms-Exch-Catalog
+schemaIDGUID: 94abaa48-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-CA-Schema-Policy    
+# A link to a schema policy that this certification authority (CA)
+# uses.
+#
+dn: CN=ms-Exch-CA-Schema-Policy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CA-Schema-Policy
+distinguishedName: CN=ms-Exch-CA-Schema-Policy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.56
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1006
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CA-Schema-Policy
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-CA-Schema-Policy
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchCASchemaPolicy
+name: ms-Exch-CA-Schema-Policy
+schemaIDGUID: 948f0e10-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ccMail-ADE-Prop   
+# Allows the Automatic Directory Exchange (ADE) to propagate
+# synchronized entries to downstream cc:Mail post offices.
+#
+dn: CN=ms-Exch-ccMail-ADE-Prop,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-ADE-Prop
+distinguishedName: CN=ms-Exch-ccMail-ADE-Prop,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1036
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-ADE-Prop
+adminDescription: ms-Exch-ccMail-ADE-Prop
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchccMailADEProp
+name: ms-Exch-ccMail-ADE-Prop
+schemaIDGUID: 94caa8da-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ccMail-Connect-As-Password  
+#
+dn: CN=ms-Exch-ccMail-Connect-As-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-Connect-As-Password
+distinguishedName: CN=ms-Exch-ccMail-Connect-As-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1207
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-Connect-As-Password
+adminDescription: ms-Exch-ccMail-Connect-As-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchccMailConnectAsPassword
+name: ms-Exch-ccMail-Connect-As-Password
+schemaIDGUID: b8d47e43-4b78-11d3-aa75-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ccMail-Connect-As-Userid 
+#
+dn: CN=ms-Exch-ccMail-Connect-As-Userid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-Connect-As-Userid
+distinguishedName: CN=ms-Exch-ccMail-Connect-As-Userid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1206
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-Connect-As-Userid
+adminDescription: ms-Exch-ccMail-Connect-As-Userid
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchccMailConnectAsUserid
+name: ms-Exch-ccMail-Connect-As-Userid
+schemaIDGUID: b8d47e3c-4b78-11d3-aa75-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ccMail-Password     
+# The Administrator password to the cc:Mail post office.
+#
+dn: CN=ms-Exch-ccMail-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-Password
+distinguishedName: CN=ms-Exch-ccMail-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1039
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-Password
+adminDescription: ms-Exch-ccMail-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchccMailPassword
+name: ms-Exch-ccMail-Password
+schemaIDGUID: 4634194c-4a93-11d3-aa73-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ccMail-PO-Name  
+# The name of the cc:Mail post office where the connector exports and
+# imports mail.
+#
+dn: CN=ms-Exch-ccMail-PO-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-PO-Name
+distinguishedName: CN=ms-Exch-ccMail-PO-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1031
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-PO-Name
+adminDescription: ms-Exch-ccMail-PO-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchccMailPOName
+name: ms-Exch-ccMail-PO-Name
+schemaIDGUID: 95633f5a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ccMail-PO-Path    
+# The file path to the cc:Mail post office.
+#
+dn: CN=ms-Exch-ccMail-PO-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ccMail-PO-Path
+distinguishedName: CN=ms-Exch-ccMail-PO-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1033
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ccMail-PO-Path
+adminDescription: ms-Exch-ccMail-PO-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchccMailPOPath
+name: ms-Exch-ccMail-PO-Path
+schemaIDGUID: 98ed3cf2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Certificate	  
+# Reserved.
+#
+dn: CN=ms-Exch-Certificate,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Certificate
+distinguishedName: CN=ms-Exch-Certificate,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9012
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Certificate
+adminDescription: ms-Exch-Certificate
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCertificate
+name: ms-Exch-Certificate
+schemaIDGUID: 98ce3e60-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Certificate-Chain-V3	
+#
+dn: CN=ms-Exch-Certificate-Chain-V3,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Certificate-Chain-V3
+distinguishedName: CN=ms-Exch-Certificate-Chain-V3,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.562
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 35879
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Certificate-Chain-V3
+adminDescription: ms-Exch-Certificate-Chain-V3
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: certificateChainV3
+name: ms-Exch-Certificate-Chain-V3
+schemaIDGUID: a8df73aa-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Certificate-Revocation-List-V1 
+# 
+dn: CN=ms-Exch-Certificate-Revocation-List-V1,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Certificate-Revocation-List-V1
+distinguishedName: CN=ms-Exch-Certificate-Revocation-List-V1,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.564
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 35881
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Certificate-Revocation-List-V1
+adminDescription: ms-Exch-Certificate-Revocation-List-V1
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: certificateRevocationListV1
+name: ms-Exch-Certificate-Revocation-List-V1
+schemaIDGUID: a8df73ab-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Certificate-Revocation-List-V3 
+#
+dn: CN=ms-Exch-Certificate-Revocation-List-V3,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Certificate-Revocation-List-V3
+distinguishedName: CN=ms-Exch-Certificate-Revocation-List-V3,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.563
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 35880
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Certificate-Revocation-List-V3
+adminDescription: ms-Exch-Certificate-Revocation-List-V3
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: certificateRevocationListV3
+name: ms-Exch-Certificate-Revocation-List-V3
+schemaIDGUID: a8df73ac-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Character-Set	       
+# The Multipurpose Internet Mail Extensions (MIME) tag of the
+# character set used by the client.
+#
+dn: CN=ms-Exch-Character-Set,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Character-Set
+distinguishedName: CN=ms-Exch-Character-Set,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.480
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 33157
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Character-Set
+adminDescription: ms-Exch-Character-Set
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: characterSet
+name: ms-Exch-Character-Set
+schemaIDGUID: a8df73ad-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Character-Set-List
+#
+dn: CN=ms-Exch-Character-Set-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Character-Set-List
+distinguishedName: CN=ms-Exch-Character-Set-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.477
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33154
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Character-Set-List
+adminDescription: ms-Exch-Character-Set-List
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: characterSetList
+name: ms-Exch-Character-Set-List
+schemaIDGUID: a8df73ae-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Access
+# An ACL string representing security on this object.
+#
+dn: CN=ms-Exch-Chat-Access,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Access
+distinguishedName: CN=ms-Exch-Chat-Access,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8044
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Access
+adminDescription: ms-Exch-Chat-Access
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatAccess
+name: ms-Exch-Chat-Access
+schemaIDGUID: 8cac5ed6-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Admin-Message   
+# The message that will be displayed to Chat administrators.
+#
+dn: CN=ms-Exch-Chat-Admin-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Admin-Message
+distinguishedName: CN=ms-Exch-Chat-Admin-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8003
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Admin-Message
+adminDescription: ms-Exch-Chat-Admin-Message
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatAdminMessage
+name: ms-Exch-Chat-Admin-Message
+schemaIDGUID: 98af3fce-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Ban-Mask	   
+# The mask determines the scope of the ban.
+#
+dn: CN=ms-Exch-Chat-Ban-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Ban-Mask
+distinguishedName: CN=ms-Exch-Chat-Ban-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8040
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Ban-Mask
+adminDescription: ms-Exch-Chat-Ban-Mask
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatBanMask
+name: ms-Exch-Chat-Ban-Mask
+schemaIDGUID: 9890413c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Ban-Reason    
+# The reason for the ban is sent to the banned user when a connection
+# is attempted.
+#
+dn: CN=ms-Exch-Chat-Ban-Reason,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Ban-Reason
+distinguishedName: CN=ms-Exch-Chat-Ban-Reason,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8043
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Ban-Reason
+adminDescription: ms-Exch-Chat-Ban-Reason
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatBanReason
+name: ms-Exch-Chat-Ban-Reason
+schemaIDGUID: 959c77ca-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Broadcast-Address     
+#
+dn: CN=ms-Exch-Chat-Broadcast-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Broadcast-Address
+distinguishedName: CN=ms-Exch-Chat-Broadcast-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8009
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Broadcast-Address
+adminDescription: ms-Exch-Chat-Broadcast-Address
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatBroadcastAddress
+name: ms-Exch-Chat-Broadcast-Address
+schemaIDGUID: 95b91402-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Channel-Auto-Create   
+# Determines if the registered channel will be started automatically
+# when the service loads.
+#
+dn: CN=ms-Exch-Chat-Channel-Auto-Create,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Auto-Create
+distinguishedName: CN=ms-Exch-Chat-Channel-Auto-Create,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8020
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Auto-Create
+adminDescription: ms-Exch-Chat-Channel-Auto-Create
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelAutoCreate
+name: ms-Exch-Chat-Channel-Auto-Create
+schemaIDGUID: 95d81294-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Flags 
+# Flags that determine the IRC/IRCX modes of the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Flags
+distinguishedName: CN=ms-Exch-Chat-Channel-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8026
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Flags
+adminDescription: ms-Exch-Chat-Channel-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelFlags
+name: ms-Exch-Chat-Channel-Flags
+schemaIDGUID: 95f4aecc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Host-Key	
+# The keyword used by a host to access a restricted channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Host-Key,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Host-Key
+distinguishedName: CN=ms-Exch-Chat-Channel-Host-Key,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8023
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Host-Key
+adminDescription: ms-Exch-Chat-Channel-Host-Key
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelHostKey
+name: ms-Exch-Chat-Channel-Host-Key
+schemaIDGUID: 96114b04-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Join-Message	  
+# The message sent to users when they join the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Join-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Join-Message
+distinguishedName: CN=ms-Exch-Chat-Channel-Join-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8030
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Join-Message
+adminDescription: ms-Exch-Chat-Channel-Join-Message
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelJoinMessage
+name: ms-Exch-Chat-Channel-Join-Message
+schemaIDGUID: 962de73c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Key  
+# The keyword used by a user to access a restricted channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Key,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Key
+distinguishedName: CN=ms-Exch-Chat-Channel-Key,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8021
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Key
+adminDescription: ms-Exch-Chat-Channel-Key
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelKey
+name: ms-Exch-Chat-Channel-Key
+schemaIDGUID: 964a8374-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Language		  
+# The language used in a channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Language,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Language
+distinguishedName: CN=ms-Exch-Chat-Channel-Language,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8028
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Language
+adminDescription: ms-Exch-Chat-Channel-Language
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelLanguage
+name: ms-Exch-Chat-Channel-Language
+schemaIDGUID: 96671fac-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-LCID	
+#
+dn: CN=ms-Exch-Chat-Channel-LCID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-LCID
+distinguishedName: CN=ms-Exch-Chat-Channel-LCID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8029
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-LCID
+adminDescription: ms-Exch-Chat-Channel-LCID
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelLCID
+name: ms-Exch-Chat-Channel-LCID
+schemaIDGUID: 9683bbe4-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Channel-Limit	
+# The number of users allowed to join this channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Limit
+distinguishedName: CN=ms-Exch-Chat-Channel-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8010
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Limit
+adminDescription: ms-Exch-Chat-Channel-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelLimit
+name: ms-Exch-Chat-Channel-Limit
+schemaIDGUID: 96a0581c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Mode 
+# The modes of a channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Mode
+distinguishedName: CN=ms-Exch-Chat-Channel-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Mode
+adminDescription: ms-Exch-Chat-Channel-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelMode
+name: ms-Exch-Chat-Channel-Mode
+schemaIDGUID: 96ba91fa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Name	
+# The IRC/IRCX style name of the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Name
+distinguishedName: CN=ms-Exch-Chat-Channel-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8019
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Name
+adminDescription: ms-Exch-Chat-Channel-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelName
+name: ms-Exch-Chat-Channel-Name
+schemaIDGUID: 96d72e32-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Channel-Owner-Key	
+# The keyword used by an owner to access a restricted channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Owner-Key,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Owner-Key
+distinguishedName: CN=ms-Exch-Chat-Channel-Owner-Key,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8022
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Owner-Key
+adminDescription: ms-Exch-Chat-Channel-Owner-Key
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelOwnerKey
+name: ms-Exch-Chat-Channel-Owner-Key
+schemaIDGUID: 96f3ca6a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Part-Message	    
+# The message sent to a user when they leave the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Part-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Part-Message
+distinguishedName: CN=ms-Exch-Chat-Channel-Part-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8031
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Part-Message
+adminDescription: ms-Exch-Chat-Channel-Part-Message
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelPartMessage
+name: ms-Exch-Chat-Channel-Part-Message
+schemaIDGUID: 9712c8fc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-PICS  
+# The Platform for Internet Content Selection (PICS) rating for the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-PICS,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-PICS
+distinguishedName: CN=ms-Exch-Chat-Channel-PICS,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8027
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-PICS
+adminDescription: ms-Exch-Chat-Channel-PICS
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelPICS
+name: ms-Exch-Chat-Channel-PICS
+schemaIDGUID: 972d02da-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Subject	    
+# The subject of the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Subject,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Subject
+distinguishedName: CN=ms-Exch-Chat-Channel-Subject,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8025
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Subject
+adminDescription: ms-Exch-Chat-Channel-Subject
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelSubject
+name: ms-Exch-Chat-Channel-Subject
+schemaIDGUID: 97499f12-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Channel-Topic	
+# The topic of the channel.
+#
+dn: CN=ms-Exch-Chat-Channel-Topic,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Channel-Topic
+distinguishedName: CN=ms-Exch-Chat-Channel-Topic,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8024
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Channel-Topic
+adminDescription: ms-Exch-Chat-Channel-Topic
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatChannelTopic
+name: ms-Exch-Chat-Channel-Topic
+schemaIDGUID: 97663b4a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Class-Ident-Mask
+# Determines the scope of the Chat
+# class. ms-Exch-Chat-Class-Scope-Type Attribute determines if this
+# property is used, or if the Internet Protocol (IP)
+# ms-Exch-Chat-Class-IP Attribute property is used to scope the class.
+#
+dn: CN=ms-Exch-Chat-Class-Ident-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Class-Ident-Mask
+distinguishedName: CN=ms-Exch-Chat-Class-Ident-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8032
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Class-Ident-Mask
+adminDescription: ms-Exch-Chat-Class-Ident-Mask
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatClassIdentMask
+name: ms-Exch-Chat-Class-Ident-Mask
+schemaIDGUID: 9782d782-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Class-IP	 
+# Determines the scope of the Chat class specified by an IP
+# address. ms-Exch-Chat-Class-Scope-Type Attribute determines if this
+# property is used, or if the IP ms-Exch-Chat-Class-Ident-Mask
+# Attribute property is used to scope the class.
+#
+dn: CN=ms-Exch-Chat-Class-IP,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Class-IP
+distinguishedName: CN=ms-Exch-Chat-Class-IP,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8033
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Class-IP
+adminDescription: ms-Exch-Chat-Class-IP
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatClassIP
+name: ms-Exch-Chat-Class-IP
+schemaIDGUID: 97a1d614-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Class-Restrictions	 
+# The Chat user class restrictions.
+#
+dn: CN=ms-Exch-Chat-Class-Restrictions,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Class-Restrictions
+distinguishedName: CN=ms-Exch-Chat-Class-Restrictions,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8046
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Class-Restrictions
+adminDescription: ms-Exch-Chat-Class-Restrictions
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatClassRestrictions
+name: ms-Exch-Chat-Class-Restrictions
+schemaIDGUID: 8090a000-1234-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Class-Scope-Type	
+# The Chat user class identification scope type.
+#
+dn: CN=ms-Exch-Chat-Class-Scope-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Class-Scope-Type
+distinguishedName: CN=ms-Exch-Chat-Class-Scope-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8047
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Class-Scope-Type
+adminDescription: ms-Exch-Chat-Class-Scope-Type
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchChatClassScopeType
+name: ms-Exch-Chat-Class-Scope-Type
+schemaIDGUID: 8090a006-1234-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Client-Port 
+#
+dn: CN=ms-Exch-Chat-Client-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Client-Port
+distinguishedName: CN=ms-Exch-Chat-Client-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8007
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Client-Port
+adminDescription: ms-Exch-Chat-Client-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatClientPort
+name: ms-Exch-Chat-Client-Port
+schemaIDGUID: 97be724c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-DNS-Reverse-Mode	    
+# Determines whether Domain Name System (DNS) reverse lookups are
+# performed on incoming client connections.
+#
+dn: CN=ms-Exch-Chat-DNS-Reverse-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-DNS-Reverse-Mode
+distinguishedName: CN=ms-Exch-Chat-DNS-Reverse-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8013
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-DNS-Reverse-Mode
+adminDescription: ms-Exch-Chat-DNS-Reverse-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatDNSReverseMode
+name: ms-Exch-Chat-DNS-Reverse-Mode
+schemaIDGUID: 97db0e84-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Duration
+# The amount of time this item is active starting from the value of
+# ms-Exch-Chat-Start-Time Attribute.
+#
+dn: CN=ms-Exch-Chat-Duration,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Duration
+distinguishedName: CN=ms-Exch-Chat-Duration,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8042
+attributeSyntax: 2.5.5.16
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Duration
+adminDescription: ms-Exch-Chat-Duration
+oMSyntax: 65
+searchFlags: 0
+lDAPDisplayName: msExchChatDuration
+name: ms-Exch-Chat-Duration
+schemaIDGUID: 97fa0d16-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Enable-Anonymous		
+# Determines whether anonymous client connections are allowed to this
+# Chat co to this Chat community.
+#
+dn: CN=ms-Exch-Chat-Enable-Anonymous,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Enable-Anonymous
+distinguishedName: CN=ms-Exch-Chat-Enable-Anonymous,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8011
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Enable-Anonymous
+adminDescription: ms-Exch-Chat-Enable-Anonymous
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchChatEnableAnonymous
+name: ms-Exch-Chat-Enable-Anonymous
+schemaIDGUID: 98190ba8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Extensions   
+# A multivalued list of the Chat service extensions for this Chat
+# community on this server.
+#
+dn: CN=ms-Exch-Chat-Extensions,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Extensions
+distinguishedName: CN=ms-Exch-Chat-Extensions,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8048
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Extensions
+adminDescription: ms-Exch-Chat-Extensions
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatExtensions
+name: ms-Exch-Chat-Extensions
+schemaIDGUID: 3b9d8de5-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Input-Flood-Limit	  
+# Determines the maximum acceptable message rate allowed by the Chat
+# server from clients.
+#
+dn: CN=ms-Exch-Chat-Input-Flood-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Input-Flood-Limit
+distinguishedName: CN=ms-Exch-Chat-Input-Flood-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8038
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Input-Flood-Limit
+adminDescription: ms-Exch-Chat-Input-Flood-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatInputFloodLimit
+name: ms-Exch-Chat-Input-Flood-Limit
+schemaIDGUID: 987142aa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Max-Anonymous	  
+# The maximum anonymous client connections that are allowed.
+#
+dn: CN=ms-Exch-Chat-Max-Anonymous,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Max-Anonymous
+distinguishedName: CN=ms-Exch-Chat-Max-Anonymous,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8015
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Max-Anonymous
+adminDescription: ms-Exch-Chat-Max-Anonymous
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMaxAnonymous
+name: ms-Exch-Chat-Max-Anonymous
+schemaIDGUID: 9969373a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Max-Connections	 
+# The maximum number of client connections allowed.
+#
+dn: CN=ms-Exch-Chat-Max-Connections,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Max-Connections
+distinguishedName: CN=ms-Exch-Chat-Max-Connections,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8014
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Max-Connections
+adminDescription: ms-Exch-Chat-Max-Connections
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMaxConnections
+name: ms-Exch-Chat-Max-Connections
+schemaIDGUID: 9985d372-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Max-Connections-Per-IP	
+# 
+dn: CN=ms-Exch-Chat-Max-Connections-Per-IP,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Max-Connections-Per-IP
+distinguishedName: CN=ms-Exch-Chat-Max-Connections-Per-IP,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8049
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Max-Connections-Per-IP
+adminDescription: ms-Exch-Chat-Max-Connections-Per-IP
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMaxConnectionsPerIP
+name: ms-Exch-Chat-Max-Connections-Per-IP
+schemaIDGUID: 2ac57e6b-f737-4e41-8386-7295ddbe05e6
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Max-Memberships		
+# The maximum number of channels that a Chat client may join at one
+# time.
+#
+dn: CN=ms-Exch-Chat-Max-Memberships,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Max-Memberships
+distinguishedName: CN=ms-Exch-Chat-Max-Memberships,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Max-Memberships
+adminDescription: ms-Exch-Chat-Max-Memberships
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMaxMemberships
+name: ms-Exch-Chat-Max-Memberships
+schemaIDGUID: 99a4d204-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Max-Octets-To-Mask  
+#
+dn: CN=ms-Exch-Chat-Max-Octets-To-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Max-Octets-To-Mask
+distinguishedName: CN=ms-Exch-Chat-Max-Octets-To-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8050
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Max-Octets-To-Mask
+adminDescription: ms-Exch-Chat-Max-Octets-To-Mask
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMaxOctetsToMask
+name: ms-Exch-Chat-Max-Octets-To-Mask
+schemaIDGUID: 3de37b23-2789-4df7-b51f-f920ce544458
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Message-Lag	   
+# The amount of lag imparted to all messages to prevent flooding.
+#
+dn: CN=ms-Exch-Chat-Message-Lag,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Message-Lag
+distinguishedName: CN=ms-Exch-Chat-Message-Lag,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8034
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Message-Lag
+adminDescription: ms-Exch-Chat-Message-Lag
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatMessageLag
+name: ms-Exch-Chat-Message-Lag
+schemaIDGUID: 99e2cf28-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-MOTD   
+# The message sent to users when they connect to a Chat community.
+#
+dn: CN=ms-Exch-Chat-MOTD,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-MOTD
+distinguishedName: CN=ms-Exch-Chat-MOTD,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8004
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-MOTD
+adminDescription: ms-Exch-Chat-MOTD
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatMOTD
+name: ms-Exch-Chat-MOTD
+schemaIDGUID: 99ff6b60-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Network-Mode 
+# The Chat network settings for channel creation and defaults.
+#
+dn: CN=ms-Exch-Chat-Network-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Network-Mode
+distinguishedName: CN=ms-Exch-Chat-Network-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8045
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Network-Mode
+adminDescription: ms-Exch-Chat-Network-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatNetworkMode
+name: ms-Exch-Chat-Network-Mode
+schemaIDGUID: 917cfe98-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Network-Name   
+#
+dn: CN=ms-Exch-Chat-Network-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Network-Name
+distinguishedName: CN=ms-Exch-Chat-Network-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8001
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Network-Name
+adminDescription: ms-Exch-Chat-Network-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatNetworkName
+name: ms-Exch-Chat-Network-Name
+schemaIDGUID: 9a1e69f2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Nick-Delay     
+# The amount of delay imparted on a user between changing
+# nicknames. Used for flood control.
+#
+dn: CN=ms-Exch-Chat-Nick-Delay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Nick-Delay
+distinguishedName: CN=ms-Exch-Chat-Nick-Delay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8036
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Nick-Delay
+adminDescription: ms-Exch-Chat-Nick-Delay
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatNickDelay
+name: ms-Exch-Chat-Nick-Delay
+schemaIDGUID: 9a3d6884-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Output-Saturation       
+# The maximum level of buffering allowed before a client connection is
+# terminated.
+#
+dn: CN=ms-Exch-Chat-Output-Saturation,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Output-Saturation
+distinguishedName: CN=ms-Exch-Chat-Output-Saturation,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8039
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Output-Saturation
+adminDescription: ms-Exch-Chat-Output-Saturation
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatOutputSaturation
+name: ms-Exch-Chat-Output-Saturation
+schemaIDGUID: 9a5c6716-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Ping-Delay      
+# The frequency of keep-alive pings from the Chat server.
+#
+dn: CN=ms-Exch-Chat-Ping-Delay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Ping-Delay
+distinguishedName: CN=ms-Exch-Chat-Ping-Delay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8037
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Ping-Delay
+adminDescription: ms-Exch-Chat-Ping-Delay
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatPingDelay
+name: ms-Exch-Chat-Ping-Delay
+schemaIDGUID: 9a7b65a8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Protection-Level	   
+# The general attack protection level used by the Chat server.
+#
+dn: CN=ms-Exch-Chat-Protection-Level,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Protection-Level
+distinguishedName: CN=ms-Exch-Chat-Protection-Level,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8035
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Protection-Level
+adminDescription: ms-Exch-Chat-Protection-Level
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatProtectionLevel
+name: ms-Exch-Chat-Protection-Level
+schemaIDGUID: 9a9a643a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Server-Port  
+#
+dn: CN=ms-Exch-Chat-Server-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Server-Port
+distinguishedName: CN=ms-Exch-Chat-Server-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8008
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Server-Port
+adminDescription: ms-Exch-Chat-Server-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchChatServerPort
+name: ms-Exch-Chat-Server-Port
+schemaIDGUID: 9ab70072-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Chat-Start-Time   
+# The time at which this item becomes active. The duration for which
+# it is active is determined by the value of ms-Exch-Chat-Duration
+# Attribute.
+#
+dn: CN=ms-Exch-Chat-Start-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Start-Time
+distinguishedName: CN=ms-Exch-Chat-Start-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8041
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Start-Time
+adminDescription: ms-Exch-Chat-Start-Time
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: msExchChatStartTime
+name: ms-Exch-Chat-Start-Time
+schemaIDGUID: 9ad39caa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Chat-Title	    
+# A description of the Chat community displayed to users when they
+# connect.
+#
+dn: CN=ms-Exch-Chat-Title,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Chat-Title
+distinguishedName: CN=ms-Exch-Chat-Title,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8002
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Chat-Title
+adminDescription: ms-Exch-Chat-Title
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchChatTitle
+name: ms-Exch-Chat-Title
+schemaIDGUID: 9af29b3c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Child-Sync-Agreements	      
+# A backlink to the connection agreements from the service.
+#
+dn: CN=ms-Exch-Child-Sync-Agreements,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Child-Sync-Agreements
+distinguishedName: CN=ms-Exch-Child-Sync-Agreements,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.37
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 147
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Child-Sync-Agreements
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Child-Sync-Agreements
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchChildSyncAgreements
+name: ms-Exch-Child-Sync-Agreements
+schemaIDGUID: 9b309860-b093-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CI-Available		
+#
+dn: CN=ms-Exch-CI-Available,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Available
+distinguishedName: CN=ms-Exch-CI-Available,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11066
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Available
+adminDescription: ms-Exch-CI-Available
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchCIAvailable
+name: ms-Exch-CI-Available
+schemaIDGUID: 035da50e-1a9e-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CI-Location		
+# Stores the location of the index.
+#
+dn: CN=ms-Exch-CI-Location,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Location
+distinguishedName: CN=ms-Exch-CI-Location,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11068
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Location
+adminDescription: ms-Exch-CI-Location
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCILocation
+name: ms-Exch-CI-Location
+schemaIDGUID: cec44725-22ae-11d3-aa62-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CI-Rebuild-Schedule	
+#
+dn: CN=ms-Exch-CI-Rebuild-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Rebuild-Schedule
+distinguishedName: CN=ms-Exch-CI-Rebuild-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11063
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Rebuild-Schedule
+adminDescription: ms-Exch-CI-Rebuild-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchCIRebuildSchedule
+name: ms-Exch-CI-Rebuild-Schedule
+schemaIDGUID: 035da4fd-1a9e-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-CI-Rebuild-Style	
+#
+dn: CN=ms-Exch-CI-Rebuild-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Rebuild-Style
+distinguishedName: CN=ms-Exch-CI-Rebuild-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11065
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Rebuild-Style
+adminDescription: ms-Exch-CI-Rebuild-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCIRebuildStyle
+name: ms-Exch-CI-Rebuild-Style
+schemaIDGUID: 035da507-1a9e-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-CI-Update-Schedule	
+#
+dn: CN=ms-Exch-CI-Update-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Update-Schedule
+distinguishedName: CN=ms-Exch-CI-Update-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11062
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Update-Schedule
+adminDescription: ms-Exch-CI-Update-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchCIUpdateSchedule
+name: ms-Exch-CI-Update-Schedule
+schemaIDGUID: 035da4f8-1a9e-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-CI-Update-Style	
+#
+dn: CN=ms-Exch-CI-Update-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CI-Update-Style
+distinguishedName: CN=ms-Exch-CI-Update-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11064
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CI-Update-Style
+adminDescription: ms-Exch-CI-Update-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCIUpdateStyle
+name: ms-Exch-CI-Update-Style
+schemaIDGUID: 035da502-1a9e-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Client-Access-Enabled	
+#
+dn: CN=ms-Exch-Client-Access-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Client-Access-Enabled
+distinguishedName: CN=ms-Exch-Client-Access-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.559
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35876
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Client-Access-Enabled
+adminDescription: ms-Exch-Client-Access-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: clientAccessEnabled
+name: ms-Exch-Client-Access-Enabled
+schemaIDGUID: a8df73af-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Clock-Alert-Offset	
+#
+dn: CN=ms-Exch-Clock-Alert-Offset,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Clock-Alert-Offset
+distinguishedName: CN=ms-Exch-Clock-Alert-Offset,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.165
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32865
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Clock-Alert-Offset
+adminDescription: ms-Exch-Clock-Alert-Offset
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: clockAlertOffset
+name: ms-Exch-Clock-Alert-Offset
+schemaIDGUID: a8df73b0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Clock-Alert-Repair	
+#
+dn: CN=ms-Exch-Clock-Alert-Repair,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Clock-Alert-Repair
+distinguishedName: CN=ms-Exch-Clock-Alert-Repair,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.164
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32866
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Clock-Alert-Repair
+adminDescription: ms-Exch-Clock-Alert-Repair
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: clockAlertRepair
+name: ms-Exch-Clock-Alert-Repair
+schemaIDGUID: a8df73b1-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Clock-Warning-Offset	
+#
+dn: CN=ms-Exch-Clock-Warning-Offset,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Clock-Warning-Offset
+distinguishedName: CN=ms-Exch-Clock-Warning-Offset,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.177
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32867
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Clock-Warning-Offset
+adminDescription: ms-Exch-Clock-Warning-Offset
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: clockWarningOffset
+name: ms-Exch-Clock-Warning-Offset
+schemaIDGUID: a8df73b2-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Clock-Warning-Repair	
+#
+dn: CN=ms-Exch-Clock-Warning-Repair,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Clock-Warning-Repair
+distinguishedName: CN=ms-Exch-Clock-Warning-Repair,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.166
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32868
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Clock-Warning-Repair
+adminDescription: ms-Exch-Clock-Warning-Repair
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: clockWarningRepair
+name: ms-Exch-Clock-Warning-Repair
+schemaIDGUID: a8df73b3-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Compromised-Key-List	
+#
+dn: CN=ms-Exch-Compromised-Key-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Compromised-Key-List
+distinguishedName: CN=ms-Exch-Compromised-Key-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.542
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 33220
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Compromised-Key-List
+adminDescription: ms-Exch-Compromised-Key-List
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: compromisedKeyList
+name: ms-Exch-Compromised-Key-List
+schemaIDGUID: 167757a9-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Computer-Link		
+# A link from the computer to the Exchange server.
+#
+dn: CN=ms-Exch-Computer-Link,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Computer-Link
+distinguishedName: CN=ms-Exch-Computer-Link,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.72
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1018
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Computer-Link
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Computer-Link
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchComputerLink
+name: ms-Exch-Computer-Link
+schemaIDGUID: 8a5852f2-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Computer-Name	
+#
+dn: CN=ms-Exch-Computer-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Computer-Name
+distinguishedName: CN=ms-Exch-Computer-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.20
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 32869
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Computer-Name
+adminDescription: ms-Exch-Computer-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: computerName
+name: ms-Exch-Computer-Name
+schemaIDGUID: a8df73b4-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Conference-Mailbox	 
+# The forward link to the Exchange Conferencing Service conference
+# calendar mailbox.
+#
+dn: CN=ms-Exch-Conference-Mailbox,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Conference-Mailbox
+distinguishedName: CN=ms-Exch-Conference-Mailbox,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9029
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1036
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Mailbox
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Conference-Mailbox
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchConferenceMailbox
+name: ms-Exch-Conference-Mailbox
+schemaIDGUID: 628f0513-88f6-4cef-9de4-b367eb7e8383
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Conference-Mailbox-BL	      
+# The backlink to the Exchange Conferencing Service conference
+# calendar mailbox.
+#
+dn: CN=ms-Exch-Conference-Mailbox-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Conference-Mailbox-BL
+distinguishedName: CN=ms-Exch-Conference-Mailbox-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9030
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1037
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Mailbox-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Conference-Mailbox-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchConferenceMailboxBL
+name: ms-Exch-Conference-Mailbox-BL
+schemaIDGUID: 9423ec2c-383b-44b2-8913-ab79ac609bd4
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Conference-Zone	  
+# The Exchange Conferencing Service site forward link.
+#
+dn: CN=ms-Exch-Conference-Zone,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Conference-Zone
+distinguishedName: CN=ms-Exch-Conference-Zone,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9015
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1020
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Zone
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Conference-Zone
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchConferenceZone
+name: ms-Exch-Conference-Zone
+schemaIDGUID: 8cfd6eca-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Conference-Zone-BL   
+# The Exchange Conferencing Service site backlink.
+#
+dn: CN=ms-Exch-Conference-Zone-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Conference-Zone-BL
+distinguishedName: CN=ms-Exch-Conference-Zone-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9024
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1021
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Conference-Zone-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Conference-Zone-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchConferenceZoneBL
+name: ms-Exch-Conference-Zone-BL
+schemaIDGUID: 8d1a0b02-b09e-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Connected-Domains    
+# The sites or AGs that are connected using this connector.
+#
+dn: CN=ms-Exch-Connected-Domains,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Connected-Domains
+distinguishedName: CN=ms-Exch-Connected-Domains,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.211
+attributeSyntax: 2.5.5.4
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1243
+mAPIID: 32870
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connected-Domains
+adminDescription: ms-Exch-Connected-Domains
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: connectedDomains
+name: ms-Exch-Connected-Domains
+schemaIDGUID: a8df73b5-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Connection-List-Filter  
+#
+dn: CN=ms-Exch-Connection-List-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Connection-List-Filter
+distinguishedName: CN=ms-Exch-Connection-List-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.475
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 10240
+mAPIID: 33152
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connection-List-Filter
+adminDescription: ms-Exch-Connection-List-Filter
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: connectionListFilter
+name: ms-Exch-Connection-List-Filter
+schemaIDGUID: a8df73b6-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Connection-List-Filter-Type 
+#
+dn: CN=ms-Exch-Connection-List-Filter-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Connection-List-Filter-Type
+distinguishedName: CN=ms-Exch-Connection-List-Filter-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.526
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33204
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connection-List-Filter-Type
+adminDescription: ms-Exch-Connection-List-Filter-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: connectionListFilterType
+name: ms-Exch-Connection-List-Filter-Type
+schemaIDGUID: a8df73b7-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Connector-Type    
+# The type of Exchange connector.
+#
+dn: CN=ms-Exch-Connector-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Connector-Type
+distinguishedName: CN=ms-Exch-Connector-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12508
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 255
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Connector-Type
+adminDescription: ms-Exch-Connector-Type
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchConnectorType
+name: ms-Exch-Connector-Type
+schemaIDGUID: 9b8d9416-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Container-Info	
+#
+dn: CN=ms-Exch-Container-Info,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Container-Info
+distinguishedName: CN=ms-Exch-Container-Info,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.296
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32871
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Container-Info
+adminDescription: ms-Exch-Container-Info
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: containerInfo
+name: ms-Exch-Container-Info
+schemaIDGUID: bf967942-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Content-Type		
+# Contains information about MIME versus Unix-to-Unix encode
+# (UUENCODE) and Rich Text Format (RTF) for a domain content
+# configuration.  
+#
+dn: CN=ms-Exch-Content-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Content-Type
+distinguishedName: CN=ms-Exch-Content-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.481
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 4
+mAPIID: 33158
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Content-Type
+adminDescription: ms-Exch-Content-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: contentType
+name: ms-Exch-Content-Type
+schemaIDGUID: a8df73b9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Controlling-Zone
+# The forward link to the Exchange Conferencing Service resource
+# mailbox.
+#
+dn: CN=ms-Exch-Controlling-Zone,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Controlling-Zone
+distinguishedName: CN=ms-Exch-Controlling-Zone,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9026
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Controlling-Zone
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Controlling-Zone
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: msExchControllingZone
+name: ms-Exch-Controlling-Zone
+schemaIDGUID: 91462882-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Control-Msg-Folder-ID	      
+#
+dn: CN=ms-Exch-Control-Msg-Folder-ID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Control-Msg-Folder-ID
+distinguishedName: CN=ms-Exch-Control-Msg-Folder-ID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.483
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33160
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Control-Msg-Folder-ID
+adminDescription: ms-Exch-Control-Msg-Folder-ID
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: controlMsgFolderID
+name: ms-Exch-Control-Msg-Folder-ID
+schemaIDGUID: a8df73ba-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Control-Msg-Rules	      
+#
+dn: CN=ms-Exch-Control-Msg-Rules,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Control-Msg-Rules
+distinguishedName: CN=ms-Exch-Control-Msg-Rules,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.485
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32767
+mAPIID: 33162
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Control-Msg-Rules
+adminDescription: ms-Exch-Control-Msg-Rules
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: controlMsgRules
+name: ms-Exch-Control-Msg-Rules
+schemaIDGUID: a8df73bb-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Convert-To-Fixed-Font	      
+# If True, the store configures IMAIL to convert Internet messages to
+# fixed font for RTF clients. The default is False.
+#
+dn: CN=ms-Exch-Convert-To-Fixed-Font,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Convert-To-Fixed-Font
+distinguishedName: CN=ms-Exch-Convert-To-Fixed-Font,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11021
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Convert-To-Fixed-Font
+adminDescription: ms-Exch-Convert-To-Fixed-Font
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchConvertToFixedFont
+name: ms-Exch-Convert-To-Fixed-Font
+schemaIDGUID: 9bac92a8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Correlation-Attribute	       
+# The LDAP display name of the attribute used to correlate
+# entries. This is not used for replication between Exchange and
+# Microsoft® Windows®.
+#
+dn: CN=ms-Exch-Correlation-Attribute,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Correlation-Attribute
+distinguishedName: CN=ms-Exch-Correlation-Attribute,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.43
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Correlation-Attribute
+adminDescription: ms-Exch-Correlation-Attribute
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCorrelationAttribute
+name: ms-Exch-Correlation-Attribute
+schemaIDGUID: 9c098e5e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Cross-Certificate-CRL	    
+#
+dn: CN=ms-Exch-Cross-Certificate-CRL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Cross-Certificate-CRL
+distinguishedName: CN=ms-Exch-Cross-Certificate-CRL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.565
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+mAPIID: 35888
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Cross-Certificate-CRL
+adminDescription: ms-Exch-Cross-Certificate-CRL
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: crossCertificateCRL
+name: ms-Exch-Cross-Certificate-CRL
+schemaIDGUID: a8df73bc-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Class-GUID	    
+# The component implementation GUID for the conference technology
+# provider (CTP).
+#
+dn: CN=ms-Exch-CTP-Class-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Class-GUID
+distinguishedName: CN=ms-Exch-CTP-Class-GUID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9008
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Class-GUID
+adminDescription: ms-Exch-CTP-Class-GUID
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCTPClassGUID
+name: ms-Exch-CTP-Class-GUID
+schemaIDGUID: 9c288cf0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Frame-Hint  
+# The frame hint size.
+#
+dn: CN=ms-Exch-CTP-Frame-Hint,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Frame-Hint
+distinguishedName: CN=ms-Exch-CTP-Frame-Hint,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9010
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Frame-Hint
+adminDescription: ms-Exch-CTP-Frame-Hint
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchCTPFrameHint
+name: ms-Exch-CTP-Frame-Hint
+schemaIDGUID: 9c478b82-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Property-Schema	
+# The CTP property schema. This attribute is obsolete.
+#
+dn: CN=ms-Exch-CTP-Property-Schema,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Property-Schema
+distinguishedName: CN=ms-Exch-CTP-Property-Schema,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9022
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Property-Schema
+adminDescription: ms-Exch-CTP-Property-Schema
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCTPPropertySchema
+name: ms-Exch-CTP-Property-Schema
+schemaIDGUID: 9c6427ba-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Provider-GUID	
+# The CTP GUID.
+#
+dn: CN=ms-Exch-CTP-Provider-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Provider-GUID
+distinguishedName: CN=ms-Exch-CTP-Provider-GUID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9007
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Provider-GUID
+adminDescription: ms-Exch-CTP-Provider-GUID
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCTPProviderGUID
+name: ms-Exch-CTP-Provider-GUID
+schemaIDGUID: 9c8588a6-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Provider-Name	
+# The CTP internal name.
+#
+dn: CN=ms-Exch-CTP-Provider-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Provider-Name
+distinguishedName: CN=ms-Exch-CTP-Provider-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9021
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Provider-Name
+adminDescription: ms-Exch-CTP-Provider-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCTPProviderName
+name: ms-Exch-CTP-Provider-Name
+schemaIDGUID: 9ca48738-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Require-CMS-Authentication	
+# Indicates whether authentication is required to join the selected
+# conference.
+#
+dn: CN=ms-Exch-CTP-Require-CMS-Authentication,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Require-CMS-Authentication
+distinguishedName: CN=ms-Exch-CTP-Require-CMS-Authentication,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9023
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Require-CMS-Authentication
+adminDescription: ms-Exch-CTP-Require-CMS-Authentication
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchCTPRequireCMSAuthentication
+name: ms-Exch-CTP-Require-CMS-Authentication
+schemaIDGUID: 8aa962e6-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-CTP-Snapin-GUID   
+# The Microsoft Management Console (MMC) snap-in implementation GUID
+# for the CTP.  
+#
+dn: CN=ms-Exch-CTP-Snapin-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-CTP-Snapin-GUID
+distinguishedName: CN=ms-Exch-CTP-Snapin-GUID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9009
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-CTP-Snapin-GUID
+adminDescription: ms-Exch-CTP-Snapin-GUID
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCTPSnapinGUID
+name: ms-Exch-CTP-Snapin-GUID
+schemaIDGUID: 9cc385ca-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Custom-Proxy-Addresses
+#
+dn: CN=ms-Exch-Custom-Proxy-Addresses,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Custom-Proxy-Addresses
+distinguishedName: CN=ms-Exch-Custom-Proxy-Addresses,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50049
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Custom-Proxy-Addresses
+adminDescription: ms-Exch-Custom-Proxy-Addresses
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchCustomProxyAddresses
+name: ms-Exch-Custom-Proxy-Addresses
+schemaIDGUID: e24d7a90-439d-11d3-aa72-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Database-Being-Restored  
+# Prevents any mount to the database. This is set during a restore.
+#
+dn: CN=ms-Exch-Database-Being-Restored,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Database-Being-Restored
+distinguishedName: CN=ms-Exch-Database-Being-Restored,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11085
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Database-Being-Restored
+adminDescription: ms-Exch-Database-Being-Restored
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDatabaseBeingRestored
+name: ms-Exch-Database-Being-Restored
+schemaIDGUID: 372fadff-d0b6-4552-8057-f3a0d2c706a7
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Database-Created  
+# Indicates to the store whether or not the database is to be created.
+#
+dn: CN=ms-Exch-Database-Created,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Database-Created
+distinguishedName: CN=ms-Exch-Database-Created,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11084
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Database-Created
+adminDescription: ms-Exch-Database-Created
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDatabaseCreated
+name: ms-Exch-Database-Created
+schemaIDGUID: 14f27149-ba76-4aee-bac8-fced38fdff9d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Database-Session-Addend 
+# The accumulator for sessions.
+#
+dn: CN=ms-Exch-Database-Session-Addend,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Database-Session-Addend
+distinguishedName: CN=ms-Exch-Database-Session-Addend,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11039
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Database-Session-Addend
+adminDescription: ms-Exch-Database-Session-Addend
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDatabaseSessionAddend
+name: ms-Exch-Database-Session-Addend
+schemaIDGUID: 9ce2845c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Database-Session-Increment	
+# Number of Microsoft Jet sessions to allocate when more Jet sessions
+# are needed.  
+#
+dn: CN=ms-Exch-Database-Session-Increment,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Database-Session-Increment
+distinguishedName: CN=ms-Exch-Database-Session-Increment,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11040
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Database-Session-Increment
+adminDescription: ms-Exch-Database-Session-Increment
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDatabaseSessionIncrement
+name: ms-Exch-Database-Session-Increment
+schemaIDGUID: 9d0647a2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Data-Path
+#
+dn: CN=ms-Exch-Data-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Data-Path
+distinguishedName: CN=ms-Exch-Data-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50052
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Data-Path
+adminDescription: ms-Exch-Data-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDataPath
+name: ms-Exch-Data-Path
+schemaIDGUID: 61c47260-454e-11d3-aa72-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Default-Admin-Group  
+# A flag indicating whether this administrator group is the default.
+#
+dn: CN=ms-Exch-Default-Admin-Group,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Default-Admin-Group
+distinguishedName: CN=ms-Exch-Default-Admin-Group,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50015
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Default-Admin-Group
+adminDescription: ms-Exch-Default-Admin-Group
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDefaultAdminGroup
+name: ms-Exch-Default-Admin-Group
+schemaIDGUID: 847584c2-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Default-Domain	     
+# The domain used for basic authentication.
+#
+dn: CN=ms-Exch-Default-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Default-Domain
+distinguishedName: CN=ms-Exch-Default-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2012
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Default-Domain
+adminDescription: ms-Exch-Default-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDefaultDomain
+name: ms-Exch-Default-Domain
+schemaIDGUID: 9d22e3da-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Default-Load-File	
+#
+dn: CN=ms-Exch-Default-Load-File,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Default-Load-File
+distinguishedName: CN=ms-Exch-Default-Load-File,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15010
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Default-Load-File
+adminDescription: ms-Exch-Default-Load-File
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDefaultLoadFile
+name: ms-Exch-Default-Load-File
+schemaIDGUID: 6267667c-cf34-407d-ba11-7cc8cc68ca1b
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Default-Logon-Domain	
+# Specifies the default domain for logon.
+dn: CN=ms-Exch-Default-Logon-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Default-Logon-Domain
+distinguishedName: CN=ms-Exch-Default-Logon-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15001
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Default-Logon-Domain
+adminDescription: ms-Exch-Default-Logon-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDefaultLogonDomain
+name: ms-Exch-Default-Logon-Domain
+schemaIDGUID: 8bb46a46-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Default-Message-Format	
+#
+dn: CN=ms-Exch-Default-Message-Format,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Default-Message-Format
+distinguishedName: CN=ms-Exch-Default-Message-Format,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.572
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35895
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Default-Message-Format
+adminDescription: ms-Exch-Default-Message-Format
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: defaultMessageFormat
+name: ms-Exch-Default-Message-Format
+schemaIDGUID: a8df73bd-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Delegate-User			
+#
+dn: CN=ms-Exch-Delegate-User,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Delegate-User
+distinguishedName: CN=ms-Exch-Delegate-User,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.591
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35913
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Delegate-User
+adminDescription: ms-Exch-Delegate-User
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: delegateUser
+name: ms-Exch-Delegate-User
+schemaIDGUID: a8df73be-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Deleted-Item-Flags		
+# Controls deleted item retention settings.
+#
+dn: CN=ms-Exch-Deleted-Item-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Deleted-Item-Flags
+distinguishedName: CN=ms-Exch-Deleted-Item-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.106
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32898
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Deleted-Item-Flags
+adminDescription: ms-Exch-Deleted-Item-Flags
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: deletedItemFlags
+name: ms-Exch-Deleted-Item-Flags
+schemaIDGUID: 167757c7-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Delivery-Mechanism	
+#
+dn: CN=ms-Exch-Delivery-Mechanism,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Delivery-Mechanism
+distinguishedName: CN=ms-Exch-Delivery-Mechanism,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.241
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32878
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Delivery-Mechanism
+adminDescription: ms-Exch-Delivery-Mechanism
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: deliveryMechanism
+name: ms-Exch-Delivery-Mechanism
+schemaIDGUID: bf96794e-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Delivery-Order	
+# Determines the order of processing messages in the connector's
+# queue. Options are: FIFO, Priority (default), and Size.
+#
+dn: CN=ms-Exch-Delivery-Order,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Delivery-Order
+distinguishedName: CN=ms-Exch-Delivery-Order,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1003
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Delivery-Order
+adminDescription: ms-Exch-Delivery-Order
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDeliveryOrder
+name: ms-Exch-Delivery-Order
+schemaIDGUID: 9d41e26c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Deliver-And-Redirect	    
+# Used with ms-Exch-Alt-Recipient. If True, delivers to the mailbox and
+# also redirects.
+#
+dn: CN=ms-Exch-Deliver-And-Redirect,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Deliver-And-Redirect
+distinguishedName: CN=ms-Exch-Deliver-And-Redirect,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.190
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32877
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Deliver-And-Redirect
+adminDescription: ms-Exch-Deliver-And-Redirect
+oMSyntax: 1
+searchFlags: 16
+lDAPDisplayName: deliverAndRedirect
+name: ms-Exch-Deliver-And-Redirect
+schemaIDGUID: bf96794d-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Deliv-Cont-Length	   
+# For recipients, the maximum message size, in kilobytes (KB), that
+# they can receive. For a connector, the maximum message size, in KB,
+# that can be sent over the connector.
+#
+dn: CN=ms-Exch-Deliv-Cont-Length,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Deliv-Cont-Length
+distinguishedName: CN=ms-Exch-Deliv-Cont-Length,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.138
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32874
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Deliv-Cont-Length
+adminDescription: ms-Exch-Deliv-Cont-Length
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: delivContLength
+name: ms-Exch-Deliv-Cont-Length
+schemaIDGUID: bf96794a-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Deliv-EITs	    
+#
+dn: CN=ms-Exch-Deliv-EITs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Deliv-EITs
+distinguishedName: CN=ms-Exch-Deliv-EITs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.139
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 4096
+mAPIID: 32875
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Deliv-EITs
+adminDescription: ms-Exch-Deliv-EITs
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: delivEITs
+name: ms-Exch-Deliv-EITs
+schemaIDGUID: bf96794b-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Deliv-Ext-Cont-Types	
+#
+dn: CN=ms-Exch-Deliv-Ext-Cont-Types,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Deliv-Ext-Cont-Types
+distinguishedName: CN=ms-Exch-Deliv-Ext-Cont-Types,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.140
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 4096
+mAPIID: 32876
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Deliv-Ext-Cont-Types
+adminDescription: ms-Exch-Deliv-Ext-Cont-Types
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: delivExtContTypes
+name: ms-Exch-Deliv-Ext-Cont-Types
+schemaIDGUID: bf96794c-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dereference-Aliases	
+# Determines if x.500 aliases should be dereferenced. This is
+# applicable when replicating with x.500/LDAP directories that support
+# aliases.
+#
+dn: CN=ms-Exch-Dereference-Aliases,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dereference-Aliases
+distinguishedName: CN=ms-Exch-Dereference-Aliases,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dereference-Aliases
+adminDescription: ms-Exch-Dereference-Aliases
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDereferenceAliases
+name: ms-Exch-Dereference-Aliases
+schemaIDGUID: 9d60e0fe-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Destination-RG-DN   
+# The routing group (RG) on the other side of an Exchange Connector.
+#
+dn: CN=ms-Exch-Destination-RG-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Destination-RG-DN
+distinguishedName: CN=ms-Exch-Destination-RG-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12507
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Destination-RG-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Destination-RG-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchDestinationRGDN
+name: ms-Exch-Destination-RG-DN
+schemaIDGUID: 9d9ede22-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dest-BH-Address   
+# This attribute is obsolete.
+#
+dn: CN=ms-Exch-Dest-BH-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dest-BH-Address
+distinguishedName: CN=ms-Exch-Dest-BH-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12510
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 255
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dest-BH-Address
+adminDescription: ms-Exch-Dest-BH-Address
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchDestBHAddress
+name: ms-Exch-Dest-BH-Address
+schemaIDGUID: 9d8241ea-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Diagnostic-Reg-Key	
+# The location of the diagnostic registry key.
+#
+dn: CN=ms-Exch-Diagnostic-Reg-Key,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Diagnostic-Reg-Key
+distinguishedName: CN=ms-Exch-Diagnostic-Reg-Key,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.189
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 32881
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Diagnostic-Reg-Key
+adminDescription: ms-Exch-Diagnostic-Reg-Key
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: diagnosticRegKey
+name: ms-Exch-Diagnostic-Reg-Key
+schemaIDGUID: bf967952-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dirsync-Filters	
+# A list of relational expressions that determine which directory
+# entries are propagated from Lotus Notes to Exchange during directory
+# synchronization.
+#
+dn: CN=ms-Exch-Dirsync-Filters,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dirsync-Filters
+distinguishedName: CN=ms-Exch-Dirsync-Filters,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1005
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dirsync-Filters
+adminDescription: ms-Exch-Dirsync-Filters
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDirsyncFilters
+name: ms-Exch-Dirsync-Filters
+schemaIDGUID: 9dbddcb4-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dirsync-Schedule 
+#
+dn: CN=ms-Exch-Dirsync-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dirsync-Schedule
+distinguishedName: CN=ms-Exch-Dirsync-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1008
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dirsync-Schedule
+adminDescription: ms-Exch-Dirsync-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchDirsyncSchedule
+name: ms-Exch-Dirsync-Schedule
+schemaIDGUID: 8e11ff92-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Dirsync-Style	      
+#
+dn: CN=ms-Exch-Dirsync-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dirsync-Style
+distinguishedName: CN=ms-Exch-Dirsync-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1009
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dirsync-Style
+adminDescription: ms-Exch-Dirsync-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDirsyncStyle
+name: ms-Exch-Dirsync-Style
+schemaIDGUID: 8e2e9bca-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Dir-Browse-Flags    
+# Contains the directory browsing flags.
+#
+dn: CN=ms-Exch-Dir-Browse-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dir-Browse-Flags
+distinguishedName: CN=ms-Exch-Dir-Browse-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15005
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dir-Browse-Flags
+adminDescription: ms-Exch-Dir-Browse-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDirBrowseFlags
+name: ms-Exch-Dir-Browse-Flags
+schemaIDGUID: 8c221672-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Disabled-Gateway-Proxy	
+#
+dn: CN=ms-Exch-Disabled-Gateway-Proxy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Disabled-Gateway-Proxy
+distinguishedName: CN=ms-Exch-Disabled-Gateway-Proxy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.541
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 0
+rangeUpper: 1024
+mAPIID: 33219
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Disabled-Gateway-Proxy
+adminDescription: ms-Exch-Disabled-Gateway-Proxy
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: disabledGatewayProxy
+name: ms-Exch-Disabled-Gateway-Proxy
+schemaIDGUID: a8df73c0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Disable-UDG-Conversion	
+# If set, this disables the conversion of universal distribution
+# groups to universal security groups.
+#
+dn: CN=ms-Exch-Disable-UDG-Conversion,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Disable-UDG-Conversion
+distinguishedName: CN=ms-Exch-Disable-UDG-Conversion,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11088
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Disable-UDG-Conversion
+adminDescription: ms-Exch-Disable-UDG-Conversion
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDisableUDGConversion
+name: ms-Exch-Disable-UDG-Conversion
+schemaIDGUID: 372d6cde-38c7-47b6-a3da-be4648124ec0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Discussion-Folder  
+#
+dn: CN=ms-Exch-Discussion-Folder,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Discussion-Folder
+distinguishedName: CN=ms-Exch-Discussion-Folder,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.14002
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Discussion-Folder
+adminDescription: ms-Exch-Discussion-Folder
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDiscussionFolder
+name: ms-Exch-Discussion-Folder
+schemaIDGUID: 3df30250-38a7-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DL-Member-Rule      
+# This attribute is not used by Exchange.
+#
+dn: CN=ms-Exch-DL-Member-Rule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Member-Rule
+distinguishedName: CN=ms-Exch-DL-Member-Rule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.330
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 4096
+mAPIID: 32884
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Member-Rule
+adminDescription: ms-Exch-DL-Member-Rule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: dLMemberRule
+name: ms-Exch-DL-Member-Rule
+schemaIDGUID: a8df73c6-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DL-Mem-Default	
+#
+dn: CN=ms-Exch-DL-Mem-Default,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Mem-Default
+distinguishedName: CN=ms-Exch-DL-Mem-Default,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12527
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Mem-Default
+adminDescription: ms-Exch-DL-Mem-Default
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dLMemDefault
+name: ms-Exch-DL-Mem-Default
+schemaIDGUID: 89d5319c-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DL-Mem-Reject-Perms	
+# A distribution list (DL) whose members may not send to this
+# recipient or send messages over this connector.
+#
+dn: CN=ms-Exch-DL-Mem-Reject-Perms,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Mem-Reject-Perms
+distinguishedName: CN=ms-Exch-DL-Mem-Reject-Perms,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.47
+attributeSyntax: 2.5.5.7
+isSingleValued: FALSE
+linkID: 116
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Mem-Reject-Perms
+oMObjectClass:: VgYBAgULHQ==
+adminDescription: ms-Exch-DL-Mem-Reject-Perms
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: dLMemRejectPerms
+name: ms-Exch-DL-Mem-Reject-Perms
+schemaIDGUID: a8df73c2-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DL-Mem-Reject-Perms-BL   
+# Backlink to ms-Exch-DL-Mem-Reject-Perms.
+#
+dn: CN=ms-Exch-DL-Mem-Reject-Perms-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Mem-Reject-Perms-BL
+distinguishedName: CN=ms-Exch-DL-Mem-Reject-Perms-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.293
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32882
+linkID: 117
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Mem-Reject-Perms-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DL-Mem-Reject-Perms-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dLMemRejectPermsBL
+name: ms-Exch-DL-Mem-Reject-Perms-BL
+schemaIDGUID: a8df73c3-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DL-Mem-Submit-Perms	
+# A DL whose members may send to this recipient or send messages over
+# this connector.
+#
+dn: CN=ms-Exch-DL-Mem-Submit-Perms,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Mem-Submit-Perms
+distinguishedName: CN=ms-Exch-DL-Mem-Submit-Perms,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.144
+attributeSyntax: 2.5.5.7
+isSingleValued: FALSE
+linkID: 112
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Mem-Submit-Perms
+oMObjectClass:: VgYBAgULHQ==
+adminDescription: ms-Exch-DL-Mem-Submit-Perms
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: dLMemSubmitPerms
+name: ms-Exch-DL-Mem-Submit-Perms
+schemaIDGUID: a8df73c4-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DL-Mem-Submit-Perms-BL      
+# Backlink to ms-Exch-DL-Mem-Submit-Perms.
+#
+dn: CN=ms-Exch-DL-Mem-Submit-Perms-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DL-Mem-Submit-Perms-BL
+distinguishedName: CN=ms-Exch-DL-Mem-Submit-Perms-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.291
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32883
+linkID: 113
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DL-Mem-Submit-Perms-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DL-Mem-Submit-Perms-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dLMemSubmitPermsBL
+name: ms-Exch-DL-Mem-Submit-Perms-BL
+schemaIDGUID: a8df73c5-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Def-Alt-Recip	
+#
+dn: CN=ms-Exch-Domain-Def-Alt-Recip,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Def-Alt-Recip
+distinguishedName: CN=ms-Exch-Domain-Def-Alt-Recip,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.145
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32885
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Def-Alt-Recip
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Domain-Def-Alt-Recip
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: domainDefAltRecip
+name: ms-Exch-Domain-Def-Alt-Recip
+schemaIDGUID: 167757bb-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Global-Group-Guid  
+# Contains the stringized GUID of the domain local group within the
+# Recipient Update Service (RUS) domain.
+#
+dn: CN=ms-Exch-Domain-Global-Group-Guid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Global-Group-Guid
+distinguishedName: CN=ms-Exch-Domain-Global-Group-Guid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50089
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Global-Group-Guid
+adminDescription: ms-Exch-Domain-Global-Group-Guid
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDomainGlobalGroupGuid
+name: ms-Exch-Domain-Global-Group-Guid
+schemaIDGUID: 0d5aaba3-b593-4256-88dc-a0db2d2ffeec
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Global-Group-Sid  
+# Contains the stringized security identifier (SID) of the domain
+# global group within the RUS domain.
+#
+dn: CN=ms-Exch-Domain-Global-Group-Sid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Global-Group-Sid
+distinguishedName: CN=ms-Exch-Domain-Global-Group-Sid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50091
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Global-Group-Sid
+adminDescription: ms-Exch-Domain-Global-Group-Sid
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDomainGlobalGroupSid
+name: ms-Exch-Domain-Global-Group-Sid
+schemaIDGUID: d059b789-3e9e-4b8f-befe-db62bb580885
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Link	 
+# A link to the root of the domain.
+#
+dn: CN=ms-Exch-Domain-Link,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Link
+distinguishedName: CN=ms-Exch-Domain-Link,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.76
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Link
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Domain-Link
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchDomainLink
+name: ms-Exch-Domain-Link
+schemaIDGUID: 8ac39cc4-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Local-Group-Guid	
+# Contains the stringized GUID of the domain local group within the RUS domain.
+#
+dn: CN=ms-Exch-Domain-Local-Group-Guid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Local-Group-Guid
+distinguishedName: CN=ms-Exch-Domain-Local-Group-Guid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50088
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Local-Group-Guid
+adminDescription: ms-Exch-Domain-Local-Group-Guid
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDomainLocalGroupGuid
+name: ms-Exch-Domain-Local-Group-Guid
+schemaIDGUID: 3bf8ffc0-6492-4af4-b2bf-4f9fdb423425
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Domain-Local-Group-Sid   
+# Contains the stringized SID of the domain local group within the RUS
+# domain.
+dn: CN=ms-Exch-Domain-Local-Group-Sid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Local-Group-Sid
+distinguishedName: CN=ms-Exch-Domain-Local-Group-Sid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50090
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Local-Group-Sid
+adminDescription: ms-Exch-Domain-Local-Group-Sid
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDomainLocalGroupSid
+name: ms-Exch-Domain-Local-Group-Sid
+schemaIDGUID: d27eb1e5-a06c-4151-b789-59eabba8edca
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Domain-Name  
+# Stores the domain name that a Domain Content Configuration object
+# applies to.
+#
+dn: CN=ms-Exch-Domain-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Domain-Name
+distinguishedName: CN=ms-Exch-Domain-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.147
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 362
+mAPIID: 32886
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Domain-Name
+adminDescription: ms-Exch-Domain-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: domainName
+name: ms-Exch-Domain-Name
+schemaIDGUID: a8df73c8-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DownGrade-Multipart-Signed 
+# If True, the store configures IMAIL to convert a multipart/signed
+# message to a normal message and discard the signature. The default
+# is False.
+#
+dn: CN=ms-Exch-DownGrade-Multipart-Signed,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DownGrade-Multipart-Signed
+distinguishedName: CN=ms-Exch-DownGrade-Multipart-Signed,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11020
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DownGrade-Multipart-Signed
+adminDescription: ms-Exch-DownGrade-Multipart-Signed
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDownGradeMultipartSigned
+name: ms-Exch-DownGrade-Multipart-Signed
+schemaIDGUID: 9e39d6fc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Do-Full-Replication  
+# A flag used to signal the service to do a full synchronization of
+# the directories.
+#
+dn: CN=ms-Exch-Do-Full-Replication,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Do-Full-Replication
+distinguishedName: CN=ms-Exch-Do-Full-Replication,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.38
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Do-Full-Replication
+adminDescription: ms-Exch-Do-Full-Replication
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchDoFullReplication
+name: ms-Exch-Do-Full-Replication
+schemaIDGUID: 9e1ad86a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Do-OAB-Version  
+#
+dn: CN=ms-Exch-Do-OAB-Version,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Do-OAB-Version
+distinguishedName: CN=ms-Exch-Do-OAB-Version,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.575
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 35898
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Do-OAB-Version
+adminDescription: ms-Exch-Do-OAB-Version
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: doOABVersion
+name: ms-Exch-Do-OAB-Version
+schemaIDGUID: a8df73c7-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DS2MB-Options	  
+#
+dn: CN=ms-Exch-DS2MB-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DS2MB-Options
+distinguishedName: CN=ms-Exch-DS2MB-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.14001
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DS2MB-Options
+adminDescription: ms-Exch-DS2MB-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchDS2MBOptions
+name: ms-Exch-DS2MB-Options
+schemaIDGUID: 974c99da-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Admin-Copy      
+#
+dn: CN=ms-Exch-DXA-Admin-Copy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Admin-Copy
+distinguishedName: CN=ms-Exch-DXA-Admin-Copy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.378
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32888
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Admin-Copy
+adminDescription: ms-Exch-DXA-Admin-Copy
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAAdminCopy
+name: ms-Exch-DXA-Admin-Copy
+schemaIDGUID: a8df73c9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Admin-Forward   
+#
+dn: CN=ms-Exch-DXA-Admin-Forward,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Admin-Forward
+distinguishedName: CN=ms-Exch-DXA-Admin-Forward,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.379
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32889
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Admin-Forward
+adminDescription: ms-Exch-DXA-Admin-Forward
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAAdminForward
+name: ms-Exch-DXA-Admin-Forward
+schemaIDGUID: 167757be-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Admin-Update 
+#
+dn: CN=ms-Exch-DXA-Admin-Update,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Admin-Update
+distinguishedName: CN=ms-Exch-DXA-Admin-Update,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.381
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32890
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Admin-Update
+adminDescription: ms-Exch-DXA-Admin-Update
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAAdminUpdate
+name: ms-Exch-DXA-Admin-Update
+schemaIDGUID: a8df73ca-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Append-ReqCN 
+#
+dn: CN=ms-Exch-DXA-Append-ReqCN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Append-ReqCN
+distinguishedName: CN=ms-Exch-DXA-Append-ReqCN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.174
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32891
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Append-ReqCN
+adminDescription: ms-Exch-DXA-Append-ReqCN
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAAppendReqCN
+name: ms-Exch-DXA-Append-ReqCN
+schemaIDGUID: a8df73cb-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Conf-Container-List 
+#
+dn: CN=ms-Exch-DXA-Conf-Container-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Conf-Container-List
+distinguishedName: CN=ms-Exch-DXA-Conf-Container-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.180
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32892
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Conf-Container-List
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DXA-Conf-Container-List
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dXAConfContainerList
+name: ms-Exch-DXA-Conf-Container-List
+schemaIDGUID: a8df73cc-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Conf-Req-Time	  
+#
+dn: CN=ms-Exch-DXA-Conf-Req-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Conf-Req-Time
+distinguishedName: CN=ms-Exch-DXA-Conf-Req-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.122
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32893
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Conf-Req-Time
+adminDescription: ms-Exch-DXA-Conf-Req-Time
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: dXAConfReqTime
+name: ms-Exch-DXA-Conf-Req-Time
+schemaIDGUID: a8df73cd-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Conf-Seq		  
+#
+dn: CN=ms-Exch-DXA-Conf-Seq,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Conf-Seq
+distinguishedName: CN=ms-Exch-DXA-Conf-Seq,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.184
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32894
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Conf-Seq
+adminDescription: ms-Exch-DXA-Conf-Seq
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: dXAConfSeq
+name: ms-Exch-DXA-Conf-Seq
+schemaIDGUID: a8df73ce-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Conf-Seq-USN	  
+#
+dn: CN=ms-Exch-DXA-Conf-Seq-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Conf-Seq-USN
+distinguishedName: CN=ms-Exch-DXA-Conf-Seq-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.45
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32895
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Conf-Seq-USN
+adminDescription: ms-Exch-DXA-Conf-Seq-USN
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAConfSeqUSN
+name: ms-Exch-DXA-Conf-Seq-USN
+schemaIDGUID: a8df73cf-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Exchange-Options	  
+#
+dn: CN=ms-Exch-DXA-Exchange-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Exchange-Options
+distinguishedName: CN=ms-Exch-DXA-Exchange-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.359
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32896
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Exchange-Options
+adminDescription: ms-Exch-DXA-Exchange-Options
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: dXAExchangeOptions
+name: ms-Exch-DXA-Exchange-Options
+schemaIDGUID: a8df73d0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Export-Now	  
+#
+dn: CN=ms-Exch-DXA-Export-Now,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Export-Now
+distinguishedName: CN=ms-Exch-DXA-Export-Now,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.377
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32897
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Export-Now
+adminDescription: ms-Exch-DXA-Export-Now
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAExportNow
+name: ms-Exch-DXA-Export-Now
+schemaIDGUID: a8df73d1-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Import-Now	  
+#
+dn: CN=ms-Exch-DXA-Import-Now,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Import-Now
+distinguishedName: CN=ms-Exch-DXA-Import-Now,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.376
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32902
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Import-Now
+adminDescription: ms-Exch-DXA-Import-Now
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAImportNow
+name: ms-Exch-DXA-Import-Now
+schemaIDGUID: a8df73d5-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Imp-Seq		  
+#
+dn: CN=ms-Exch-DXA-Imp-Seq,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Imp-Seq
+distinguishedName: CN=ms-Exch-DXA-Imp-Seq,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.116
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32899
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Imp-Seq
+adminDescription: ms-Exch-DXA-Imp-Seq
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: dXAImpSeq
+name: ms-Exch-DXA-Imp-Seq
+schemaIDGUID: a8df73d2-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Imp-Seq-Time	  
+#
+dn: CN=ms-Exch-DXA-Imp-Seq-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Imp-Seq-Time
+distinguishedName: CN=ms-Exch-DXA-Imp-Seq-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.117
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32900
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Imp-Seq-Time
+adminDescription: ms-Exch-DXA-Imp-Seq-Time
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: dXAImpSeqTime
+name: ms-Exch-DXA-Imp-Seq-Time
+schemaIDGUID: a8df73d3-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Imp-Seq-USN	  
+#
+dn: CN=ms-Exch-DXA-Imp-Seq-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Imp-Seq-USN
+distinguishedName: CN=ms-Exch-DXA-Imp-Seq-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.86
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32901
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Imp-Seq-USN
+adminDescription: ms-Exch-DXA-Imp-Seq-USN
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAImpSeqUSN
+name: ms-Exch-DXA-Imp-Seq-USN
+schemaIDGUID: a8df73d4-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-In-Template-Map	  
+#
+dn: CN=ms-Exch-DXA-In-Template-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-In-Template-Map
+distinguishedName: CN=ms-Exch-DXA-In-Template-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.363
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 32903
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-In-Template-Map
+adminDescription: ms-Exch-DXA-In-Template-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dXAInTemplateMap
+name: ms-Exch-DXA-In-Template-Map
+schemaIDGUID: a8df73d6-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Local-Admin	  
+#
+dn: CN=ms-Exch-DXA-Local-Admin,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Local-Admin
+distinguishedName: CN=ms-Exch-DXA-Local-Admin,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.113
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32904
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Local-Admin
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DXA-Local-Admin
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dXALocalAdmin
+name: ms-Exch-DXA-Local-Admin
+schemaIDGUID: a8df73d7-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Native-Address-Type 
+#
+dn: CN=ms-Exch-DXA-Native-Address-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Native-Address-Type
+distinguishedName: CN=ms-Exch-DXA-Native-Address-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.331
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32906
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Native-Address-Type
+adminDescription: ms-Exch-DXA-Native-Address-Type
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: dXANativeAddressType
+name: ms-Exch-DXA-Native-Address-Type
+schemaIDGUID: a8df73d9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Out-Template-Map	  
+#
+dn: CN=ms-Exch-DXA-Out-Template-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Out-Template-Map
+distinguishedName: CN=ms-Exch-DXA-Out-Template-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.364
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 32907
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Out-Template-Map
+adminDescription: ms-Exch-DXA-Out-Template-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dXAOutTemplateMap
+name: ms-Exch-DXA-Out-Template-Map
+schemaIDGUID: a8df73da-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Password		  
+#
+dn: CN=ms-Exch-DXA-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Password
+distinguishedName: CN=ms-Exch-DXA-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.305
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 12
+mAPIID: 32908
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Password
+adminDescription: ms-Exch-DXA-Password
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dXAPassword
+name: ms-Exch-DXA-Password
+schemaIDGUID: a8df73db-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Prev-Exchange-Options   
+#
+dn: CN=ms-Exch-DXA-Prev-Exchange-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Exchange-Options
+distinguishedName: CN=ms-Exch-DXA-Prev-Exchange-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.216
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32909
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Exchange-Options
+adminDescription: ms-Exch-DXA-Prev-Exchange-Options
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: dXAPrevExchangeOptions
+name: ms-Exch-DXA-Prev-Exchange-Options
+schemaIDGUID: a8df73dc-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Prev-Export-Native-Only 
+#
+dn: CN=ms-Exch-DXA-Prev-Export-Native-Only,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Export-Native-Only
+distinguishedName: CN=ms-Exch-DXA-Prev-Export-Native-Only,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.203
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32910
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Export-Native-Only
+adminDescription: ms-Exch-DXA-Prev-Export-Native-Only
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: dXAPrevExportNativeOnly
+name: ms-Exch-DXA-Prev-Export-Native-Only
+schemaIDGUID: a8df73dd-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Prev-In-Exchange-Sensitivity     
+#
+dn: CN=ms-Exch-DXA-Prev-In-Exchange-Sensitivity,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-In-Exchange-Sensitivity
+distinguishedName: CN=ms-Exch-DXA-Prev-In-Exchange-Sensitivity,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.90
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32911
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-In-Exchange-Sensitivity
+adminDescription: ms-Exch-DXA-Prev-In-Exchange-Sensitivity
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAPrevInExchangeSensitivity
+name: ms-Exch-DXA-Prev-In-Exchange-Sensitivity
+schemaIDGUID: a8df73de-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Prev-Remote-Entries	       
+#
+dn: CN=ms-Exch-DXA-Prev-Remote-Entries,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Remote-Entries
+distinguishedName: CN=ms-Exch-DXA-Prev-Remote-Entries,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.265
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32912
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Remote-Entries
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DXA-Prev-Remote-Entries
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dXAPrevRemoteEntries
+name: ms-Exch-DXA-Prev-Remote-Entries
+schemaIDGUID: a8df73df-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Prev-Replication-Sensitivity     
+#
+dn: CN=ms-Exch-DXA-Prev-Replication-Sensitivity,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Replication-Sensitivity
+distinguishedName: CN=ms-Exch-DXA-Prev-Replication-Sensitivity,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.215
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32913
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Replication-Sensitivity
+adminDescription: ms-Exch-DXA-Prev-Replication-Sensitivity
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAPrevReplicationSensitivity
+name: ms-Exch-DXA-Prev-Replication-Sensitivity
+schemaIDGUID: a8df73e0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Prev-Template-Options	       
+#
+dn: CN=ms-Exch-DXA-Prev-Template-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Template-Options
+distinguishedName: CN=ms-Exch-DXA-Prev-Template-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.395
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32914
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Template-Options
+adminDescription: ms-Exch-DXA-Prev-Template-Options
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: dXAPrevTemplateOptions
+name: ms-Exch-DXA-Prev-Template-Options
+schemaIDGUID: a8df73e1-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Prev-Types  
+#
+dn: CN=ms-Exch-DXA-Prev-Types,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Prev-Types
+distinguishedName: CN=ms-Exch-DXA-Prev-Types,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.217
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32915
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Prev-Types
+adminDescription: ms-Exch-DXA-Prev-Types
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAPrevTypes
+name: ms-Exch-DXA-Prev-Types
+schemaIDGUID: 167757d8-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Recipient-CP 
+#
+dn: CN=ms-Exch-DXA-Recipient-CP,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Recipient-CP
+distinguishedName: CN=ms-Exch-DXA-Recipient-CP,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.384
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 24
+mAPIID: 32916
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Recipient-CP
+adminDescription: ms-Exch-DXA-Recipient-CP
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dXARecipientCP
+name: ms-Exch-DXA-Recipient-CP
+schemaIDGUID: a8df73e2-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Remote-Client   
+#
+dn: CN=ms-Exch-DXA-Remote-Client,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Remote-Client
+distinguishedName: CN=ms-Exch-DXA-Remote-Client,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.112
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32917
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Remote-Client
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DXA-Remote-Client
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dXARemoteClient
+name: ms-Exch-DXA-Remote-Client
+schemaIDGUID: a8df73e3-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-ReqName	      
+#
+dn: CN=ms-Exch-DXA-ReqName,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-ReqName
+distinguishedName: CN=ms-Exch-DXA-ReqName,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.446
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 32921
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-ReqName
+adminDescription: ms-Exch-DXA-ReqName
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dXAReqName
+name: ms-Exch-DXA-ReqName
+schemaIDGUID: a8df73e7-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Req-Seq	      
+#
+dn: CN=ms-Exch-DXA-Req-Seq,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Req-Seq
+distinguishedName: CN=ms-Exch-DXA-Req-Seq,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.101
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32918
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Req-Seq
+adminDescription: ms-Exch-DXA-Req-Seq
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: dXAReqSeq
+name: ms-Exch-DXA-Req-Seq
+schemaIDGUID: a8df73e4-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Req-Seq-Time 
+#
+dn: CN=ms-Exch-DXA-Req-Seq-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Req-Seq-Time
+distinguishedName: CN=ms-Exch-DXA-Req-Seq-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.114
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32919
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Req-Seq-Time
+adminDescription: ms-Exch-DXA-Req-Seq-Time
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: dXAReqSeqTime
+name: ms-Exch-DXA-Req-Seq-Time
+schemaIDGUID: a8df73e5-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Req-Seq-USN     
+#
+dn: CN=ms-Exch-DXA-Req-Seq-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Req-Seq-USN
+distinguishedName: CN=ms-Exch-DXA-Req-Seq-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.182
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32920
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Req-Seq-USN
+adminDescription: ms-Exch-DXA-Req-Seq-USN
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXAReqSeqUSN
+name: ms-Exch-DXA-Req-Seq-USN
+schemaIDGUID: a8df73e6-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Svr-Seq	      
+#
+dn: CN=ms-Exch-DXA-Svr-Seq,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Svr-Seq
+distinguishedName: CN=ms-Exch-DXA-Svr-Seq,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.360
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32922
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Svr-Seq
+adminDescription: ms-Exch-DXA-Svr-Seq
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: dXASvrSeq
+name: ms-Exch-DXA-Svr-Seq
+schemaIDGUID: a8df73e8-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-Svr-Seq-Time 
+#
+dn: CN=ms-Exch-DXA-Svr-Seq-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Svr-Seq-Time
+distinguishedName: CN=ms-Exch-DXA-Svr-Seq-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.361
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32923
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Svr-Seq-Time
+adminDescription: ms-Exch-DXA-Svr-Seq-Time
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: dXASvrSeqTime
+name: ms-Exch-DXA-Svr-Seq-Time
+schemaIDGUID: a8df73e9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Svr-Seq-USN     
+#
+dn: CN=ms-Exch-DXA-Svr-Seq-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Svr-Seq-USN
+distinguishedName: CN=ms-Exch-DXA-Svr-Seq-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.124
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32924
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Svr-Seq-USN
+adminDescription: ms-Exch-DXA-Svr-Seq-USN
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXASvrSeqUSN
+name: ms-Exch-DXA-Svr-Seq-USN
+schemaIDGUID: a8df73ea-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Template-Options	  
+#
+dn: CN=ms-Exch-DXA-Template-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Template-Options
+distinguishedName: CN=ms-Exch-DXA-Template-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.358
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32926
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Template-Options
+adminDescription: ms-Exch-DXA-Template-Options
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: dXATemplateOptions
+name: ms-Exch-DXA-Template-Options
+schemaIDGUID: a8df73eb-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Template-TimeStamp  
+#
+dn: CN=ms-Exch-DXA-Template-TimeStamp,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Template-TimeStamp
+distinguishedName: CN=ms-Exch-DXA-Template-TimeStamp,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.365
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32927
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Template-TimeStamp
+adminDescription: ms-Exch-DXA-Template-TimeStamp
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: dXATemplateTimeStamp
+name: ms-Exch-DXA-Template-TimeStamp
+schemaIDGUID: a8df73ec-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-DXA-Types 
+#
+dn: CN=ms-Exch-DXA-Types,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-Types
+distinguishedName: CN=ms-Exch-DXA-Types,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.119
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32928
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-Types
+adminDescription: ms-Exch-DXA-Types
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: dXATypes
+name: ms-Exch-DXA-Types
+schemaIDGUID: a8df73ed-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-DXA-UnConf-Container-List	     
+#
+dn: CN=ms-Exch-DXA-UnConf-Container-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-DXA-UnConf-Container-List
+distinguishedName: CN=ms-Exch-DXA-UnConf-Container-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.181
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32929
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-DXA-UnConf-Container-List
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-DXA-UnConf-Container-List
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: dXAUnConfContainerList
+name: ms-Exch-DXA-UnConf-Container-List
+schemaIDGUID: a8df73ee-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Dynamic-DL-BaseDN		     
+#
+dn: CN=ms-Exch-Dynamic-DL-BaseDN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dynamic-DL-BaseDN
+distinguishedName: CN=ms-Exch-Dynamic-DL-BaseDN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12543
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dynamic-DL-BaseDN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Dynamic-DL-BaseDN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchDynamicDLBaseDN
+name: ms-Exch-Dynamic-DL-BaseDN
+schemaIDGUID: 763d0ef9-bd92-41f9-ab34-7e329db76ee3
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Dynamic-DL-Filter		     
+#
+dn: CN=ms-Exch-Dynamic-DL-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Dynamic-DL-Filter
+distinguishedName: CN=ms-Exch-Dynamic-DL-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12544
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Dynamic-DL-Filter
+adminDescription: ms-Exch-Dynamic-DL-Filter
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchDynamicDLFilter
+name: ms-Exch-Dynamic-DL-Filter
+schemaIDGUID: e1b6d32c-6bac-48da-a313-2b58ae1c45ce
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-EDB-File			     
+# The database file location for this store.
+#
+dn: CN=ms-Exch-EDB-File,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-EDB-File
+distinguishedName: CN=ms-Exch-EDB-File,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11001
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-EDB-File
+adminDescription: ms-Exch-EDB-File
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchEDBFile
+name: ms-Exch-EDB-File
+schemaIDGUID: 9e58d58e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-EDB-Offline  
+# If TRUE, the MDB is offline. The default is FALSE.
+#
+dn: CN=ms-Exch-EDB-Offline,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-EDB-Offline
+distinguishedName: CN=ms-Exch-EDB-Offline,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11007
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-EDB-Offline
+adminDescription: ms-Exch-EDB-Offline
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchEDBOffline
+name: ms-Exch-EDB-Offline
+schemaIDGUID: 9e7a367a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Enabled-Authorization-Packages	
+# A list of authorization packages enabled for this protocol.
+#
+dn: CN=ms-Exch-Enabled-Authorization-Packages,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Enabled-Authorization-Packages
+distinguishedName: CN=ms-Exch-Enabled-Authorization-Packages,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.479
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33156
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Enabled-Authorization-Packages
+adminDescription: ms-Exch-Enabled-Authorization-Packages
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: enabledAuthorizationPackages
+name: ms-Exch-Enabled-Authorization-Packages
+schemaIDGUID: a8df73f3-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Enabled-Protocols	 
+#
+dn: CN=ms-Exch-Enabled-Protocols,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Enabled-Protocols
+distinguishedName: CN=ms-Exch-Enabled-Protocols,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.474
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33151
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Enabled-Protocols
+adminDescription: ms-Exch-Enabled-Protocols
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: enabledProtocols
+name: ms-Exch-Enabled-Protocols
+schemaIDGUID: f0f8ff8c-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Enabled-Protocol-Cfg	 
+# Determines whether this protocol is enabled or not.
+dn: CN=ms-Exch-Enabled-Protocol-Cfg,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Enabled-Protocol-Cfg
+distinguishedName: CN=ms-Exch-Enabled-Protocol-Cfg,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.515
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33192
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Enabled-Protocol-Cfg
+adminDescription: ms-Exch-Enabled-Protocol-Cfg
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: enabledProtocolCfg
+name: ms-Exch-Enabled-Protocol-Cfg
+schemaIDGUID: a8df73f4-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Enable-Compatibility	    
+#
+dn: CN=ms-Exch-Enable-Compatibility,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Enable-Compatibility
+distinguishedName: CN=ms-Exch-Enable-Compatibility,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.567
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35890
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Enable-Compatibility
+adminDescription: ms-Exch-Enable-Compatibility
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: enableCompatibility
+name: ms-Exch-Enable-Compatibility
+schemaIDGUID: a8df73f1-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Enable-Internal-Evaluator 
+#
+dn: CN=ms-Exch-Enable-Internal-Evaluator,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Enable-Internal-Evaluator
+distinguishedName: CN=ms-Exch-Enable-Internal-Evaluator,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.99
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Enable-Internal-Evaluator
+adminDescription: ms-Exch-Enable-Internal-Evaluator
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchEnableInternalEvaluator
+name: ms-Exch-Enable-Internal-Evaluator
+schemaIDGUID: 9a56980f-283c-4f86-8395-23011350600c
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encapsulation-Method	    
+# This is present only on X.400 connectors.
+#
+dn: CN=ms-Exch-Encapsulation-Method,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encapsulation-Method
+distinguishedName: CN=ms-Exch-Encapsulation-Method,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.448
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32930
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encapsulation-Method
+adminDescription: ms-Exch-Encapsulation-Method
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: encapsulationMethod
+name: ms-Exch-Encapsulation-Method
+schemaIDGUID: a8df73f5-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encode-SMTP-Relay	
+# Determines whether or not messages submitted to this domain will be
+# encoded using the content configuration settings.
+#
+dn: CN=ms-Exch-Encode-SMTP-Relay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encode-SMTP-Relay
+distinguishedName: CN=ms-Exch-Encode-SMTP-Relay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5053
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encode-SMTP-Relay
+adminDescription: ms-Exch-Encode-SMTP-Relay
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchEncodeSMTPRelay
+name: ms-Exch-Encode-SMTP-Relay
+schemaIDGUID: 3a633f17-5194-11d3-aa77-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypt 
+#
+dn: CN=ms-Exch-Encrypt,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypt
+distinguishedName: CN=ms-Exch-Encrypt,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.236
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32931
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypt
+adminDescription: ms-Exch-Encrypt
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: encrypt
+name: ms-Exch-Encrypt
+schemaIDGUID: a8df73f6-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypted-Anonymous-Password	
+#
+dn: CN=ms-Exch-Encrypted-Anonymous-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypted-Anonymous-Password
+distinguishedName: CN=ms-Exch-Encrypted-Anonymous-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15009
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypted-Anonymous-Password
+adminDescription: ms-Exch-Encrypted-Anonymous-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchEncryptedAnonymousPassword
+name: ms-Exch-Encrypted-Anonymous-Password
+schemaIDGUID: 5dc055fc-5c3f-4a6f-a34a-4dbcb68e2ad0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypted-Password 
+#
+dn: CN=ms-Exch-Encrypted-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypted-Password
+distinguishedName: CN=ms-Exch-Encrypted-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50062
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypted-Password
+adminDescription: ms-Exch-Encrypted-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchEncryptedPassword
+name: ms-Exch-Encrypted-Password
+schemaIDGUID: 08c63250-0df6-405d-8907-0312dd1aa145
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypted-Password-2	 
+#
+dn: CN=ms-Exch-Encrypted-Password-2,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypted-Password-2
+distinguishedName: CN=ms-Exch-Encrypted-Password-2,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50065
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypted-Password-2
+adminDescription: ms-Exch-Encrypted-Password-2
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchEncryptedPassword2
+name: ms-Exch-Encrypted-Password-2
+schemaIDGUID: dcbc61e9-9279-44d1-b494-25562659db75
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypt-Alg-List-NA	 
+#
+dn: CN=ms-Exch-Encrypt-Alg-List-NA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypt-Alg-List-NA
+distinguishedName: CN=ms-Exch-Encrypt-Alg-List-NA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.130
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32832
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypt-Alg-List-NA
+adminDescription: ms-Exch-Encrypt-Alg-List-NA
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: encryptAlgListNA
+name: ms-Exch-Encrypt-Alg-List-NA
+schemaIDGUID: a8df73f7-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Encrypt-Alg-List-Other 
+#
+dn: CN=ms-Exch-Encrypt-Alg-List-Other,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypt-Alg-List-Other
+distinguishedName: CN=ms-Exch-Encrypt-Alg-List-Other,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.399
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32833
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypt-Alg-List-Other
+adminDescription: ms-Exch-Encrypt-Alg-List-Other
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: encryptAlgListOther
+name: ms-Exch-Encrypt-Alg-List-Other
+schemaIDGUID: a8df73f8-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Encrypt-Alg-Selected-NA 
+#
+dn: CN=ms-Exch-Encrypt-Alg-Selected-NA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypt-Alg-Selected-NA
+distinguishedName: CN=ms-Exch-Encrypt-Alg-Selected-NA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.401
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32835
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypt-Alg-Selected-NA
+adminDescription: ms-Exch-Encrypt-Alg-Selected-NA
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: encryptAlgSelectedNA
+name: ms-Exch-Encrypt-Alg-Selected-NA
+schemaIDGUID: a8df73f9-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Encrypt-Alg-Selected-Other 
+#
+dn: CN=ms-Exch-Encrypt-Alg-Selected-Other,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Encrypt-Alg-Selected-Other
+distinguishedName: CN=ms-Exch-Encrypt-Alg-Selected-Other,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.397
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32829
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Encrypt-Alg-Selected-Other
+adminDescription: ms-Exch-Encrypt-Alg-Selected-Other
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: encryptAlgSelectedOther
+name: ms-Exch-Encrypt-Alg-Selected-Other
+schemaIDGUID: a8df73fa-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Assert-Action    
+# The action on assert.
+dn: CN=ms-Exch-ESE-Param-Assert-Action,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Assert-Action
+distinguishedName: CN=ms-Exch-ESE-Param-Assert-Action,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11074
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Assert-Action
+adminDescription: ms-Exch-ESE-Param-Assert-Action
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamAssertAction
+name: ms-Exch-ESE-Param-Assert-Action
+schemaIDGUID: 2d09783d-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Base-Name	
+# The base name for all Database Management System (DBMS) object names.
+#
+dn: CN=ms-Exch-ESE-Param-Base-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Base-Name
+distinguishedName: CN=ms-Exch-ESE-Param-Base-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11076
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Base-Name
+adminDescription: ms-Exch-ESE-Param-Base-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchESEParamBaseName
+name: ms-Exch-ESE-Param-Base-Name
+schemaIDGUID: 2d097845-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Cached-Closed-Tables 
+#
+dn: CN=ms-Exch-ESE-Param-Cached-Closed-Tables,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Cached-Closed-Tables
+distinguishedName: CN=ms-Exch-ESE-Param-Cached-Closed-Tables,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11096
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Cached-Closed-Tables
+adminDescription: ms-Exch-ESE-Param-Cached-Closed-Tables
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCachedClosedTables
+name: ms-Exch-ESE-Param-Cached-Closed-Tables
+schemaIDGUID: d19c67f8-a0eb-432a-bedd-af10cd7da25c
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Cache-Size 
+#
+dn: CN=ms-Exch-ESE-Param-Cache-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Cache-Size
+distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11002
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Cache-Size
+adminDescription: ms-Exch-ESE-Param-Cache-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCacheSize
+name: ms-Exch-ESE-Param-Cache-Size
+schemaIDGUID: 9eb8339e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Cache-Size-Max 
+#
+dn: CN=ms-Exch-ESE-Param-Cache-Size-Max,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Cache-Size-Max
+distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size-Max,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11003
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Cache-Size-Max
+adminDescription: ms-Exch-ESE-Param-Cache-Size-Max
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCacheSizeMax
+name: ms-Exch-ESE-Param-Cache-Size-Max
+schemaIDGUID: 9ed73230-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Cache-Size-Min 
+# The minimum cache size in pages.
+#
+dn: CN=ms-Exch-ESE-Param-Cache-Size-Min,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Cache-Size-Min
+distinguishedName: CN=ms-Exch-ESE-Param-Cache-Size-Min,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11075
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Cache-Size-Min
+adminDescription: ms-Exch-ESE-Param-Cache-Size-Min
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCacheSizeMin
+name: ms-Exch-ESE-Param-Cache-Size-Min
+schemaIDGUID: 2d097841-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Checkpoint-Depth-Max	
+# The maximum checkpoint depth in bytes.
+#
+dn: CN=ms-Exch-ESE-Param-Checkpoint-Depth-Max,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Checkpoint-Depth-Max
+distinguishedName: CN=ms-Exch-ESE-Param-Checkpoint-Depth-Max,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11081
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Checkpoint-Depth-Max
+adminDescription: ms-Exch-ESE-Param-Checkpoint-Depth-Max
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCheckpointDepthMax
+name: ms-Exch-ESE-Param-Checkpoint-Depth-Max
+schemaIDGUID: 2d09785a-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Circular-Log	
+# A Boolean flag for circular logging.
+#
+dn: CN=ms-Exch-ESE-Param-Circular-Log,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Circular-Log
+distinguishedName: CN=ms-Exch-ESE-Param-Circular-Log,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11005
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Circular-Log
+adminDescription: ms-Exch-ESE-Param-Circular-Log
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCircularLog
+name: ms-Exch-ESE-Param-Circular-Log
+schemaIDGUID: 9ef8931c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Commit-Default	
+# The default grbit for JetCommitTransaction.
+#
+dn: CN=ms-Exch-ESE-Param-Commit-Default,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Commit-Default
+distinguishedName: CN=ms-Exch-ESE-Param-Commit-Default,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11077
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Commit-Default
+adminDescription: ms-Exch-ESE-Param-Commit-Default
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamCommitDefault
+name: ms-Exch-ESE-Param-Commit-Default
+schemaIDGUID: 2d097849-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Db-Extension-Size	
+# The database extension size in pages.
+#
+dn: CN=ms-Exch-ESE-Param-Db-Extension-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Db-Extension-Size
+distinguishedName: CN=ms-Exch-ESE-Param-Db-Extension-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11078
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Db-Extension-Size
+adminDescription: ms-Exch-ESE-Param-Db-Extension-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamDbExtensionSize
+name: ms-Exch-ESE-Param-Db-Extension-Size
+schemaIDGUID: 2d09784d-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Enable-Index-Checking	
+# Enables checking the operating system version for indexes. The
+# default is False.
+#
+dn: CN=ms-Exch-ESE-Param-Enable-Index-Checking,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Enable-Index-Checking
+distinguishedName: CN=ms-Exch-ESE-Param-Enable-Index-Checking,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11073
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Enable-Index-Checking
+adminDescription: ms-Exch-ESE-Param-Enable-Index-Checking
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchESEParamEnableIndexChecking
+name: ms-Exch-ESE-Param-Enable-Index-Checking
+schemaIDGUID: 2d097838-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Enable-Online-Defrag  
+# Enables online defragmentation. The default is True.
+#
+dn: CN=ms-Exch-ESE-Param-Enable-Online-Defrag,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Enable-Online-Defrag
+distinguishedName: CN=ms-Exch-ESE-Param-Enable-Online-Defrag,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11072
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Enable-Online-Defrag
+adminDescription: ms-Exch-ESE-Param-Enable-Online-Defrag
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchESEParamEnableOnlineDefrag
+name: ms-Exch-ESE-Param-Enable-Online-Defrag
+schemaIDGUID: 2d097833-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns	
+# Internally sorts (in a dynamically allocated parallel array)
+# JET_RETRIEVECOLUMN structures passed to JetRetrieveColumns(). The
+# default is False.
+#
+dn: CN=ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns
+distinguishedName: CN=ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns,CN=Sche
+attributeID: 1.2.840.113556.1.4.7000.102.11069
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns
+adminDescription: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchESEParamEnableSortedRetrieveColumns
+name: ms-Exch-ESE-Param-Enable-Sorted-Retrieve-Columns
+schemaIDGUID: 2d097828-2b54-11d3-aa6b-00c04f8eedd8
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Event-Source     
+# A language-independent process descriptor string.
+#
+dn: CN=ms-Exch-ESE-Param-Event-Source,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Event-Source
+distinguishedName: CN=ms-Exch-ESE-Param-Event-Source,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11008
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Event-Source
+adminDescription: ms-Exch-ESE-Param-Event-Source
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchESEParamEventSource
+name: ms-Exch-ESE-Param-Event-Source
+schemaIDGUID: 9f19f408-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Global-Min-Ver-Pages	
+# The global minimum version page size in 16-kilobyte (KB) units.
+#
+dn: CN=ms-Exch-ESE-Param-Global-Min-Ver-Pages,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Global-Min-Ver-Pages
+distinguishedName: CN=ms-Exch-ESE-Param-Global-Min-Ver-Pages,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11082
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Global-Min-Ver-Pages
+adminDescription: ms-Exch-ESE-Param-Global-Min-Ver-Pages
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamGlobalMinVerPages
+name: ms-Exch-ESE-Param-Global-Min-Ver-Pages
+schemaIDGUID: 02e831da-2f29-11d3-aa6c-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Log-Buffers	
+# Log buffers in 512 bytes.
+#
+dn: CN=ms-Exch-ESE-Param-Log-Buffers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Log-Buffers
+distinguishedName: CN=ms-Exch-ESE-Param-Log-Buffers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11009
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Log-Buffers
+adminDescription: ms-Exch-ESE-Param-Log-Buffers
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamLogBuffers
+name: ms-Exch-ESE-Param-Log-Buffers
+schemaIDGUID: 9f38f29a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Log-Checkpoint-Period	
+#
+dn: CN=ms-Exch-ESE-Param-Log-Checkpoint-Period,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Log-Checkpoint-Period
+distinguishedName: CN=ms-Exch-ESE-Param-Log-Checkpoint-Period,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11010
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Log-Checkpoint-Period
+adminDescription: ms-Exch-ESE-Param-Log-Checkpoint-Period
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamLogCheckpointPeriod
+name: ms-Exch-ESE-Param-Log-Checkpoint-Period
+schemaIDGUID: 9f5a5386-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Log-File-Path
+# The path to the log file directory.
+#
+dn: CN=ms-Exch-ESE-Param-Log-File-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Log-File-Path
+distinguishedName: CN=ms-Exch-ESE-Param-Log-File-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11011
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Log-File-Path
+adminDescription: ms-Exch-ESE-Param-Log-File-Path
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchESEParamLogFilePath
+name: ms-Exch-ESE-Param-Log-File-Path
+schemaIDGUID: 9f795218-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Log-File-Size	
+# The log file size in KB.
+dn: CN=ms-Exch-ESE-Param-Log-File-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Log-File-Size
+distinguishedName: CN=ms-Exch-ESE-Param-Log-File-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11012
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Log-File-Size
+adminDescription: ms-Exch-ESE-Param-Log-File-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamLogFileSize
+name: ms-Exch-ESE-Param-Log-File-Size
+schemaIDGUID: 9f9ab304-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Log-Waiting-User-Max	
+# The maximum sessions waiting on log flush.
+#
+dn: CN=ms-Exch-ESE-Param-Log-Waiting-User-Max,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Log-Waiting-User-Max
+distinguishedName: CN=ms-Exch-ESE-Param-Log-Waiting-User-Max,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11013
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Log-Waiting-User-Max
+adminDescription: ms-Exch-ESE-Param-Log-Waiting-User-Max
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamLogWaitingUserMax
+name: ms-Exch-ESE-Param-Log-Waiting-User-Max
+schemaIDGUID: 9fbe764a-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Max-Cursors	
+# The maximum number of open cursors.
+#
+dn: CN=ms-Exch-ESE-Param-Max-Cursors,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Max-Cursors
+distinguishedName: CN=ms-Exch-ESE-Param-Max-Cursors,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11071
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Max-Cursors
+adminDescription: ms-Exch-ESE-Param-Max-Cursors
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamMaxCursors
+name: ms-Exch-ESE-Param-Max-Cursors
+schemaIDGUID: 2d097830-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Max-Open-Tables	
+# The maximum number of open directories.
+#
+dn: CN=ms-Exch-ESE-Param-Max-Open-Tables,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Max-Open-Tables
+distinguishedName: CN=ms-Exch-ESE-Param-Max-Open-Tables,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11014
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Max-Open-Tables
+adminDescription: ms-Exch-ESE-Param-Max-Open-Tables
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamMaxOpenTables
+name: ms-Exch-ESE-Param-Max-Open-Tables
+schemaIDGUID: 9fdfd736-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Max-Sessions	
+# The maximum number of sessions.
+#
+dn: CN=ms-Exch-ESE-Param-Max-Sessions,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Max-Sessions
+distinguishedName: CN=ms-Exch-ESE-Param-Max-Sessions,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11015
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Max-Sessions
+adminDescription: ms-Exch-ESE-Param-Max-Sessions
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamMaxSessions
+name: ms-Exch-ESE-Param-Max-Sessions
+schemaIDGUID: 9ffed5c8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Max-Temporary-Tables	
+# The maximum concurrent open temporary table/index creation.
+#
+dn: CN=ms-Exch-ESE-Param-Max-Temporary-Tables,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Max-Temporary-Tables
+distinguishedName: CN=ms-Exch-ESE-Param-Max-Temporary-Tables,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11070
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Max-Temporary-Tables
+adminDescription: ms-Exch-ESE-Param-Max-Temporary-Tables
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamMaxTemporaryTables
+name: ms-Exch-ESE-Param-Max-Temporary-Tables
+schemaIDGUID: 2d09782c-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Max-Ver-Pages	  
+# The maximum version store size in 16-KB units.
+#
+dn: CN=ms-Exch-ESE-Param-Max-Ver-Pages,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Max-Ver-Pages
+distinguishedName: CN=ms-Exch-ESE-Param-Max-Ver-Pages,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11017
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Max-Ver-Pages
+adminDescription: ms-Exch-ESE-Param-Max-Ver-Pages
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamMaxVerPages
+name: ms-Exch-ESE-Param-Max-Ver-Pages
+schemaIDGUID: a02036b4-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Page-Fragment	
+# The maximum disk extent considered fragment, in pages.
+#
+dn: CN=ms-Exch-ESE-Param-Page-Fragment,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Page-Fragment
+distinguishedName: CN=ms-Exch-ESE-Param-Page-Fragment,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11080
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Page-Fragment
+adminDescription: ms-Exch-ESE-Param-Page-Fragment
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamPageFragment
+name: ms-Exch-ESE-Param-Page-Fragment
+schemaIDGUID: 2d097855-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Page-Temp-DB-Min 
+# The minimum size of a temporary database, in pages.
+#
+dn: CN=ms-Exch-ESE-Param-Page-Temp-DB-Min,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Page-Temp-DB-Min
+distinguishedName: CN=ms-Exch-ESE-Param-Page-Temp-DB-Min,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11079
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Page-Temp-DB-Min
+adminDescription: ms-Exch-ESE-Param-Page-Temp-DB-Min
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamPageTempDBMin
+name: ms-Exch-ESE-Param-Page-Temp-DB-Min
+schemaIDGUID: 2d097851-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Preferred-Max-Open-Tables	
+# The preferred maximum number of open directories.
+dn: CN=ms-Exch-ESE-Param-Preferred-Max-Open-Tables,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Preferred-Max-Open-Tables
+distinguishedName: CN=ms-Exch-ESE-Param-Preferred-Max-Open-Tables,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11018
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Preferred-Max-Open-Tables
+adminDescription: ms-Exch-ESE-Param-Preferred-Max-Open-Tables
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamPreferredMaxOpenTables
+name: ms-Exch-ESE-Param-Preferred-Max-Open-Tables
+schemaIDGUID: a04197a0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Preferred-Ver-Pages	
+# The preferred version store size in 16-KB units.
+#
+dn: CN=ms-Exch-ESE-Param-Preferred-Ver-Pages,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Preferred-Ver-Pages
+distinguishedName: CN=ms-Exch-ESE-Param-Preferred-Ver-Pages,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11019
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Preferred-Ver-Pages
+adminDescription: ms-Exch-ESE-Param-Preferred-Ver-Pages
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamPreferredVerPages
+name: ms-Exch-ESE-Param-Preferred-Ver-Pages
+schemaIDGUID: a062f88c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Start-Flush-Threshold	
+#
+dn: CN=ms-Exch-ESE-Param-Start-Flush-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Start-Flush-Threshold
+distinguishedName: CN=ms-Exch-ESE-Param-Start-Flush-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11056
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Start-Flush-Threshold
+adminDescription: ms-Exch-ESE-Param-Start-Flush-Threshold
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamStartFlushThreshold
+name: ms-Exch-ESE-Param-Start-Flush-Threshold
+schemaIDGUID: 92abc93e-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Stop-Flush-Threshold	
+#
+dn: CN=ms-Exch-ESE-Param-Stop-Flush-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Stop-Flush-Threshold
+distinguishedName: CN=ms-Exch-ESE-Param-Stop-Flush-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11057
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Stop-Flush-Threshold
+adminDescription: ms-Exch-ESE-Param-Stop-Flush-Threshold
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamStopFlushThreshold
+name: ms-Exch-ESE-Param-Stop-Flush-Threshold
+schemaIDGUID: 92c6031c-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-System-Path			
+# The path to check point file.
+dn: CN=ms-Exch-ESE-Param-System-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-System-Path
+distinguishedName: CN=ms-Exch-ESE-Param-System-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11022
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-System-Path
+adminDescription: ms-Exch-ESE-Param-System-Path
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchESEParamSystemPath
+name: ms-Exch-ESE-Param-System-Path
+schemaIDGUID: a086bbd2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Temp-Path	
+# The path to the temporary database.
+#
+dn: CN=ms-Exch-ESE-Param-Temp-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Temp-Path
+distinguishedName: CN=ms-Exch-ESE-Param-Temp-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11023
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Temp-Path
+adminDescription: ms-Exch-ESE-Param-Temp-Path
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchESEParamTempPath
+name: ms-Exch-ESE-Param-Temp-Path
+schemaIDGUID: a0a5ba64-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-ESE-Param-Wait-Log-Flush	
+# The wait time in milliseconds.
+#
+dn: CN=ms-Exch-ESE-Param-Wait-Log-Flush,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Wait-Log-Flush
+distinguishedName: CN=ms-Exch-ESE-Param-Wait-Log-Flush,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Wait-Log-Flush
+adminDescription: ms-Exch-ESE-Param-Wait-Log-Flush
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamWaitLogFlush
+name: ms-Exch-ESE-Param-Wait-Log-Flush
+schemaIDGUID: a0c71b50-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-ESE-Param-Zero-Database-During-Backup	
+# Overwrites deleted records/long values during backup.
+#
+dn: CN=ms-Exch-ESE-Param-Zero-Database-During-Backup,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-ESE-Param-Zero-Database-During-Backup
+distinguishedName: CN=ms-Exch-ESE-Param-Zero-Database-During-Backup,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11026
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-ESE-Param-Zero-Database-During-Backup
+adminDescription: ms-Exch-ESE-Param-Zero-Database-During-Backup
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchESEParamZeroDatabaseDuringBackup
+name: ms-Exch-ESE-Param-Zero-Database-During-Backup
+schemaIDGUID: a0e619e2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Exchange-Server-Link 
+# A link to an Exchange server that this object corresponds to.
+#
+dn: CN=ms-Exch-Exchange-Server-Link,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Exchange-Server-Link
+distinguishedName: CN=ms-Exch-Exchange-Server-Link,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.71
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1019
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Exchange-Server-Link
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Exchange-Server-Link
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchExchangeServerLink
+name: ms-Exch-Exchange-Server-Link
+schemaIDGUID: a1051874-b093-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Exchange-Site	  
+# Contains the DN to the site that this connection agreement is for.
+#
+dn: CN=ms-Exch-Exchange-Site,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Exchange-Site
+distinguishedName: CN=ms-Exch-Exchange-Site,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.85
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Exchange-Site
+adminDescription: ms-Exch-Exchange-Site
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchExchangeSite
+name: ms-Exch-Exchange-Site
+schemaIDGUID: 24d808f5-2439-11d3-aa66-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Expand-DLs-Locally  
+#
+dn: CN=ms-Exch-Expand-DLs-Locally,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Expand-DLs-Locally
+distinguishedName: CN=ms-Exch-Expand-DLs-Locally,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.201
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32932
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Expand-DLs-Locally
+adminDescription: ms-Exch-Expand-DLs-Locally
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: expandDLsLocally
+name: ms-Exch-Expand-DLs-Locally
+schemaIDGUID: a8df73fb-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Expansion-Server-Name	  
+#
+dn: CN=ms-Exch-Expansion-Server-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Expansion-Server-Name
+distinguishedName: CN=ms-Exch-Expansion-Server-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.49
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Expansion-Server-Name
+adminDescription: ms-Exch-Expansion-Server-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchExpansionServerName
+name: ms-Exch-Expansion-Server-Name
+schemaIDGUID: a1241706-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Expiration-Time	  
+#
+dn: CN=ms-Exch-Expiration-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Expiration-Time
+distinguishedName: CN=ms-Exch-Expiration-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.394
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32808
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Expiration-Time
+adminDescription: ms-Exch-Expiration-Time
+oMSyntax: 23
+searchFlags: 1
+lDAPDisplayName: expirationTime
+name: ms-Exch-Expiration-Time
+schemaIDGUID: bf967965-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Export-Containers	  
+#
+dn: CN=ms-Exch-Export-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Export-Containers
+distinguishedName: CN=ms-Exch-Export-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.111
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32933
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Export-Containers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Export-Containers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: exportContainers
+name: ms-Exch-Export-Containers
+schemaIDGUID: a8df73fc-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Export-Containers-BL	  
+#
+dn: CN=ms-Exch-Export-Containers-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Export-Containers-BL
+distinguishedName: CN=ms-Exch-Export-Containers-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1027
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1029
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Export-Containers-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Export-Containers-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchExportContainersBL
+name: ms-Exch-Export-Containers-BL
+schemaIDGUID: 2436ac3e-1d4e-11d3-aa5e-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Export-Containers-Linked 
+#
+dn: CN=ms-Exch-Export-Containers-Linked,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Export-Containers-Linked
+distinguishedName: CN=ms-Exch-Export-Containers-Linked,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1026
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1028
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Export-Containers-Linked
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Export-Containers-Linked
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchExportContainersLinked
+name: ms-Exch-Export-Containers-Linked
+schemaIDGUID: 3b7ea364-1d4d-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Export-Custom-Recipients 
+#
+dn: CN=ms-Exch-Export-Custom-Recipients,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Export-Custom-Recipients
+distinguishedName: CN=ms-Exch-Export-Custom-Recipients,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.307
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32934
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Export-Custom-Recipients
+adminDescription: ms-Exch-Export-Custom-Recipients
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: exportCustomRecipients
+name: ms-Exch-Export-Custom-Recipients
+schemaIDGUID: a8df73fd-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Export-DLs	 
+# A flag indicating whether distribution list (DL) names are
+# propagated to foreign systems via directory synchronization.
+#
+dn: CN=ms-Exch-Export-DLs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Export-DLs
+distinguishedName: CN=ms-Exch-Export-DLs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1004
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Export-DLs
+adminDescription: ms-Exch-Export-DLs
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchExportDLs
+name: ms-Exch-Export-DLs
+schemaIDGUID: a14577f2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Extension-Attribute-1	    
+#
+dn: CN=ms-Exch-Extension-Attribute-1,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-1
+distinguishedName: CN=ms-Exch-Extension-Attribute-1,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.423
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32813
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-1
+adminDescription: ms-Exch-Extension-Attribute-1
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute1
+name: ms-Exch-Extension-Attribute-1
+schemaIDGUID: bf967967-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-10 
+#
+dn: CN=ms-Exch-Extension-Attribute-10,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-10
+distinguishedName: CN=ms-Exch-Extension-Attribute-10,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.432
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32822
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-10
+adminDescription: ms-Exch-Extension-Attribute-10
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute10
+name: ms-Exch-Extension-Attribute-10
+schemaIDGUID: bf967968-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-11 
+#
+dn: CN=ms-Exch-Extension-Attribute-11,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-11
+distinguishedName: CN=ms-Exch-Extension-Attribute-11,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.599
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 2048
+mAPIID: 35927
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-11
+adminDescription: ms-Exch-Extension-Attribute-11
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute11
+name: ms-Exch-Extension-Attribute-11
+schemaIDGUID: 167757f6-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-12 
+#
+dn: CN=ms-Exch-Extension-Attribute-12,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-12
+distinguishedName: CN=ms-Exch-Extension-Attribute-12,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.600
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 2048
+mAPIID: 35928
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-12
+adminDescription: ms-Exch-Extension-Attribute-12
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute12
+name: ms-Exch-Extension-Attribute-12
+schemaIDGUID: 167757f7-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-13 
+#
+dn: CN=ms-Exch-Extension-Attribute-13,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-13
+distinguishedName: CN=ms-Exch-Extension-Attribute-13,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.601
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 2048
+mAPIID: 35929
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-13
+adminDescription: ms-Exch-Extension-Attribute-13
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute13
+name: ms-Exch-Extension-Attribute-13
+schemaIDGUID: 167757f8-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-14 Attribut
+#
+
+
+
+
+#
+# ms-Exch-Extension-Attribute-15	
+#
+dn: CN=ms-Exch-Extension-Attribute-15,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-15
+distinguishedName: CN=ms-Exch-Extension-Attribute-15,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.603
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 2048
+mAPIID: 35937
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-15
+adminDescription: ms-Exch-Extension-Attribute-15
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute15
+name: ms-Exch-Extension-Attribute-15
+schemaIDGUID: 167757fa-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-2		
+#
+dn: CN=ms-Exch-Extension-Attribute-2,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-2
+distinguishedName: CN=ms-Exch-Extension-Attribute-2,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.424
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32814
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-2
+adminDescription: ms-Exch-Extension-Attribute-2
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute2
+name: ms-Exch-Extension-Attribute-2
+schemaIDGUID: bf967969-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-3		
+#
+dn: CN=ms-Exch-Extension-Attribute-3,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-3
+distinguishedName: CN=ms-Exch-Extension-Attribute-3,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.425
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32815
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-3
+adminDescription: ms-Exch-Extension-Attribute-3
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute3
+name: ms-Exch-Extension-Attribute-3
+schemaIDGUID: bf96796a-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-4		
+#
+dn: CN=ms-Exch-Extension-Attribute-4,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-4
+distinguishedName: CN=ms-Exch-Extension-Attribute-4,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.426
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32816
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-4
+adminDescription: ms-Exch-Extension-Attribute-4
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute4
+name: ms-Exch-Extension-Attribute-4
+schemaIDGUID: bf96796b-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Extension-Attribute-5		
+#
+dn: CN=ms-Exch-Extension-Attribute-5,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-5
+distinguishedName: CN=ms-Exch-Extension-Attribute-5,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.427
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32817
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-5
+adminDescription: ms-Exch-Extension-Attribute-5
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute5
+name: ms-Exch-Extension-Attribute-5
+schemaIDGUID: bf96796c-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-6		
+#
+dn: CN=ms-Exch-Extension-Attribute-6,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-6
+distinguishedName: CN=ms-Exch-Extension-Attribute-6,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.428
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32818
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-6
+adminDescription: ms-Exch-Extension-Attribute-6
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute6
+name: ms-Exch-Extension-Attribute-6
+schemaIDGUID: bf96796d-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-7		
+#
+dn: CN=ms-Exch-Extension-Attribute-7,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-7
+distinguishedName: CN=ms-Exch-Extension-Attribute-7,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.429
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32819
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-7
+adminDescription: ms-Exch-Extension-Attribute-7
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute7
+name: ms-Exch-Extension-Attribute-7
+schemaIDGUID: bf96796e-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-8		
+#
+dn: CN=ms-Exch-Extension-Attribute-8,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-8
+distinguishedName: CN=ms-Exch-Extension-Attribute-8,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.430
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32820
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-8
+adminDescription: ms-Exch-Extension-Attribute-8
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute8
+name: ms-Exch-Extension-Attribute-8
+schemaIDGUID: bf96796f-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Extension-Attribute-9		
+#
+dn: CN=ms-Exch-Extension-Attribute-9,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Attribute-9
+distinguishedName: CN=ms-Exch-Extension-Attribute-9,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.431
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32821
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Attribute-9
+adminDescription: ms-Exch-Extension-Attribute-9
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: extensionAttribute9
+name: ms-Exch-Extension-Attribute-9
+schemaIDGUID: bf967970-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Extension-Data		
+#
+dn: CN=ms-Exch-Extension-Data,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Extension-Data
+distinguishedName: CN=ms-Exch-Extension-Data,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.228
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 32768
+mAPIID: 32936
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Extension-Data
+adminDescription: ms-Exch-Extension-Data
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: extensionData
+name: ms-Exch-Extension-Data
+schemaIDGUID: bf967971-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-FB-URL			
+#
+dn: CN=ms-Exch-FB-URL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-FB-URL
+distinguishedName: CN=ms-Exch-FB-URL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.10001
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+mAPIID: 35966
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-FB-URL
+adminDescription: ms-Exch-FB-URL
+oMSyntax: 64
+searchFlags: 1
+lDAPDisplayName: msExchFBURL
+name: ms-Exch-FB-URL
+schemaIDGUID: a166d8de-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-File-Version			
+#
+dn: CN=ms-Exch-File-Version,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-File-Version
+distinguishedName: CN=ms-Exch-File-Version,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.178
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 8
+mAPIID: 32940
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-File-Version
+adminDescription: ms-Exch-File-Version
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: fileVersion
+name: ms-Exch-File-Version
+schemaIDGUID: 167757fb-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Filter-Local-Addresses	
+#
+dn: CN=ms-Exch-Filter-Local-Addresses,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Filter-Local-Addresses
+distinguishedName: CN=ms-Exch-Filter-Local-Addresses,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.44
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32941
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Filter-Local-Addresses
+adminDescription: ms-Exch-Filter-Local-Addresses
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: filterLocalAddresses
+name: ms-Exch-Filter-Local-Addresses
+schemaIDGUID: a8df73fe-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-First-Instance		
+#
+dn: CN=ms-Exch-First-Instance,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-First-Instance
+distinguishedName: CN=ms-Exch-First-Instance,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11053
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-First-Instance
+adminDescription: ms-Exch-First-Instance
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchFirstInstance
+name: ms-Exch-First-Instance
+schemaIDGUID: 8a8f2908-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Folder-Affinity-Custom   
+#
+dn: CN=ms-Exch-Folder-Affinity-Custom,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Folder-Affinity-Custom
+distinguishedName: CN=ms-Exch-Folder-Affinity-Custom,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11090
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Folder-Affinity-Custom
+adminDescription: ms-Exch-Folder-Affinity-Custom
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchFolderAffinityCustom
+name: ms-Exch-Folder-Affinity-Custom
+schemaIDGUID: 5070257a-85b7-4ed4-b2e2-51f726684c58
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Folder-Affinity-List	   
+#
+dn: CN=ms-Exch-Folder-Affinity-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Folder-Affinity-List
+distinguishedName: CN=ms-Exch-Folder-Affinity-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11089
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Folder-Affinity-List
+adminDescription: ms-Exch-Folder-Affinity-List
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchFolderAffinityList
+name: ms-Exch-Folder-Affinity-List
+schemaIDGUID: 3592bc80-1117-4962-aa50-38c6e69bbb91
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Folder-Pathname	   
+#
+dn: CN=ms-Exch-Folder-Pathname,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Folder-Pathname
+distinguishedName: CN=ms-Exch-Folder-Pathname,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.337
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32772
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Folder-Pathname
+adminDescription: ms-Exch-Folder-Pathname
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: folderPathname
+name: ms-Exch-Folder-Pathname
+schemaIDGUID: f0f8ff8d-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Form-Data		   
+#
+dn: CN=ms-Exch-Form-Data,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Form-Data
+distinguishedName: CN=ms-Exch-Form-Data,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.607
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 35941
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Form-Data
+adminDescription: ms-Exch-Form-Data
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: formData
+name: ms-Exch-Form-Data
+schemaIDGUID: a8df7400-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Forwarding-Address	   
+# Contains an SMTP address that should be used as the mail forwarding
+# address of the object.
+#
+dn: CN=ms-Exch-Forwarding-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Forwarding-Address
+distinguishedName: CN=ms-Exch-Forwarding-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.606
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 35940
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Forwarding-Address
+adminDescription: ms-Exch-Forwarding-Address
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: forwardingAddress
+name: ms-Exch-Forwarding-Address
+schemaIDGUID: 167757ff-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Gateway-Local-Cred 
+#
+dn: CN=ms-Exch-Gateway-Local-Cred,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Gateway-Local-Cred
+distinguishedName: CN=ms-Exch-Gateway-Local-Cred,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.37
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 32944
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Gateway-Local-Cred
+adminDescription: ms-Exch-Gateway-Local-Cred
+oMSyntax: 22
+searchFlags: 0
+lDAPDisplayName: gatewayLocalCred
+name: ms-Exch-Gateway-Local-Cred
+schemaIDGUID: a8df7401-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Gateway-Local-Desig	 
+#
+dn: CN=ms-Exch-Gateway-Local-Desig,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Gateway-Local-Desig
+distinguishedName: CN=ms-Exch-Gateway-Local-Desig,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.29
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 32945
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Gateway-Local-Desig
+adminDescription: ms-Exch-Gateway-Local-Desig
+oMSyntax: 22
+searchFlags: 0
+lDAPDisplayName: gatewayLocalDesig
+name: ms-Exch-Gateway-Local-Desig
+schemaIDGUID: a8df7402-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Gateway-Proxy		 
+#
+dn: CN=ms-Exch-Gateway-Proxy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Gateway-Proxy
+distinguishedName: CN=ms-Exch-Gateway-Proxy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.302
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1123
+mAPIID: 32946
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Gateway-Proxy
+adminDescription: ms-Exch-Gateway-Proxy
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: gatewayProxy
+name: ms-Exch-Gateway-Proxy
+schemaIDGUID: 16775802-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Gateway-Routing-Tree	 
+# Contains the Gateway Address Resolution Table (GWART) for the site.
+#
+dn: CN=ms-Exch-Gateway-Routing-Tree,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Gateway-Routing-Tree
+distinguishedName: CN=ms-Exch-Gateway-Routing-Tree,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.167
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 32947
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Gateway-Routing-Tree
+adminDescription: ms-Exch-Gateway-Routing-Tree
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: gatewayRoutingTree
+name: ms-Exch-Gateway-Routing-Tree
+schemaIDGUID: a8df7403-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Grace-Period-After	
+# Defines a period, in seconds, for which the conference allows
+# attendees to continue after the scheduled termination.
+#
+dn: CN=ms-Exch-Grace-Period-After,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Grace-Period-After
+distinguishedName: CN=ms-Exch-Grace-Period-After,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9003
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Grace-Period-After
+adminDescription: ms-Exch-Grace-Period-After
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchGracePeriodAfter
+name: ms-Exch-Grace-Period-After
+schemaIDGUID: a1d6e764-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Grace-Period-Prior	
+# Defines a period, in seconds, for which clients are accepted into a
+# conference prior to the scheduled start time.
+#
+dn: CN=ms-Exch-Grace-Period-Prior,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Grace-Period-Prior
+distinguishedName: CN=ms-Exch-Grace-Period-Prior,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9002
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Grace-Period-Prior
+adminDescription: ms-Exch-Grace-Period-Prior
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchGracePeriodPrior
+name: ms-Exch-Grace-Period-Prior
+schemaIDGUID: a1f84850-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-GWART-Last-Modified	
+# Contains the time the Gateway Address Resolution Table (GWART) was
+# last modified.
+#
+dn: CN=ms-Exch-GWART-Last-Modified,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWART-Last-Modified
+distinguishedName: CN=ms-Exch-GWART-Last-Modified,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.260
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 32948
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWART-Last-Modified
+adminDescription: ms-Exch-GWART-Last-Modified
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: gWARTLastModified
+name: ms-Exch-GWART-Last-Modified
+schemaIDGUID: 8fa43470-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-GWise-API-Gateway   
+#
+dn: CN=ms-Exch-GWise-API-Gateway,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-API-Gateway
+distinguishedName: CN=ms-Exch-GWise-API-Gateway,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1045
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-API-Gateway
+adminDescription: ms-Exch-GWise-API-Gateway
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchGWiseAPIGateway
+name: ms-Exch-GWise-API-Gateway
+schemaIDGUID: c7e96933-bd80-44a2-a535-ec744ea5f54f
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-GWise-API-Gateway-Path  
+#
+dn: CN=ms-Exch-GWise-API-Gateway-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-API-Gateway-Path
+distinguishedName: CN=ms-Exch-GWise-API-Gateway-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1201
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-API-Gateway-Path
+adminDescription: ms-Exch-GWise-API-Gateway-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchGWiseAPIGatewayPath
+name: ms-Exch-GWise-API-Gateway-Path
+schemaIDGUID: 3b9d8dea-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-GWise-Filter-Type	  
+#
+dn: CN=ms-Exch-GWise-Filter-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-Filter-Type
+distinguishedName: CN=ms-Exch-GWise-Filter-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1205
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-Filter-Type
+adminDescription: ms-Exch-GWise-Filter-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchGWiseFilterType
+name: ms-Exch-GWise-Filter-Type
+schemaIDGUID: 3b9d8dee-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-GWise-Foreign-Domain	  
+#
+dn: CN=ms-Exch-GWise-Foreign-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-Foreign-Domain
+distinguishedName: CN=ms-Exch-GWise-Foreign-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1204
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-Foreign-Domain
+adminDescription: ms-Exch-GWise-Foreign-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchGWiseForeignDomain
+name: ms-Exch-GWise-Foreign-Domain
+schemaIDGUID: 3b9d8df3-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-GWise-Password	  
+#
+dn: CN=ms-Exch-GWise-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-Password
+distinguishedName: CN=ms-Exch-GWise-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1203
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-Password
+adminDescription: ms-Exch-GWise-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchGWisePassword
+name: ms-Exch-GWise-Password
+schemaIDGUID: 3b9d8df9-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-GWise-User-Id		  
+#
+dn: CN=ms-Exch-GWise-User-Id,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-GWise-User-Id
+distinguishedName: CN=ms-Exch-GWise-User-Id,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1202
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-GWise-User-Id
+adminDescription: ms-Exch-GWise-User-Id
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchGWiseUserId
+name: ms-Exch-GWise-User-Id
+schemaIDGUID: 3b9d8e00-2d93-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Heuristics		  
+# Contains special connector attributes, such as "allow system
+# messages".
+#
+dn: CN=ms-Exch-Heuristics,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Heuristics
+distinguishedName: CN=ms-Exch-Heuristics,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.452
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32951
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Heuristics
+adminDescription: ms-Exch-Heuristics
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: heuristics
+name: ms-Exch-Heuristics
+schemaIDGUID: bf967983-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Hide-DL-Membership   
+#
+dn: CN=ms-Exch-Hide-DL-Membership,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Hide-DL-Membership
+distinguishedName: CN=ms-Exch-Hide-DL-Membership,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.297
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32952
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Hide-DL-Membership
+adminDescription: ms-Exch-Hide-DL-Membership
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: hideDLMembership
+name: ms-Exch-Hide-DL-Membership
+schemaIDGUID: a8df7405-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Hide-From-Address-Lists  
+# Determines if the recipient appears in address lists.
+#
+dn: CN=ms-Exch-Hide-From-Address-Lists,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Hide-From-Address-Lists
+distinguishedName: CN=ms-Exch-Hide-From-Address-Lists,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.73
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Hide-From-Address-Lists
+adminDescription: ms-Exch-Hide-From-Address-Lists
+oMSyntax: 1
+searchFlags: 16
+lDAPDisplayName: msExchHideFromAddressLists
+name: ms-Exch-Hide-From-Address-Lists
+schemaIDGUID: a21c0b96-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Home-MDB  
+# The distinguished name of the MDB for this mailbox.
+#
+dn: CN=ms-Exch-Home-MDB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-MDB
+distinguishedName: CN=ms-Exch-Home-MDB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.244
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32774
+linkID: 32
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-MDB
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-MDB
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: homeMDB
+name: ms-Exch-Home-MDB
+schemaIDGUID: bf967987-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Home-MDB-BL 
+#
+dn: CN=ms-Exch-Home-MDB-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-MDB-BL
+distinguishedName: CN=ms-Exch-Home-MDB-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.393
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32788
+linkID: 33
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-MDB-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-MDB-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: homeMDBBL
+name: ms-Exch-Home-MDB-BL
+schemaIDGUID: bf967988-0de6-11d0-a285-00aa003049e2
+systemFlags: 1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Home-MTA    
+# Points to the MTA that services this object.
+#
+dn: CN=ms-Exch-Home-MTA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-MTA
+distinguishedName: CN=ms-Exch-Home-MTA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.171
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32775
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-MTA
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-MTA
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: homeMTA
+name: ms-Exch-Home-MTA
+schemaIDGUID: bf967989-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Home-Public-MDB    
+# The DN of the object for the home public MDB.
+#
+dn: CN=ms-Exch-Home-Public-MDB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-Public-MDB
+distinguishedName: CN=ms-Exch-Home-Public-MDB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11044
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-Public-MDB
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-Public-MDB
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchHomePublicMDB
+name: ms-Exch-Home-Public-MDB
+schemaIDGUID: a23fcedc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Home-Routing-Group	 
+#
+dn: CN=ms-Exch-Home-Routing-Group,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-Routing-Group
+distinguishedName: CN=ms-Exch-Home-Routing-Group,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12539
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1050
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-Routing-Group
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-Routing-Group
+oMSyntax: 127
+searchFlags: 1
+lDAPDisplayName: msExchHomeRoutingGroup
+name: ms-Exch-Home-Routing-Group
+schemaIDGUID: f649deed-1c26-4ed4-b639-f333a4850bc2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Home-Routing-Group-DN-BL	 
+# A backlink to the routing group that this object is a member of.
+#
+dn: CN=ms-Exch-Home-Routing-Group-DN-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-Routing-Group-DN-BL
+distinguishedName: CN=ms-Exch-Home-Routing-Group-DN-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12513
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1001
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-Routing-Group-DN-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-Routing-Group-DN-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchHomeRoutingGroupDNBL
+name: ms-Exch-Home-Routing-Group-DN-BL
+schemaIDGUID: a2612fc8-b093-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Home-Server-Name   
+#
+dn: CN=ms-Exch-Home-Server-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-Server-Name
+distinguishedName: CN=ms-Exch-Home-Server-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.47
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-Server-Name
+adminDescription: ms-Exch-Home-Server-Name
+oMSyntax: 64
+searchFlags: 25
+lDAPDisplayName: msExchHomeServerName
+name: ms-Exch-Home-Server-Name
+schemaIDGUID: a284f30e-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Home-Sync-Service  
+# Link to the Active Directory Connector (ADC) for this connection
+# agreement.
+#
+dn: CN=ms-Exch-Home-Sync-Service,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Home-Sync-Service
+distinguishedName: CN=ms-Exch-Home-Sync-Service,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.36
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 146
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Home-Sync-Service
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Home-Sync-Service
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchHomeSyncService
+name: ms-Exch-Home-Sync-Service
+schemaIDGUID: a2a3f1a0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-House-Identifier     
+#
+#dn: CN=ms-Exch-House-Identifier,${SCHEMADN}
+#objectClass: top
+#objectClass: attributeSchema
+#cn: ms-Exch-House-Identifier
+#distinguishedName: CN=ms-Exch-House-Identifier,${SCHEMADN}
+#attributeID: 1.2.840.113556.1.2.596
+#attributeSyntax: 2.5.5.12
+#isSingleValued: TRUE
+#rangeLower: 1
+#rangeUpper: 128
+#mAPIID: 35924
+#adminDisplayName: ms-Exch-House-Identifier
+#adminDescription: ms-Exch-House-Identifier
+#oMSyntax: 64
+#searchFlags: 0
+#lDAPDisplayName: msExchHouseIdentifier
+#name: ms-Exch-House-Identifier
+#schemaIDGUID: a8df7407-c5ea-11d1-bbcb-0080c76670c0
+#objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-HTTP-Pub-AB-Attributes   
+#
+dn: CN=ms-Exch-HTTP-Pub-AB-Attributes,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-HTTP-Pub-AB-Attributes
+distinguishedName: CN=ms-Exch-HTTP-Pub-AB-Attributes,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.516
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33193
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-HTTP-Pub-AB-Attributes
+adminDescription: ms-Exch-HTTP-Pub-AB-Attributes
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: hTTPPubABAttributes
+name: ms-Exch-HTTP-Pub-AB-Attributes
+schemaIDGUID: a8df7408-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-HTTP-Pub-GAL 
+#
+dn: CN=ms-Exch-HTTP-Pub-GAL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-HTTP-Pub-GAL
+distinguishedName: CN=ms-Exch-HTTP-Pub-GAL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.502
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33179
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-HTTP-Pub-GAL
+adminDescription: ms-Exch-HTTP-Pub-GAL
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: hTTPPubGAL
+name: ms-Exch-HTTP-Pub-GAL
+schemaIDGUID: a8df7409-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-HTTP-Pub-GAL-Limit	
+#
+dn: CN=ms-Exch-HTTP-Pub-GAL-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-HTTP-Pub-GAL-Limit
+distinguishedName: CN=ms-Exch-HTTP-Pub-GAL-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.503
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33180
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-HTTP-Pub-GAL-Limit
+adminDescription: ms-Exch-HTTP-Pub-GAL-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: hTTPPubGALLimit
+name: ms-Exch-HTTP-Pub-GAL-Limit
+schemaIDGUID: a8df740a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-HTTP-Pub-PF		
+#
+dn: CN=ms-Exch-HTTP-Pub-PF,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-HTTP-Pub-PF
+distinguishedName: CN=ms-Exch-HTTP-Pub-PF,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.505
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33182
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-HTTP-Pub-PF
+adminDescription: ms-Exch-HTTP-Pub-PF
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: hTTPPubPF
+name: ms-Exch-HTTP-Pub-PF
+schemaIDGUID: a8df740b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-HTTP-Servers		
+#
+dn: CN=ms-Exch-HTTP-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-HTTP-Servers
+distinguishedName: CN=ms-Exch-HTTP-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.517
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 33195
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-HTTP-Servers
+adminDescription: ms-Exch-HTTP-Servers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: hTTPServers
+name: ms-Exch-HTTP-Servers
+schemaIDGUID: a8df740c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IFS-Private-Enabled	
+# Determines whether private mailboxes are shared.
+dn: CN=ms-Exch-IFS-Private-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IFS-Private-Enabled
+distinguishedName: CN=ms-Exch-IFS-Private-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11029
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IFS-Private-Enabled
+adminDescription: ms-Exch-IFS-Private-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchIFSPrivateEnabled
+name: ms-Exch-IFS-Private-Enabled
+schemaIDGUID: a2e915d2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IFS-Private-Name   
+# The name of the private share.
+#
+dn: CN=ms-Exch-IFS-Private-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IFS-Private-Name
+distinguishedName: CN=ms-Exch-IFS-Private-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11033
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IFS-Private-Name
+adminDescription: ms-Exch-IFS-Private-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchIFSPrivateName
+name: ms-Exch-IFS-Private-Name
+schemaIDGUID: a30a76be-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IFS-Public-Enabled	
+# Determines whether public folders are shared.
+#
+dn: CN=ms-Exch-IFS-Public-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IFS-Public-Enabled
+distinguishedName: CN=ms-Exch-IFS-Public-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11050
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IFS-Public-Enabled
+adminDescription: ms-Exch-IFS-Public-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchIFSPublicEnabled
+name: ms-Exch-IFS-Public-Enabled
+schemaIDGUID: a32bd7aa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IFS-Public-Name 
+# The name of the public share.
+#
+dn: CN=ms-Exch-IFS-Public-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IFS-Public-Name
+distinguishedName: CN=ms-Exch-IFS-Public-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11051
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IFS-Public-Name
+adminDescription: ms-Exch-IFS-Public-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchIFSPublicName
+name: ms-Exch-IFS-Public-Name
+schemaIDGUID: a34d3896-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IMAP-OWA-URL-Prefix-Override	
+#
+dn: CN=ms-Exch-IMAP-OWA-URL-Prefix-Override,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IMAP-OWA-URL-Prefix-Override
+distinguishedName: CN=ms-Exch-IMAP-OWA-URL-Prefix-Override,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50213
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IMAP-OWA-URL-Prefix-Override
+adminDescription: ms-Exch-IMAP-OWA-URL-Prefix-Override
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchIMAPOWAURLPrefixOverride
+name: ms-Exch-IMAP-OWA-URL-Prefix-Override
+schemaIDGUID: 5e26dd2a-9b0a-4219-8183-20ad44f5cbdf
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Imported-From	     
+# Contains the DN to the connecter from which this object is imported.
+#
+dn: CN=ms-Exch-Imported-From,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Imported-From
+distinguishedName: CN=ms-Exch-Imported-From,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.263
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32834
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Imported-From
+adminDescription: ms-Exch-Imported-From
+oMSyntax: 64
+searchFlags: 9
+lDAPDisplayName: importedFrom
+name: ms-Exch-Imported-From
+schemaIDGUID: bf96798a-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Import-Container 
+#
+dn: CN=ms-Exch-Import-Container,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Import-Container
+distinguishedName: CN=ms-Exch-Import-Container,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.110
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32954
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Import-Container
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Import-Container
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: importContainer
+name: ms-Exch-Import-Container
+schemaIDGUID: a8df740d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Import-Container-Linked
+#
+dn: CN=ms-Exch-Import-Container-Linked,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Import-Container-Linked
+distinguishedName: CN=ms-Exch-Import-Container-Linked,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1028
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1032
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Import-Container-Linked
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Import-Container-Linked
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchImportContainerLinked
+name: ms-Exch-Import-Container-Linked
+schemaIDGUID: 9ff15c4c-1ec9-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-ACL	
+# A multivalued list of access control entries (ACEs) for Instant
+# Messaging.
+#
+dn: CN=ms-Exch-IM-ACL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-ACL
+distinguishedName: CN=ms-Exch-IM-ACL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7031
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-ACL
+adminDescription: ms-Exch-IM-ACL
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchIMACL
+name: ms-Exch-IM-ACL
+schemaIDGUID: 06551010-2845-11d3-aa68-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IM-Address 
+# A representation (resembling e-mail) of the public URL for a user
+# that is enabled for Instant Messaging.
+#
+dn: CN=ms-Exch-IM-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Address
+distinguishedName: CN=ms-Exch-IM-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7038
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Address
+adminDescription: ms-Exch-IM-Address
+oMSyntax: 19
+searchFlags: 1
+lDAPDisplayName: msExchIMAddress
+name: ms-Exch-IM-Address
+schemaIDGUID: cbbd3752-b8d8-47dc-92ee-ab488c1af969
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-DB-Log-Path     
+# States the directory path root for all database transaction log
+# files.
+#
+dn: CN=ms-Exch-IM-DB-Log-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-DB-Log-Path
+distinguishedName: CN=ms-Exch-IM-DB-Log-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7016
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 1024
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-DB-Log-Path
+adminDescription: ms-Exch-IM-DB-Log-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchIMDBLogPath
+name: ms-Exch-IM-DB-Log-Path
+schemaIDGUID: a4394164-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IM-DB-Path   
+# States the directory path root for all database files for a
+# particular server.
+#
+dn: CN=ms-Exch-IM-DB-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-DB-Path
+distinguishedName: CN=ms-Exch-IM-DB-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7015
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 1024
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-DB-Path
+adminDescription: ms-Exch-IM-DB-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchIMDBPath
+name: ms-Exch-IM-DB-Path
+schemaIDGUID: a45aa250-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Firewall-Type 
+# Describes the type of firewall entry for this firewall object.
+#
+dn: CN=ms-Exch-IM-Firewall-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Firewall-Type
+distinguishedName: CN=ms-Exch-IM-Firewall-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7028
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Firewall-Type
+adminDescription: ms-Exch-IM-Firewall-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchIMFirewallType
+name: ms-Exch-IM-Firewall-Type
+schemaIDGUID: 06550ffc-2845-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IM-Host-Name 
+# The host name for the Instant Messaging virtual server.
+#
+dn: CN=ms-Exch-IM-Host-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Host-Name
+distinguishedName: CN=ms-Exch-IM-Host-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7034
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Host-Name
+adminDescription: ms-Exch-IM-Host-Name
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchIMHostName
+name: ms-Exch-IM-Host-Name
+schemaIDGUID: 807b6084-439b-11d3-aa72-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-IP-Range 
+# A multivalued attribute that lists IP ranges that are valid for the
+# Instant Messaging firewall.
+dn: CN=ms-Exch-IM-IP-Range,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-IP-Range
+distinguishedName: CN=ms-Exch-IM-IP-Range,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7030
+attributeSyntax: 2.5.5.16
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-IP-Range
+adminDescription: ms-Exch-IM-IP-Range
+oMSyntax: 65
+searchFlags: 0
+lDAPDisplayName: msExchIMIPRange
+name: ms-Exch-IM-IP-Range
+schemaIDGUID: 0655100b-2845-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IM-Meta-Physical-URL	     
+# The public URL for a user that is enabled for Instant Messaging.
+#
+dn: CN=ms-Exch-IM-Meta-Physical-URL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Meta-Physical-URL
+distinguishedName: CN=ms-Exch-IM-Meta-Physical-URL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7035
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Meta-Physical-URL
+adminDescription: ms-Exch-IM-Meta-Physical-URL
+oMSyntax: 19
+searchFlags: 1
+lDAPDisplayName: msExchIMMetaPhysicalURL
+name: ms-Exch-IM-Meta-Physical-URL
+schemaIDGUID: 8e7a93a3-5a7c-11d3-aa78-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-IM-Physical-URL	
+# The private URL for a user that is enabled for Instant Messaging.
+#
+dn: CN=ms-Exch-IM-Physical-URL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Physical-URL
+distinguishedName: CN=ms-Exch-IM-Physical-URL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7036
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Physical-URL
+adminDescription: ms-Exch-IM-Physical-URL
+oMSyntax: 19
+searchFlags: 1
+lDAPDisplayName: msExchIMPhysicalURL
+name: ms-Exch-IM-Physical-URL
+schemaIDGUID: 8e7a93a8-5a7c-11d3-aa78-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Proxy 
+# The proxy name for the Instant Messaging firewall.
+#
+dn: CN=ms-Exch-IM-Proxy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Proxy
+distinguishedName: CN=ms-Exch-IM-Proxy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7029
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Proxy
+adminDescription: ms-Exch-IM-Proxy
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchIMProxy
+name: ms-Exch-IM-Proxy
+schemaIDGUID: 06551002-2845-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Server-Hosts-Users	 
+# States whether an Instant Messaging virtual server can host users.
+#
+dn: CN=ms-Exch-IM-Server-Hosts-Users,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Server-Hosts-Users
+distinguishedName: CN=ms-Exch-IM-Server-Hosts-Users,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7025
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Server-Hosts-Users
+adminDescription: ms-Exch-IM-Server-Hosts-Users
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchIMServerHostsUsers
+name: ms-Exch-IM-Server-Hosts-Users
+schemaIDGUID: 8d6b1af6-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Server-IIS-Id  
+# The Microsoft Internet Information Services (IIS) Web Server
+# Instance in the metabase.
+#
+dn: CN=ms-Exch-IM-Server-IIS-Id,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Server-IIS-Id
+distinguishedName: CN=ms-Exch-IM-Server-IIS-Id,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7023
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 1
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Server-IIS-Id
+adminDescription: ms-Exch-IM-Server-IIS-Id
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchIMServerIISId
+name: ms-Exch-IM-Server-IIS-Id
+schemaIDGUID: 8d3444e0-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Server-Name   
+#
+dn: CN=ms-Exch-IM-Server-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Server-Name
+distinguishedName: CN=ms-Exch-IM-Server-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7024
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Server-Name
+adminDescription: ms-Exch-IM-Server-Name
+oMSyntax: 64
+searchFlags: 1
+lDAPDisplayName: msExchIMServerName
+name: ms-Exch-IM-Server-Name
+schemaIDGUID: 8d4e7ebe-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IM-Virtual-Server   
+# The DN of the Instant Messaging home server.
+#
+dn: CN=ms-Exch-IM-Virtual-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IM-Virtual-Server
+distinguishedName: CN=ms-Exch-IM-Virtual-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7037
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IM-Virtual-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-IM-Virtual-Server
+oMSyntax: 127
+searchFlags: 1
+lDAPDisplayName: msExchIMVirtualServer
+name: ms-Exch-IM-Virtual-Server
+schemaIDGUID: 41e8fd82-8f37-4e56-a44a-33a3e6b7526c
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Inbound-Sites	
+#
+dn: CN=ms-Exch-Inbound-Sites,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Inbound-Sites
+distinguishedName: CN=ms-Exch-Inbound-Sites,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.71
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32956
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Inbound-Sites
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Inbound-Sites
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: inboundSites
+name: ms-Exch-Inbound-Sites
+schemaIDGUID: a8df7414-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Incoming-Connection-Timeout	      
+# The maximum length of time for incoming connections.
+#
+dn: CN=ms-Exch-Incoming-Connection-Timeout,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Incoming-Connection-Timeout
+distinguishedName: CN=ms-Exch-Incoming-Connection-Timeout,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2015
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Incoming-Connection-Timeout
+adminDescription: ms-Exch-Incoming-Connection-Timeout
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchIncomingConnectionTimeout
+name: ms-Exch-Incoming-Connection-Timeout
+schemaIDGUID: a64cedca-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Incoming-Msg-Size-Limit	
+#
+dn: CN=ms-Exch-Incoming-Msg-Size-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Incoming-Msg-Size-Limit
+distinguishedName: CN=ms-Exch-Incoming-Msg-Size-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.491
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33168
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Incoming-Msg-Size-Limit
+adminDescription: ms-Exch-Incoming-Msg-Size-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: incomingMsgSizeLimit
+name: ms-Exch-Incoming-Msg-Size-Limit
+schemaIDGUID: 1677581a-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Inconsistent-State		
+#
+dn: CN=ms-Exch-Inconsistent-State,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Inconsistent-State
+distinguishedName: CN=ms-Exch-Inconsistent-State,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.96
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Inconsistent-State
+adminDescription: ms-Exch-Inconsistent-State
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchInconsistentState
+name: ms-Exch-Inconsistent-State
+schemaIDGUID: 1d80475f-e7b4-4005-af4d-82bcbf407c3c
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-INSAdmin 
+#
+dn: CN=ms-Exch-INSAdmin,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-INSAdmin
+distinguishedName: CN=ms-Exch-INSAdmin,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.543
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33221
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-INSAdmin
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-INSAdmin
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: iNSAdmin
+name: ms-Exch-INSAdmin
+schemaIDGUID: a8df7416-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Installed-Components		 
+# Contains a list of installed components on a given server.
+#
+dn: CN=ms-Exch-Installed-Components,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Installed-Components
+distinguishedName: CN=ms-Exch-Installed-Components,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50024
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Installed-Components
+adminDescription: ms-Exch-Installed-Components
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchInstalledComponents
+name: ms-Exch-Installed-Components
+schemaIDGUID: 99f5865d-12e8-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Install-Path		
+#
+dn: CN=ms-Exch-Install-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Install-Path
+distinguishedName: CN=ms-Exch-Install-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50019
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Install-Path
+adminDescription: ms-Exch-Install-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchInstallPath
+name: ms-Exch-Install-Path
+schemaIDGUID: 8a23df36-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Internet-Encoding    
+#
+dn: CN=ms-Exch-Internet-Encoding,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Internet-Encoding
+distinguishedName: CN=ms-Exch-Internet-Encoding,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.551
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 14961
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Internet-Encoding
+adminDescription: ms-Exch-Internet-Encoding
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: internetEncoding
+name: ms-Exch-Internet-Encoding
+schemaIDGUID: 1677581d-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Internet-Name	       
+# The data conference Internet name.
+#
+dn: CN=ms-Exch-Internet-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Internet-Name
+distinguishedName: CN=ms-Exch-Internet-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9019
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Internet-Name
+adminDescription: ms-Exch-Internet-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchInternetName
+name: ms-Exch-Internet-Name
+schemaIDGUID: a670b110-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Inter-Org-Address-Type	
+# 
+#
+dn: CN=ms-Exch-Inter-Org-Address-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Inter-Org-Address-Type
+distinguishedName: CN=ms-Exch-Inter-Org-Address-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.94
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Inter-Org-Address-Type
+adminDescription: ms-Exch-Inter-Org-Address-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchInterOrgAddressType
+name: ms-Exch-Inter-Org-Address-Type
+schemaIDGUID: 3836c80b-8cee-4413-9e65-e937c1aed10f
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-IP-Address   
+#
+dn: CN=ms-Exch-IP-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IP-Address
+distinguishedName: CN=ms-Exch-IP-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5050
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IP-Address
+adminDescription: ms-Exch-IP-Address
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchIPAddress
+name: ms-Exch-IP-Address
+schemaIDGUID: 8b46be1a-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-IP-Security  
+# Restricts IP connections to this resource.
+#
+dn: CN=ms-Exch-IP-Security,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-IP-Security
+distinguishedName: CN=ms-Exch-IP-Security,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2013
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-IP-Security
+adminDescription: ms-Exch-IP-Security
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchIPSecurity
+name: ms-Exch-IP-Security
+schemaIDGUID: a68fafa2-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Is-Bridgehead-Site	
+# A flag to determine whether non-mailbox associated objects are
+# replicated over this particular connection agreement.
+#
+dn: CN=ms-Exch-Is-Bridgehead-Site,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Is-Bridgehead-Site
+distinguishedName: CN=ms-Exch-Is-Bridgehead-Site,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.35
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Is-Bridgehead-Site
+adminDescription: ms-Exch-Is-Bridgehead-Site
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchIsBridgeheadSite
+name: ms-Exch-Is-Bridgehead-Site
+schemaIDGUID: a6b1108e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Is-Config-CA		
+# Determines if this is a configuration Connection Agreement.
+#
+dn: CN=ms-Exch-Is-Config-CA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Is-Config-CA
+distinguishedName: CN=ms-Exch-Is-Config-CA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.79
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Is-Config-CA
+adminDescription: ms-Exch-Is-Config-CA
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchIsConfigCA
+name: ms-Exch-Is-Config-CA
+schemaIDGUID: 910f526c-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-KCC-Status	      
+#
+dn: CN=ms-Exch-KCC-Status,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-KCC-Status
+distinguishedName: CN=ms-Exch-KCC-Status,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.237
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+mAPIID: 32962
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-KCC-Status
+adminDescription: ms-Exch-KCC-Status
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: kCCStatus
+name: ms-Exch-KCC-Status
+schemaIDGUID: 5fd424ae-1262-11d0-a060-00aa006c33ed
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-KM-Server	      
+#
+dn: CN=ms-Exch-KM-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-KM-Server
+distinguishedName: CN=ms-Exch-KM-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.440
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 32781
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-KM-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-KM-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: kMServer
+name: ms-Exch-KM-Server
+schemaIDGUID: 1677581e-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-LabeledURI	      
+#
+#dn: CN=ms-Exch-LabeledURI,${SCHEMADN}
+#objectClass: top
+#objectClass: attributeSchema
+#cn: ms-Exch-LabeledURI
+#distinguishedName: CN=ms-Exch-LabeledURI,${SCHEMADN}
+#attributeID: 1.2.840.113556.1.2.593
+#attributeSyntax: 2.5.5.12
+#isSingleValued: FALSE
+#rangeLower: 1
+#rangeUpper: 1024
+#mAPIID: 35921
+#adminDisplayName: ms-Exch-LabeledURI
+#adminDescription: ms-Exch-LabeledURI
+#oMSyntax: 64
+#searchFlags: 0
+#lDAPDisplayName: msExchLabeledURI
+#name: ms-Exch-LabeledURI
+#schemaIDGUID: 16775820-47f3-11d1-a9c3-0000f80367c1
+#attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+#objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Language	      
+#
+dn: CN=ms-Exch-Language,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Language
+distinguishedName: CN=ms-Exch-Language,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.467
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33144
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Language
+adminDescription: ms-Exch-Language
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: languageCode
+name: ms-Exch-Language
+schemaIDGUID: bf967994-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Language-ISO639     
+# The ISO-639 language code identifying a user's language.
+#
+dn: CN=ms-Exch-Language-ISO639,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Language-ISO639
+distinguishedName: CN=ms-Exch-Language-ISO639,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.616
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 35948
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Language-ISO639
+adminDescription: ms-Exch-Language-ISO639
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: language
+name: ms-Exch-Language-ISO639
+schemaIDGUID: 16775821-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-LDAP-Search-Cfg     
+#
+dn: CN=ms-Exch-LDAP-Search-Cfg,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-LDAP-Search-Cfg
+distinguishedName: CN=ms-Exch-LDAP-Search-Cfg,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.552
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 35869
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-LDAP-Search-Cfg
+adminDescription: ms-Exch-LDAP-Search-Cfg
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: lDAPSearchCfg
+name: ms-Exch-LDAP-Search-Cfg
+schemaIDGUID: a8df7417-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Legacy-Account      
+#
+dn: CN=ms-Exch-Legacy-Account,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Legacy-Account
+distinguishedName: CN=ms-Exch-Legacy-Account,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50040
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Legacy-Account
+adminDescription: ms-Exch-Legacy-Account
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchLegacyAccount
+name: ms-Exch-Legacy-Account
+schemaIDGUID: 974c99e1-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Legacy-Domain	      
+#
+dn: CN=ms-Exch-Legacy-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Legacy-Domain
+distinguishedName: CN=ms-Exch-Legacy-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50041
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Legacy-Domain
+adminDescription: ms-Exch-Legacy-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchLegacyDomain
+name: ms-Exch-Legacy-Domain
+schemaIDGUID: 974c99ea-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Legacy-PW    
+#
+dn: CN=ms-Exch-Legacy-PW,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Legacy-PW
+distinguishedName: CN=ms-Exch-Legacy-PW,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50042
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Legacy-PW
+adminDescription: ms-Exch-Legacy-PW
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchLegacyPW
+name: ms-Exch-Legacy-PW
+schemaIDGUID: 974c99f2-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Line-Wrap    
+#
+dn: CN=ms-Exch-Line-Wrap,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Line-Wrap
+distinguishedName: CN=ms-Exch-Line-Wrap,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.449
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32964
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Line-Wrap
+adminDescription: ms-Exch-Line-Wrap
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: lineWrap
+name: ms-Exch-Line-Wrap
+schemaIDGUID: a8df7418-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-List-Public  
+# Lists public data conferences.
+#
+dn: CN=ms-Exch-List-Public,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-List-Public
+distinguishedName: CN=ms-Exch-List-Public,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9011
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-List-Public
+adminDescription: ms-Exch-List-Public
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchListPublic
+name: ms-Exch-List-Public
+schemaIDGUID: a6f634c0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-List-Public-Folders	
+#
+dn: CN=ms-Exch-List-Public-Folders,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-List-Public-Folders
+distinguishedName: CN=ms-Exch-List-Public-Folders,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.592
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35920
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-List-Public-Folders
+adminDescription: ms-Exch-List-Public-Folders
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: listPublicFolders
+name: ms-Exch-List-Public-Folders
+schemaIDGUID: a8df7419-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Locales   
+# The set of locales that determine client sort order.
+#
+dn: CN=ms-Exch-Locales,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Locales
+distinguishedName: CN=ms-Exch-Locales,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50017
+attributeSyntax: 2.5.5.9
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Locales
+adminDescription: ms-Exch-Locales
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchLocales
+name: ms-Exch-Locales
+schemaIDGUID: a738f698-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-Bridge-Head	 
+#
+dn: CN=ms-Exch-Local-Bridge-Head,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Local-Bridge-Head
+distinguishedName: CN=ms-Exch-Local-Bridge-Head,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.311
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 32966
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-Bridge-Head
+adminDescription: ms-Exch-Local-Bridge-Head
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: localBridgeHead
+name: ms-Exch-Local-Bridge-Head
+schemaIDGUID: a8df741a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-Bridge-Head-Address  
+#
+dn: CN=ms-Exch-Local-Bridge-Head-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Local-Bridge-Head-Address
+distinguishedName: CN=ms-Exch-Local-Bridge-Head-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.225
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 1118
+mAPIID: 32967
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-Bridge-Head-Address
+adminDescription: ms-Exch-Local-Bridge-Head-Address
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: localBridgeHeadAddress
+name: ms-Exch-Local-Bridge-Head-Address
+schemaIDGUID: a8df741b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-Domains	  
+#
+dn: CN=ms-Exch-Local-Domains,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Local-Domains
+distinguishedName: CN=ms-Exch-Local-Domains,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50032
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-Domains
+adminDescription: ms-Exch-Local-Domains
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchLocalDomains
+name: ms-Exch-Local-Domains
+schemaIDGUID: ab3a1ac7-1df5-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-Initial-Turn  
+#
+dn: CN=ms-Exch-Local-Initial-Turn,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Local-Initial-Turn
+distinguishedName: CN=ms-Exch-Local-Initial-Turn,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.39
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32968
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-Initial-Turn
+adminDescription: ms-Exch-Local-Initial-Turn
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: localInitialTurn
+name: ms-Exch-Local-Initial-Turn
+schemaIDGUID: a8df741c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Local-Name	      
+# The data conference local name.
+#
+dn: CN=ms-Exch-Local-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Local-Name
+distinguishedName: CN=ms-Exch-Local-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9017
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Local-Name
+adminDescription: ms-Exch-Local-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchLocalName
+name: ms-Exch-Local-Name
+schemaIDGUID: a7153352-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Logon-ACL	
+#
+dn: CN=ms-Exch-Logon-ACL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Logon-ACL
+distinguishedName: CN=ms-Exch-Logon-ACL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5057
+attributeSyntax: 2.5.5.15
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Logon-ACL
+adminDescription: ms-Exch-Logon-ACL
+oMSyntax: 66
+searchFlags: 0
+lDAPDisplayName: msExchLogonACL
+name: ms-Exch-Logon-ACL
+schemaIDGUID: 7acf216d-1f42-48ec-b1bb-6ca281fe5b00
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Logon-Method 
+# Specifies the logon method for clear text logons.
+#
+dn: CN=ms-Exch-Logon-Method,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Logon-Method
+distinguishedName: CN=ms-Exch-Logon-Method,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15002
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Logon-Method
+adminDescription: ms-Exch-Logon-Method
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchLogonMethod
+name: ms-Exch-Logon-Method
+schemaIDGUID: 8bcc41ca-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Log-Filename 
+#
+dn: CN=ms-Exch-Log-Filename,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Log-Filename
+distinguishedName: CN=ms-Exch-Log-Filename,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.192
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 32970
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Log-Filename
+adminDescription: ms-Exch-Log-Filename
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: logFilename
+name: ms-Exch-Log-Filename
+schemaIDGUID: a8df741d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Log-Rollover-Interval	
+#
+dn: CN=ms-Exch-Log-Rollover-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Log-Rollover-Interval
+distinguishedName: CN=ms-Exch-Log-Rollover-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.348
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32971
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Log-Rollover-Interval
+adminDescription: ms-Exch-Log-Rollover-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: logRolloverInterval
+name: ms-Exch-Log-Rollover-Interval
+schemaIDGUID: bf9679a7-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Log-Type    
+# The log formats that this resource writes to.
+dn: CN=ms-Exch-Log-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Log-Type
+distinguishedName: CN=ms-Exch-Log-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2005
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Log-Type
+adminDescription: ms-Exch-Log-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchLogType
+name: ms-Exch-Log-Type
+schemaIDGUID: a75a5784-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Mailbox-Folder-Set	  
+#
+dn: CN=ms-Exch-Mailbox-Folder-Set,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Folder-Set
+distinguishedName: CN=ms-Exch-Mailbox-Folder-Set,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11091
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Folder-Set
+adminDescription: ms-Exch-Mailbox-Folder-Set
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxFolderSet
+name: ms-Exch-Mailbox-Folder-Set
+schemaIDGUID: d72941ba-ffd0-4d8e-bb85-97713440c8a3
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Guid		  
+# The GUID of the user's mailbox.
+#
+dn: CN=ms-Exch-Mailbox-Guid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Guid
+distinguishedName: CN=ms-Exch-Mailbox-Guid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11058
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 16
+rangeUpper: 16
+mAPIID: 35955
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Guid
+adminDescription: ms-Exch-Mailbox-Guid
+oMSyntax: 4
+searchFlags: 9
+lDAPDisplayName: msExchMailboxGuid
+name: ms-Exch-Mailbox-Guid
+schemaIDGUID: 9333af48-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Activation-Schedule	
+# When the mailbox clean process should be started.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Activation-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Activation-Schedule
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Activation-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50067
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Activation-Schedule
+adminDescription: ms-Exch-Mailbox-Manager-Activation-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerActivationSchedule
+name: ms-Exch-Mailbox-Manager-Activation-Schedule
+schemaIDGUID: 829122d7-25b1-4be6-a2e3-d8453c950938
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Activation-Style	
+#
+dn: CN=ms-Exch-Mailbox-Manager-Activation-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Activation-Style
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Activation-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50068
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Activation-Style
+adminDescription: ms-Exch-Mailbox-Manager-Activation-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerActivationStyle
+name: ms-Exch-Mailbox-Manager-Activation-Style
+schemaIDGUID: 9ea95949-7d74-49cd-af09-3db0870e535e
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Admin-Mode	 
+# The summary mode for this policy (MCASM_NONE, MCASM_SUMMARY_ONLY,
+# MCASM_DETAILED_REPORT).
+#
+dn: CN=ms-Exch-Mailbox-Manager-Admin-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Admin-Mode
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Admin-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50077
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Admin-Mode
+adminDescription: ms-Exch-Mailbox-Manager-Admin-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerAdminMode
+name: ms-Exch-Mailbox-Manager-Admin-Mode
+schemaIDGUID: 9a6b371e-a3e7-4266-9b7b-2ce454336f90
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Age-Limit   
+# The age at which messages larger than the specified size limit are
+# deleted.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Age-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Age-Limit
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Age-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50081
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Age-Limit
+adminDescription: ms-Exch-Mailbox-Manager-Age-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerAgeLimit
+name: ms-Exch-Mailbox-Manager-Age-Limit
+schemaIDGUID: cd63db2c-8aa9-4a14-941b-1b59fdcaafbd
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Custom-Message    
+# Indicates that a custom message is being used.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Custom-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Custom-Message
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Custom-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50070
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Custom-Message
+adminDescription: ms-Exch-Mailbox-Manager-Custom-Message
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerCustomMessage
+name: ms-Exch-Mailbox-Manager-Custom-Message
+schemaIDGUID: 8681f0bc-24d6-4d58-bc16-62f73cd5bedb
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Folder-Settings	
+# Settings for each folder or store (Enabled, Folder-Name, Age-Limit,
+# Size-Limit). A limit of -1 should be interpreted as "Any".
+#
+dn: CN=ms-Exch-Mailbox-Manager-Folder-Settings,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Folder-Settings
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Folder-Settings,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50078
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Folder-Settings
+adminDescription: ms-Exch-Mailbox-Manager-Folder-Settings
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerFolderSettings
+name: ms-Exch-Mailbox-Manager-Folder-Settings
+schemaIDGUID: a57cf645-4b12-4ee4-a6eb-fce022068ffd
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Keep-Message-Classes	 
+# The message classes that should not be deleted.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Keep-Message-Classes,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Keep-Message-Classes
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Keep-Message-Classes,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50074
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Keep-Message-Classes
+adminDescription: ms-Exch-Mailbox-Manager-Keep-Message-Classes
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerKeepMessageClasses
+name: ms-Exch-Mailbox-Manager-Keep-Message-Classes
+schemaIDGUID: 0044d40c-6a24-4b57-abce-f555cc724c8e
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Mode 
+# Cleanup mode for this policy (MCACM_AUDIT,
+# MCACM_CLEANMCADM_DELETED_ITEMS, MCADM_SYSTEM_CLEANUP,
+# MCADM_JUST_DELETE).
+#
+dn: CN=ms-Exch-Mailbox-Manager-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Mode
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50075
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Mode
+adminDescription: ms-Exch-Mailbox-Manager-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerMode
+name: ms-Exch-Mailbox-Manager-Mode
+schemaIDGUID: 9bd7499b-282b-4eb6-a40e-7d044d896741
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Report-Recipient			   
+# The recipient of summary reports.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Report-Recipient,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Report-Recipient
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Report-Recipient,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50076
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Report-Recipient
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Mailbox-Manager-Report-Recipient
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerReportRecipient
+name: ms-Exch-Mailbox-Manager-Report-Recipient
+schemaIDGUID: 445791fb-e6fc-48dd-aad5-32e32c9059d9
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Send-User-Notification-Mail	
+# Sends a notification to the user after a clean operation.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Send-User-Notification-Mail,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Send-User-Notification-Mail,CN=S
+attributeID: 1.2.840.113556.1.4.7000.102.50069
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail
+adminDescription: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerSendUserNotificationMail
+name: ms-Exch-Mailbox-Manager-Send-User-Notification-Mail
+schemaIDGUID: d2888db3-2b0d-4d6a-831e-4efdfc036584
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Size-Limit   
+# Messages larger than this size will be deleted automatically when
+# their age exceeds the age limit.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Size-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Size-Limit
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Size-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50080
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Size-Limit
+adminDescription: ms-Exch-Mailbox-Manager-Size-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerSizeLimit
+name: ms-Exch-Mailbox-Manager-Size-Limit
+schemaIDGUID: 92d9302b-76bd-4156-95a1-f5b6a1463eb4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-Size-Limit-Enabled	     
+# Determines if a size limit is in effect.
+#
+dn: CN=ms-Exch-Mailbox-Manager-Size-Limit-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-Size-Limit-Enabled
+distinguishedName: CN=ms-Exch-Mailbox-Manager-Size-Limit-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50079
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-Size-Limit-Enabled
+adminDescription: ms-Exch-Mailbox-Manager-Size-Limit-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerSizeLimitEnabled
+name: ms-Exch-Mailbox-Manager-Size-Limit-Enabled
+schemaIDGUID: 1563eae5-3ac1-4274-9e59-7d2fcc836f82
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-User-Message-Body	
+# The mail notification message body.
+#
+dn: CN=ms-Exch-Mailbox-Manager-User-Message-Body,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-User-Message-Body
+distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Body,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50072
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Body
+adminDescription: ms-Exch-Mailbox-Manager-User-Message-Body
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerUserMessageBody
+name: ms-Exch-Mailbox-Manager-User-Message-Body
+schemaIDGUID: 9ec3ccac-09fa-4a22-869f-9144258d230d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-User-Message-Footer	
+# The mail notification message footer.
+#
+dn: CN=ms-Exch-Mailbox-Manager-User-Message-Footer,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-User-Message-Footer
+distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Footer,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50073
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Footer
+adminDescription: ms-Exch-Mailbox-Manager-User-Message-Footer
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerUserMessageFooter
+name: ms-Exch-Mailbox-Manager-User-Message-Footer
+schemaIDGUID: 33795abb-57ba-43ec-9f7e-a4601c2e4d4f
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Manager-User-Message-Header	
+# The mail notification message header.
+#
+dn: CN=ms-Exch-Mailbox-Manager-User-Message-Header,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Manager-User-Message-Header
+distinguishedName: CN=ms-Exch-Mailbox-Manager-User-Message-Header,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50071
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Manager-User-Message-Header
+adminDescription: ms-Exch-Mailbox-Manager-User-Message-Header
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxManagerUserMessageHeader
+name: ms-Exch-Mailbox-Manager-User-Message-Header
+schemaIDGUID: fbcffefe-8916-4ce6-ac76-eab226fe5440
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Retention-Period	
+# The number of days to retain deleted mailboxes before purging them.
+#
+dn: CN=ms-Exch-Mailbox-Retention-Period,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Retention-Period
+distinguishedName: CN=ms-Exch-Mailbox-Retention-Period,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11060
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Retention-Period
+adminDescription: ms-Exch-Mailbox-Retention-Period
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMailboxRetentionPeriod
+name: ms-Exch-Mailbox-Retention-Period
+schemaIDGUID: 7b4a7a8a-1876-11d3-aa59-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Security-Descriptor  
+# The security descriptor of the user's mailbox.
+#
+dn: CN=ms-Exch-Mailbox-Security-Descriptor,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Security-Descriptor
+distinguishedName: CN=ms-Exch-Mailbox-Security-Descriptor,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.80
+attributeSyntax: 2.5.5.15
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+mAPIID: 35956
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Security-Descriptor
+adminDescription: ms-Exch-Mailbox-Security-Descriptor
+oMSyntax: 66
+searchFlags: 8
+lDAPDisplayName: msExchMailboxSecurityDescriptor
+name: ms-Exch-Mailbox-Security-Descriptor
+schemaIDGUID: 934de926-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mailbox-Url  
+# The URL to a user's mailbox.
+#
+dn: CN=ms-Exch-Mailbox-Url,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mailbox-Url
+distinguishedName: CN=ms-Exch-Mailbox-Url,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50085
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+mAPIID: 35967
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mailbox-Url
+adminDescription: ms-Exch-Mailbox-Url
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMailboxUrl
+name: ms-Exch-Mailbox-Url
+schemaIDGUID: fc1ffd10-ae3f-466c-87c7-518b91dadbd0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mail-Nickname	
+#
+dn: CN=ms-Exch-Mail-Nickname,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mail-Nickname
+distinguishedName: CN=ms-Exch-Mail-Nickname,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.447
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 14848
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mail-Nickname
+adminDescription: ms-Exch-Mail-Nickname
+oMSyntax: 64
+searchFlags: 5
+lDAPDisplayName: mailNickname
+name: ms-Exch-Mail-Nickname
+schemaIDGUID: bf9679b3-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Maintenance-Schedule	 
+#
+dn: CN=ms-Exch-Maintenance-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Maintenance-Schedule
+distinguishedName: CN=ms-Exch-Maintenance-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1029
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Maintenance-Schedule
+adminDescription: ms-Exch-Maintenance-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchMaintenanceSchedule
+name: ms-Exch-Maintenance-Schedule
+schemaIDGUID: 8fa76ef0-25d7-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Maintenance-Style	 
+#
+dn: CN=ms-Exch-Maintenance-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Maintenance-Style
+distinguishedName: CN=ms-Exch-Maintenance-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1030
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Maintenance-Style
+adminDescription: ms-Exch-Maintenance-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaintenanceStyle
+name: ms-Exch-Maintenance-Style
+schemaIDGUID: 8fa76ef6-25d7-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mandatory-Attributes	 
+#
+dn: CN=ms-Exch-Mandatory-Attributes,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mandatory-Attributes
+distinguishedName: CN=ms-Exch-Mandatory-Attributes,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50029
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mandatory-Attributes
+adminDescription: ms-Exch-Mandatory-Attributes
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMandatoryAttributes
+name: ms-Exch-Mandatory-Attributes
+schemaIDGUID: e32977be-1d31-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MAPI-Recipient	 
+#
+dn: CN=ms-Exch-MAPI-Recipient,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MAPI-Recipient
+distinguishedName: CN=ms-Exch-MAPI-Recipient,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.371
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 14912
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MAPI-Recipient
+adminDescription: ms-Exch-MAPI-Recipient
+oMSyntax: 1
+searchFlags: 16
+lDAPDisplayName: mAPIRecipient
+name: ms-Exch-MAPI-Recipient
+schemaIDGUID: bf9679b8-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Master-Account-Sid	 
+#
+dn: CN=ms-Exch-Master-Account-Sid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Master-Account-Sid
+distinguishedName: CN=ms-Exch-Master-Account-Sid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.81
+attributeSyntax: 2.5.5.17
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 28
+mAPIID: 35957
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Master-Account-Sid
+adminDescription: ms-Exch-Master-Account-Sid
+oMSyntax: 4
+searchFlags: 9
+lDAPDisplayName: msExchMasterAccountSid
+name: ms-Exch-Master-Account-Sid
+schemaIDGUID: 936a855e-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Master-Service	 
+# The Address List Service master server.
+#
+dn: CN=ms-Exch-Master-Service,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Master-Service
+distinguishedName: CN=ms-Exch-Master-Service,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.82
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1022
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Master-Service
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Master-Service
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMasterService
+name: ms-Exch-Master-Service
+schemaIDGUID: 944d04c4-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Master-Service-BL	
+# A backlink to the Address List Service master server.
+#
+dn: CN=ms-Exch-Master-Service-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Master-Service-BL
+distinguishedName: CN=ms-Exch-Master-Service-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.83
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1023
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Master-Service-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Master-Service-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMasterServiceBL
+name: ms-Exch-Master-Service-BL
+schemaIDGUID: 946c0356-b09e-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Maximum-Object-ID    
+#
+dn: CN=ms-Exch-Maximum-Object-ID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Maximum-Object-ID
+distinguishedName: CN=ms-Exch-Maximum-Object-ID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.458
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 22
+mAPIID: 33129
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Maximum-Object-ID
+adminDescription: ms-Exch-Maximum-Object-ID
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: maximumObjectID
+name: ms-Exch-Maximum-Object-ID
+schemaIDGUID: a8df741e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Maximum-Recurring-Instances	
+# The maximum number of instances generated per day.
+#
+dn: CN=ms-Exch-Maximum-Recurring-Instances,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Maximum-Recurring-Instances
+distinguishedName: CN=ms-Exch-Maximum-Recurring-Instances,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.10014
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Maximum-Recurring-Instances
+adminDescription: ms-Exch-Maximum-Recurring-Instances
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaximumRecurringInstances
+name: ms-Exch-Maximum-Recurring-Instances
+schemaIDGUID: a8b8d132-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Maximum-Recurring-Instances-Months	
+# The maximum window of instances (months) generated by the store
+# expansion agent.
+#
+dn: CN=ms-Exch-Maximum-Recurring-Instances-Months,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Maximum-Recurring-Instances-Months
+distinguishedName: CN=ms-Exch-Maximum-Recurring-Instances-Months,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.10015
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Maximum-Recurring-Instances-Months
+adminDescription: ms-Exch-Maximum-Recurring-Instances-Months
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaximumRecurringInstancesMonths
+name: ms-Exch-Maximum-Recurring-Instances-Months
+schemaIDGUID: a8da321e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Max-Cached-Views	 
+# The maximum number of restricted views cached for any given folder
+# in the MDB.
+#
+dn: CN=ms-Exch-Max-Cached-Views,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Cached-Views
+distinguishedName: CN=ms-Exch-Max-Cached-Views,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11083
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Cached-Views
+adminDescription: ms-Exch-Max-Cached-Views
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxCachedViews
+name: ms-Exch-Max-Cached-Views
+schemaIDGUID: 1529cf69-2fdb-11d3-aa6d-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Connections      
+# Defines the maximum allowed connections.
+#
+dn: CN=ms-Exch-Max-Connections,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Connections
+distinguishedName: CN=ms-Exch-Max-Connections,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9013
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Connections
+adminDescription: ms-Exch-Max-Connections
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxConnections
+name: ms-Exch-Max-Connections
+schemaIDGUID: a7c33efc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Extension-Time	
+# The maximum minutes a video conference can be extended.
+#
+dn: CN=ms-Exch-Max-Extension-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Extension-Time
+distinguishedName: CN=ms-Exch-Max-Extension-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9028
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Extension-Time
+adminDescription: ms-Exch-Max-Extension-Time
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxExtensionTime
+name: ms-Exch-Max-Extension-Time
+schemaIDGUID: 99f58668-12e8-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Max-Incoming-Connections 
+# The maximum number of incoming connections allowed for this
+# resource.
+#
+dn: CN=ms-Exch-Max-Incoming-Connections,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Incoming-Connections
+distinguishedName: CN=ms-Exch-Max-Incoming-Connections,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2004
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Incoming-Connections
+adminDescription: ms-Exch-Max-Incoming-Connections
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxIncomingConnections
+name: ms-Exch-Max-Incoming-Connections
+schemaIDGUID: a808632e-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Participants	   
+# The maximum number of participants allowed in a video conference.
+#
+dn: CN=ms-Exch-Max-Participants,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Participants
+distinguishedName: CN=ms-Exch-Max-Participants,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9027
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Participants
+adminDescription: ms-Exch-Max-Participants
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxParticipants
+name: ms-Exch-Max-Participants
+schemaIDGUID: 99f58663-12e8-11d3-aa58-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Pool-Threads 
+#
+dn: CN=ms-Exch-Max-Pool-Threads,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Pool-Threads
+distinguishedName: CN=ms-Exch-Max-Pool-Threads,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11041
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Pool-Threads
+adminDescription: ms-Exch-Max-Pool-Threads
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxPoolThreads
+name: ms-Exch-Max-Pool-Threads
+schemaIDGUID: a82e88ce-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Restore-Storage-Groups		 
+#
+dn: CN=ms-Exch-Max-Restore-Storage-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Restore-Storage-Groups
+distinguishedName: CN=ms-Exch-Max-Restore-Storage-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11095
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Restore-Storage-Groups
+adminDescription: ms-Exch-Max-Restore-Storage-Groups
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxRestoreStorageGroups
+name: ms-Exch-Max-Restore-Storage-Groups
+schemaIDGUID: 3ef2a80e-ea82-421b-8a62-a12543c34141
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Storage-Groups			 
+# The maximum number of Jet instances allowed on this computer.
+#
+dn: CN=ms-Exch-Max-Storage-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Storage-Groups
+distinguishedName: CN=ms-Exch-Max-Storage-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11027
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Storage-Groups
+adminDescription: ms-Exch-Max-Storage-Groups
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxStorageGroups
+name: ms-Exch-Max-Storage-Groups
+schemaIDGUID: a84fe9ba-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Max-Stores-Per-Group	    
+# The maximum number of stores allowed per Jet instance on this
+# computer.
+#
+dn: CN=ms-Exch-Max-Stores-Per-Group,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Stores-Per-Group
+distinguishedName: CN=ms-Exch-Max-Stores-Per-Group,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11028
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Stores-Per-Group
+adminDescription: ms-Exch-Max-Stores-Per-Group
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxStoresPerGroup
+name: ms-Exch-Max-Stores-Per-Group
+schemaIDGUID: a8714aa6-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Max-Threads	     
+# The maximum remote procedure call (RPC) threads for the server.
+#
+dn: CN=ms-Exch-Max-Threads,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Max-Threads
+distinguishedName: CN=ms-Exch-Max-Threads,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11042
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Max-Threads
+adminDescription: ms-Exch-Max-Threads
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMaxThreads
+name: ms-Exch-Max-Threads
+schemaIDGUID: a8950dec-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MCU-Hosts-Sites 
+# A forward link to Microsoft® Windows® sites supported by the
+# specified multipoint control unit (MCU).
+#
+dn: CN=ms-Exch-MCU-Hosts-Sites,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MCU-Hosts-Sites
+distinguishedName: CN=ms-Exch-MCU-Hosts-Sites,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9031
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1038
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MCU-Hosts-Sites
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-MCU-Hosts-Sites
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMCUHostsSites
+name: ms-Exch-MCU-Hosts-Sites
+schemaIDGUID: bd062bc7-ce32-4690-8b8e-5c63b816b516
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MCU-Hosts-Sites-BL  
+# A backlink to Microsoft® Windows® sites supported by the specified multipoint control unit (MCU).
+#
+dn: CN=ms-Exch-MCU-Hosts-Sites-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MCU-Hosts-Sites-BL
+distinguishedName: CN=ms-Exch-MCU-Hosts-Sites-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9032
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1039
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MCU-Hosts-Sites-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-MCU-Hosts-Sites-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMCUHostsSitesBL
+name: ms-Exch-MCU-Hosts-Sites-BL
+schemaIDGUID: b0ab8d77-2486-467d-a331-3e3524438a57
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MDB-Backoff-Interval	
+#
+dn: CN=ms-Exch-MDB-Backoff-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Backoff-Interval
+distinguishedName: CN=ms-Exch-MDB-Backoff-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.72
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32975
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Backoff-Interval
+adminDescription: ms-Exch-MDB-Backoff-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: mDBBackoffInterval
+name: ms-Exch-MDB-Backoff-Interval
+schemaIDGUID: a8df741f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-MDB-Msg-Time-Out-Period   
+#
+dn: CN=ms-Exch-MDB-Msg-Time-Out-Period,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Msg-Time-Out-Period
+distinguishedName: CN=ms-Exch-MDB-Msg-Time-Out-Period,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.64
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32976
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Msg-Time-Out-Period
+adminDescription: ms-Exch-MDB-Msg-Time-Out-Period
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: mDBMsgTimeOutPeriod
+name: ms-Exch-MDB-Msg-Time-Out-Period
+schemaIDGUID: a8df7420-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-MDB-Over-Hard-Quota-Limit 
+# The default size limit after which messages can no longer be sent or
+# received.
+#
+dn: CN=ms-Exch-MDB-Over-Hard-Quota-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Over-Hard-Quota-Limit
+distinguishedName: CN=ms-Exch-MDB-Over-Hard-Quota-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11037
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Over-Hard-Quota-Limit
+adminDescription: ms-Exch-MDB-Over-Hard-Quota-Limit
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: mDBOverHardQuotaLimit
+name: ms-Exch-MDB-Over-Hard-Quota-Limit
+schemaIDGUID: 8fcf1ec4-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MDB-Over-Quota-Limit	    
+#
+dn: CN=ms-Exch-MDB-Over-Quota-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Over-Quota-Limit
+distinguishedName: CN=ms-Exch-MDB-Over-Quota-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.272
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32977
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Over-Quota-Limit
+adminDescription: ms-Exch-MDB-Over-Quota-Limit
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: mDBOverQuotaLimit
+name: ms-Exch-MDB-Over-Quota-Limit
+schemaIDGUID: f0f8ff91-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-MDB-Storage-Quota	    
+#
+dn: CN=ms-Exch-MDB-Storage-Quota,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Storage-Quota
+distinguishedName: CN=ms-Exch-MDB-Storage-Quota,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.266
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32978
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Storage-Quota
+adminDescription: ms-Exch-MDB-Storage-Quota
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: mDBStorageQuota
+name: ms-Exch-MDB-Storage-Quota
+schemaIDGUID: f0f8ff92-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-MDB-Unread-Limit	    
+#
+dn: CN=ms-Exch-MDB-Unread-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Unread-Limit
+distinguishedName: CN=ms-Exch-MDB-Unread-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.69
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32979
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Unread-Limit
+adminDescription: ms-Exch-MDB-Unread-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: mDBUnreadLimit
+name: ms-Exch-MDB-Unread-Limit
+schemaIDGUID: a8df7421-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MDB-Use-Defaults	    
+#
+dn: CN=ms-Exch-MDB-Use-Defaults,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MDB-Use-Defaults
+distinguishedName: CN=ms-Exch-MDB-Use-Defaults,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.309
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32980
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MDB-Use-Defaults
+adminDescription: ms-Exch-MDB-Use-Defaults
+oMSyntax: 1
+searchFlags: 16
+lDAPDisplayName: mDBUseDefaults
+name: ms-Exch-MDB-Use-Defaults
+schemaIDGUID: f0f8ff93-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Member-Base-DN	    
+# Contains the base of the LDAP search that should be used to compute
+# this dynamic DL.
+#
+dn: CN=ms-Exch-Member-Base-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Member-Base-DN
+distinguishedName: CN=ms-Exch-Member-Base-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12524
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Member-Base-DN
+adminDescription: ms-Exch-Member-Base-DN
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchMemberBaseDN
+name: ms-Exch-Member-Base-DN
+schemaIDGUID: a921b8aa-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Member-Filter	     
+# The LDAP search filter used to generate this dynamic DL.
+#
+dn: CN=ms-Exch-Member-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Member-Filter
+distinguishedName: CN=ms-Exch-Member-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12522
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Member-Filter
+adminDescription: ms-Exch-Member-Filter
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchMemberFilter
+name: ms-Exch-Member-Filter
+schemaIDGUID: a9457bf0-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Message-Journal-Recipient  
+# A pointer to the mailbox that should get a journal (copy) of all
+# messages sent on this mailbox store.
+#
+dn: CN=ms-Exch-Message-Journal-Recipient,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Message-Journal-Recipient
+distinguishedName: CN=ms-Exch-Message-Journal-Recipient,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5055
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Message-Journal-Recipient
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Message-Journal-Recipient
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchMessageJournalRecipient
+name: ms-Exch-Message-Journal-Recipient
+schemaIDGUID: a95fee9d-b634-41e9-8f8c-d3d9ac1d5941
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Message-Size-Limit 
+#
+dn: CN=ms-Exch-Message-Size-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Message-Size-Limit
+distinguishedName: CN=ms-Exch-Message-Size-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.100
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32925
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Message-Size-Limit
+adminDescription: ms-Exch-Message-Size-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: messageSizeLimit
+name: ms-Exch-Message-Size-Limit
+schemaIDGUID: 167757e2-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Message-Tracking-Enabled    
+#
+dn: CN=ms-Exch-Message-Tracking-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Message-Tracking-Enabled
+distinguishedName: CN=ms-Exch-Message-Tracking-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.453
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32981
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Message-Tracking-Enabled
+adminDescription: ms-Exch-Message-Tracking-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: messageTrackingEnabled
+name: ms-Exch-Message-Tracking-Enabled
+schemaIDGUID: a8df7422-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Message-Track-Log-Filter    
+# Defines the filter for the fields in the message tracking log. Each
+# bit controls a field.
+#
+dn: CN=ms-Exch-Message-Track-Log-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Message-Track-Log-Filter
+distinguishedName: CN=ms-Exch-Message-Track-Log-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50001
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Message-Track-Log-Filter
+adminDescription: ms-Exch-Message-Track-Log-Filter
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMessageTrackLogFilter
+name: ms-Exch-Message-Track-Log-Filter
+schemaIDGUID: a9647a82-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mime-Types	  
+#
+dn: CN=ms-Exch-Mime-Types,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mime-Types
+distinguishedName: CN=ms-Exch-Mime-Types,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.550
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 10240
+mAPIID: 35868
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mime-Types
+adminDescription: ms-Exch-Mime-Types
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchMimeTypes
+name: ms-Exch-Mime-Types
+schemaIDGUID: 8addd6a2-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Minimum-Threads 
+# The minimum RPC threads for the server.
+#
+dn: CN=ms-Exch-Minimum-Threads,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Minimum-Threads
+distinguishedName: CN=ms-Exch-Minimum-Threads,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11043
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Minimum-Threads
+adminDescription: ms-Exch-Minimum-Threads
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMinimumThreads
+name: ms-Exch-Minimum-Threads
+schemaIDGUID: a9883dc8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Min-Admin-Version	
+#
+dn: CN=ms-Exch-Min-Admin-Version,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Min-Admin-Version
+distinguishedName: CN=ms-Exch-Min-Admin-Version,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50093
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Min-Admin-Version
+adminDescription: ms-Exch-Min-Admin-Version
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMinAdminVersion
+name: ms-Exch-Min-Admin-Version
+schemaIDGUID: 8fca497d-4ac7-4df4-b180-eec0bfef27df
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Mixed-Mode		
+#
+dn: CN=ms-Exch-Mixed-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Mixed-Mode
+distinguishedName: CN=ms-Exch-Mixed-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50022
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Mixed-Mode
+adminDescription: ms-Exch-Mixed-Mode
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchMixedMode
+name: ms-Exch-Mixed-Mode
+schemaIDGUID: 8ddb297c-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitored-Configurations  
+#
+dn: CN=ms-Exch-Monitored-Configurations,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitored-Configurations
+distinguishedName: CN=ms-Exch-Monitored-Configurations,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.198
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32985
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitored-Configurations
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitored-Configurations
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoredConfigurations
+name: ms-Exch-Monitored-Configurations
+schemaIDGUID: bf9679c9-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitored-Servers	    
+#
+dn: CN=ms-Exch-Monitored-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitored-Servers
+distinguishedName: CN=ms-Exch-Monitored-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.179
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32986
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitored-Servers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitored-Servers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoredServers
+name: ms-Exch-Monitored-Servers
+schemaIDGUID: a8df7426-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitored-Services	    
+#
+dn: CN=ms-Exch-Monitored-Services,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitored-Services
+distinguishedName: CN=ms-Exch-Monitored-Services,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.199
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 32987
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitored-Services
+adminDescription: ms-Exch-Monitored-Services
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: monitoredServices
+name: ms-Exch-Monitored-Services
+schemaIDGUID: bf9679ca-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Alert-Delay    
+#
+dn: CN=ms-Exch-Monitoring-Alert-Delay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Alert-Delay
+distinguishedName: CN=ms-Exch-Monitoring-Alert-Delay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.158
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32988
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Alert-Delay
+adminDescription: ms-Exch-Monitoring-Alert-Delay
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringAlertDelay
+name: ms-Exch-Monitoring-Alert-Delay
+schemaIDGUID: a8df7427-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Alert-Units    
+#
+dn: CN=ms-Exch-Monitoring-Alert-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Alert-Units
+distinguishedName: CN=ms-Exch-Monitoring-Alert-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.57
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 32989
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Alert-Units
+adminDescription: ms-Exch-Monitoring-Alert-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringAlertUnits
+name: ms-Exch-Monitoring-Alert-Units
+schemaIDGUID: a8df7428-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Availability-Style	
+#
+dn: CN=ms-Exch-Monitoring-Availability-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Availability-Style
+distinguishedName: CN=ms-Exch-Monitoring-Availability-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.450
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 3
+mAPIID: 32990
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Availability-Style
+adminDescription: ms-Exch-Monitoring-Availability-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringAvailabilityStyle
+name: ms-Exch-Monitoring-Availability-Style
+schemaIDGUID: bf9679cb-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Availability-Window    
+#
+dn: CN=ms-Exch-Monitoring-Availability-Window,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Availability-Window
+distinguishedName: CN=ms-Exch-Monitoring-Availability-Window,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.200
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 84
+mAPIID: 32991
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Availability-Window
+adminDescription: ms-Exch-Monitoring-Availability-Window
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: monitoringAvailabilityWindow
+name: ms-Exch-Monitoring-Availability-Window
+schemaIDGUID: bf9679cc-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Cached-Via-Mail	    
+#
+dn: CN=ms-Exch-Monitoring-Cached-Via-Mail,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Cached-Via-Mail
+distinguishedName: CN=ms-Exch-Monitoring-Cached-Via-Mail,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.196
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32992
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Cached-Via-Mail
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitoring-Cached-Via-Mail
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoringCachedViaMail
+name: ms-Exch-Monitoring-Cached-Via-Mail
+schemaIDGUID: bf9679cd-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Cached-Via-RPC	    
+#
+dn: CN=ms-Exch-Monitoring-Cached-Via-RPC,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Cached-Via-RPC
+distinguishedName: CN=ms-Exch-Monitoring-Cached-Via-RPC,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.197
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32993
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Cached-Via-RPC
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitoring-Cached-Via-RPC
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoringCachedViaRPC
+name: ms-Exch-Monitoring-Cached-Via-RPC
+schemaIDGUID: bf9679ce-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Disk-Space		    
+#
+dn: CN=ms-Exch-Monitoring-Disk-Space,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Disk-Space
+distinguishedName: CN=ms-Exch-Monitoring-Disk-Space,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50046
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Disk-Space
+adminDescription: ms-Exch-Monitoring-Disk-Space
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringDiskSpace
+name: ms-Exch-Monitoring-Disk-Space
+schemaIDGUID: 0210cc37-34cf-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Escalation-Procedure     
+#
+dn: CN=ms-Exch-Monitoring-Escalation-Procedure,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Escalation-Procedure
+distinguishedName: CN=ms-Exch-Monitoring-Escalation-Procedure,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.188
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1064
+mAPIID: 32994
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Escalation-Procedure
+adminDescription: ms-Exch-Monitoring-Escalation-Procedure
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: monitoringEscalationProcedure
+name: ms-Exch-Monitoring-Escalation-Procedure
+schemaIDGUID: a8df7429-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Hotsite-Poll-Interval    
+#
+dn: CN=ms-Exch-Monitoring-Hotsite-Poll-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Hotsite-Poll-Interval
+distinguishedName: CN=ms-Exch-Monitoring-Hotsite-Poll-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.186
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32995
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Hotsite-Poll-Interval
+adminDescription: ms-Exch-Monitoring-Hotsite-Poll-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringHotsitePollInterval
+name: ms-Exch-Monitoring-Hotsite-Poll-Interval
+schemaIDGUID: a8df742a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Hotsite-Poll-Units	      
+#
+dn: CN=ms-Exch-Monitoring-Hotsite-Poll-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Hotsite-Poll-Units
+distinguishedName: CN=ms-Exch-Monitoring-Hotsite-Poll-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.87
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 32996
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Hotsite-Poll-Units
+adminDescription: ms-Exch-Monitoring-Hotsite-Poll-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringHotsitePollUnits
+name: ms-Exch-Monitoring-Hotsite-Poll-Units
+schemaIDGUID: a8df742b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Mail-Update-Interval     
+#
+dn: CN=ms-Exch-Monitoring-Mail-Update-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Mail-Update-Interval
+distinguishedName: CN=ms-Exch-Monitoring-Mail-Update-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.195
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32997
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Mail-Update-Interval
+adminDescription: ms-Exch-Monitoring-Mail-Update-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringMailUpdateInterval
+name: ms-Exch-Monitoring-Mail-Update-Interval
+schemaIDGUID: bf9679cf-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Mail-Update-Units	      
+#
+dn: CN=ms-Exch-Monitoring-Mail-Update-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Mail-Update-Units
+distinguishedName: CN=ms-Exch-Monitoring-Mail-Update-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.93
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 32998
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Mail-Update-Units
+adminDescription: ms-Exch-Monitoring-Mail-Update-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringMailUpdateUnits
+name: ms-Exch-Monitoring-Mail-Update-Units
+schemaIDGUID: bf9679d0-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Mode    
+#
+dn: CN=ms-Exch-Monitoring-Mode,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Mode
+distinguishedName: CN=ms-Exch-Monitoring-Mode,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50060
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Mode
+adminDescription: ms-Exch-Monitoring-Mode
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringMode
+name: ms-Exch-Monitoring-Mode
+schemaIDGUID: e520be0a-d2ea-449b-9177-caaadec1a4c6
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Monitored-Services	 
+#
+dn: CN=ms-Exch-Monitoring-Monitored-Services,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Monitored-Services
+distinguishedName: CN=ms-Exch-Monitoring-Monitored-Services,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50045
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Monitored-Services
+adminDescription: ms-Exch-Monitoring-Monitored-Services
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringMonitoredServices
+name: ms-Exch-Monitoring-Monitored-Services
+schemaIDGUID: 0210cc30-34cf-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Normal-Poll-Interval     
+#
+dn: CN=ms-Exch-Monitoring-Normal-Poll-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Normal-Poll-Interval
+distinguishedName: CN=ms-Exch-Monitoring-Normal-Poll-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.187
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 32999
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Normal-Poll-Interval
+adminDescription: ms-Exch-Monitoring-Normal-Poll-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringNormalPollInterval
+name: ms-Exch-Monitoring-Normal-Poll-Interval
+schemaIDGUID: a8df742c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Normal-Poll-Units	      
+#
+dn: CN=ms-Exch-Monitoring-Normal-Poll-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Normal-Poll-Units
+distinguishedName: CN=ms-Exch-Monitoring-Normal-Poll-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.88
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33000
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Normal-Poll-Units
+adminDescription: ms-Exch-Monitoring-Normal-Poll-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringNormalPollUnits
+name: ms-Exch-Monitoring-Normal-Poll-Units
+schemaIDGUID: a8df742d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Notification-Rate	      
+# How frequently the MAD should check whether a notification (such as
+# a mail or page) should be sent.
+#
+dn: CN=ms-Exch-Monitoring-Notification-Rate,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Notification-Rate
+distinguishedName: CN=ms-Exch-Monitoring-Notification-Rate,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50057
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Notification-Rate
+adminDescription: ms-Exch-Monitoring-Notification-Rate
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringNotificationRate
+name: ms-Exch-Monitoring-Notification-Rate
+schemaIDGUID: 8bf11686-fb18-4147-95e4-f43f8c9de87d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Polling-Rate   
+# The set of polling rates for each of the types of monitored
+# resources (such as queues, CPU, and disk). The syntax of each of the
+# entries will be: [TYPE],[RATE as Seconds].
+#
+dn: CN=ms-Exch-Monitoring-Polling-Rate,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Polling-Rate
+distinguishedName: CN=ms-Exch-Monitoring-Polling-Rate,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50058
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Polling-Rate
+adminDescription: ms-Exch-Monitoring-Polling-Rate
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringPollingRate
+name: ms-Exch-Monitoring-Polling-Rate
+schemaIDGUID: a3af17a5-b2bf-442c-bd04-83dcedb19ea4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Queue-Polling-Frequency	    
+#
+dn: CN=ms-Exch-Monitoring-Queue-Polling-Frequency,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Queue-Polling-Frequency
+distinguishedName: CN=ms-Exch-Monitoring-Queue-Polling-Frequency,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50038
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Queue-Polling-Frequency
+adminDescription: ms-Exch-Monitoring-Queue-Polling-Frequency
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringQueuePollingFrequency
+name: ms-Exch-Monitoring-Queue-Polling-Frequency
+schemaIDGUID: 501b8818-29ae-11d3-aa69-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Monitoring-Queue-Polling-Interval   
+#
+dn: CN=ms-Exch-Monitoring-Queue-Polling-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Queue-Polling-Interval
+distinguishedName: CN=ms-Exch-Monitoring-Queue-Polling-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50037
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Queue-Polling-Interval
+adminDescription: ms-Exch-Monitoring-Queue-Polling-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringQueuePollingInterval
+name: ms-Exch-Monitoring-Queue-Polling-Interval
+schemaIDGUID: 501b880f-29ae-11d3-aa69-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Monitoring-Recipients		 
+#
+dn: CN=ms-Exch-Monitoring-Recipients,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Recipients
+distinguishedName: CN=ms-Exch-Monitoring-Recipients,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.159
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33001
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Recipients
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitoring-Recipients
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoringRecipients
+name: ms-Exch-Monitoring-Recipients
+schemaIDGUID: a8df742e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Recipients-NDR	 
+#
+dn: CN=ms-Exch-Monitoring-Recipients-NDR,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Recipients-NDR
+distinguishedName: CN=ms-Exch-Monitoring-Recipients-NDR,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.387
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33002
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Recipients-NDR
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Monitoring-Recipients-NDR
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: monitoringRecipientsNDR
+name: ms-Exch-Monitoring-Recipients-NDR
+schemaIDGUID: a8df742f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Resources		 
+# The set of monitored resources (such as queues, CPU, and disk). The
+# general syntax of each of the entries will be: TYPE, ID, [Warning
+# value], [Error value]. Some TYPEs may need different formats.
+#
+dn: CN=ms-Exch-Monitoring-Resources,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Resources
+distinguishedName: CN=ms-Exch-Monitoring-Resources,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50059
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Resources
+adminDescription: ms-Exch-Monitoring-Resources
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringResources
+name: ms-Exch-Monitoring-Resources
+schemaIDGUID: c1293ac0-b228-4b41-9409-2ca7d0c19459
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Responses	
+#
+dn: CN=ms-Exch-Monitoring-Responses,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Responses
+distinguishedName: CN=ms-Exch-Monitoring-Responses,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50047
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Responses
+adminDescription: ms-Exch-Monitoring-Responses
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMonitoringResponses
+name: ms-Exch-Monitoring-Responses
+schemaIDGUID: 0210cc43-34cf-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-RPC-Update-Interval 
+#
+dn: CN=ms-Exch-Monitoring-RPC-Update-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-RPC-Update-Interval
+distinguishedName: CN=ms-Exch-Monitoring-RPC-Update-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.92
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33003
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-RPC-Update-Interval
+adminDescription: ms-Exch-Monitoring-RPC-Update-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringRPCUpdateInterval
+name: ms-Exch-Monitoring-RPC-Update-Interval
+schemaIDGUID: bf9679d1-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-RPC-Update-Units	 
+#
+dn: CN=ms-Exch-Monitoring-RPC-Update-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-RPC-Update-Units
+distinguishedName: CN=ms-Exch-Monitoring-RPC-Update-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.89
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33004
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-RPC-Update-Units
+adminDescription: ms-Exch-Monitoring-RPC-Update-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringRPCUpdateUnits
+name: ms-Exch-Monitoring-RPC-Update-Units
+schemaIDGUID: bf9679d2-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Warning-Delay	 
+#
+dn: CN=ms-Exch-Monitoring-Warning-Delay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Warning-Delay
+distinguishedName: CN=ms-Exch-Monitoring-Warning-Delay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.157
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33005
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Warning-Delay
+adminDescription: ms-Exch-Monitoring-Warning-Delay
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: monitoringWarningDelay
+name: ms-Exch-Monitoring-Warning-Delay
+schemaIDGUID: a8df7430-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitoring-Warning-Units	 
+#
+dn: CN=ms-Exch-Monitoring-Warning-Units,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitoring-Warning-Units
+distinguishedName: CN=ms-Exch-Monitoring-Warning-Units,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.56
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33006
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitoring-Warning-Units
+adminDescription: ms-Exch-Monitoring-Warning-Units
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: monitoringWarningUnits
+name: ms-Exch-Monitoring-Warning-Units
+schemaIDGUID: a8df7431-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitor-Clock	 
+#
+dn: CN=ms-Exch-Monitor-Clock,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitor-Clock
+distinguishedName: CN=ms-Exch-Monitor-Clock,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.163
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32982
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitor-Clock
+adminDescription: ms-Exch-Monitor-Clock
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: monitorClock
+name: ms-Exch-Monitor-Clock
+schemaIDGUID: a8df7423-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitor-Servers    
+#
+dn: CN=ms-Exch-Monitor-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitor-Servers
+distinguishedName: CN=ms-Exch-Monitor-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.156
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32983
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitor-Servers
+adminDescription: ms-Exch-Monitor-Servers
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: monitorServers
+name: ms-Exch-Monitor-Servers
+schemaIDGUID: a8df7424-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Monitor-Services   
+#
+dn: CN=ms-Exch-Monitor-Services,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Monitor-Services
+distinguishedName: CN=ms-Exch-Monitor-Services,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.160
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 32984
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Monitor-Services
+adminDescription: ms-Exch-Monitor-Services
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: monitorServices
+name: ms-Exch-Monitor-Services
+schemaIDGUID: a8df7425-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Move-To-LSA	     
+#
+dn: CN=ms-Exch-Move-To-LSA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Move-To-LSA
+distinguishedName: CN=ms-Exch-Move-To-LSA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.88
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Move-To-LSA
+adminDescription: ms-Exch-Move-To-LSA
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchMoveToLSA
+name: ms-Exch-Move-To-LSA
+schemaIDGUID: ab4cc53c-4ba4-11d3-aa75-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-MTA-Database-Path   
+#
+dn: CN=ms-Exch-MTA-Database-Path,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MTA-Database-Path
+distinguishedName: CN=ms-Exch-MTA-Database-Path,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.18001
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MTA-Database-Path
+adminDescription: ms-Exch-MTA-Database-Path
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchMTADatabasePath
+name: ms-Exch-MTA-Database-Path
+schemaIDGUID: 2f2dc2a4-242e-11d3-aa66-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MTA-Local-Cred      
+#
+dn: CN=ms-Exch-MTA-Local-Cred,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MTA-Local-Cred
+distinguishedName: CN=ms-Exch-MTA-Local-Cred,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.270
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 33007
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MTA-Local-Cred
+adminDescription: ms-Exch-MTA-Local-Cred
+oMSyntax: 22
+searchFlags: 0
+lDAPDisplayName: mTALocalCred
+name: ms-Exch-MTA-Local-Cred
+schemaIDGUID: a8df7432-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-MTA-Local-Desig     
+#
+dn: CN=ms-Exch-MTA-Local-Desig,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-MTA-Local-Desig
+distinguishedName: CN=ms-Exch-MTA-Local-Desig,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.271
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 33008
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-MTA-Local-Desig
+adminDescription: ms-Exch-MTA-Local-Desig
+oMSyntax: 22
+searchFlags: 0
+lDAPDisplayName: mTALocalDesig
+name: ms-Exch-MTA-Local-Desig
+schemaIDGUID: a8df7433-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Non-Authoritative-Domains    
+#
+dn: CN=ms-Exch-Non-Authoritative-Domains,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Non-Authoritative-Domains
+distinguishedName: CN=ms-Exch-Non-Authoritative-Domains,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50084
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1123
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Non-Authoritative-Domains
+adminDescription: ms-Exch-Non-Authoritative-Domains
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNonAuthoritativeDomains
+name: ms-Exch-Non-Authoritative-Domains
+schemaIDGUID: ef2c7c70-f874-4280-8643-2334f2d3340c
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Non-MIME-Character-Set       
+#
+dn: CN=ms-Exch-Non-MIME-Character-Set,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Non-MIME-Character-Set
+distinguishedName: CN=ms-Exch-Non-MIME-Character-Set,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50043
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Non-MIME-Character-Set
+adminDescription: ms-Exch-Non-MIME-Character-Set
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNonMIMECharacterSet
+name: ms-Exch-Non-MIME-Character-Set
+schemaIDGUID: 974c99fe-33fc-11d3-aa6e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Connector-Mailbox      
+# Name of the Lotus Notes mailbox where the connector picks up mail
+# from Notes for delivery into Exchange.
+#
+dn: CN=ms-Exch-Notes-Connector-Mailbox,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Connector-Mailbox
+distinguishedName: CN=ms-Exch-Notes-Connector-Mailbox,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1014
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Connector-Mailbox
+adminDescription: ms-Exch-Notes-Connector-Mailbox
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesConnectorMailbox
+name: ms-Exch-Notes-Connector-Mailbox
+schemaIDGUID: aa5a0cb8-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Exclude-Groups	  
+# A list of Lotus Notes groups to exclude from directory
+# synchronization.
+#
+dn: CN=ms-Exch-Notes-Exclude-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Exclude-Groups
+distinguishedName: CN=ms-Exch-Notes-Exclude-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1022
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Exclude-Groups
+adminDescription: ms-Exch-Notes-Exclude-Groups
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesExcludeGroups
+name: ms-Exch-Notes-Exclude-Groups
+schemaIDGUID: 0c74acba-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Export-Groups	
+# A flag indicating whether Lotus Notes groups should be exported to
+# Exchange during directory synchronization.
+#
+dn: CN=ms-Exch-Notes-Export-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Export-Groups
+distinguishedName: CN=ms-Exch-Notes-Export-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1021
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Export-Groups
+adminDescription: ms-Exch-Notes-Export-Groups
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchNotesExportGroups
+name: ms-Exch-Notes-Export-Groups
+schemaIDGUID: 0eb5a5ce-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Foreign-Domain	     
+# The name of the Lotus Notes foreign domain that represents Exchange.
+#
+dn: CN=ms-Exch-Notes-Foreign-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Foreign-Domain
+distinguishedName: CN=ms-Exch-Notes-Foreign-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1012
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Foreign-Domain
+adminDescription: ms-Exch-Notes-Foreign-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesForeignDomain
+name: ms-Exch-Notes-Foreign-Domain
+schemaIDGUID: 137332c0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Letterhead  
+# The name of the Lotus Notes letterhead style used for messages
+# delivered into Notes from Exchange.
+#
+dn: CN=ms-Exch-Notes-Letterhead,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Letterhead
+distinguishedName: CN=ms-Exch-Notes-Letterhead,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1015
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Letterhead
+adminDescription: ms-Exch-Notes-Letterhead
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesLetterhead
+name: ms-Exch-Notes-Letterhead
+schemaIDGUID: 141552a8-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Notes-INI      
+# The full path and file name of the Lotus Notes client INI file used
+# by the connector to log on to the Notes server.
+#
+dn: CN=ms-Exch-Notes-Notes-INI,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Notes-INI
+distinguishedName: CN=ms-Exch-Notes-Notes-INI,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1017
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Notes-INI
+adminDescription: ms-Exch-Notes-Notes-INI
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesNotesINI
+name: ms-Exch-Notes-Notes-INI
+schemaIDGUID: 13d02e76-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Notes-Links	 
+# Determines how Lotus Notes doclinks are converted in messages to
+# Exchange. Options are RTF, OLE, or URL.
+#
+dn: CN=ms-Exch-Notes-Notes-Links,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Notes-Links
+distinguishedName: CN=ms-Exch-Notes-Notes-Links,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1016
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Notes-Links
+adminDescription: ms-Exch-Notes-Notes-Links
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesNotesLinks
+name: ms-Exch-Notes-Notes-Links
+schemaIDGUID: aa7dcffe-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Notes-Server	
+# The name of the Lotus Notes server to which the Connector
+# attaches. Notes format name, not server name.
+#
+dn: CN=ms-Exch-Notes-Notes-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Notes-Server
+distinguishedName: CN=ms-Exch-Notes-Notes-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1011
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Notes-Server
+adminDescription: ms-Exch-Notes-Notes-Server
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesNotesServer
+name: ms-Exch-Notes-Notes-Server
+schemaIDGUID: 14b51036-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Password   
+#
+dn: CN=ms-Exch-Notes-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Password
+distinguishedName: CN=ms-Exch-Notes-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1010
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Password
+adminDescription: ms-Exch-Notes-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchNotesPassword
+name: ms-Exch-Notes-Password
+schemaIDGUID: 593fa28d-2862-11d3-aa68-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Routable-Domains    
+#
+dn: CN=ms-Exch-Notes-Routable-Domains,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Routable-Domains
+distinguishedName: CN=ms-Exch-Notes-Routable-Domains,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1023
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Routable-Domains
+adminDescription: ms-Exch-Notes-Routable-Domains
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesRoutableDomains
+name: ms-Exch-Notes-Routable-Domains
+schemaIDGUID: 90804554-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Rtr-Mailbox	    
+# The name of the mailbox used by the Lotus Notes mail router. This is
+# usually MAIL.BOX.
+#
+dn: CN=ms-Exch-Notes-Rtr-Mailbox,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Rtr-Mailbox
+distinguishedName: CN=ms-Exch-Notes-Rtr-Mailbox,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1013
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Rtr-Mailbox
+adminDescription: ms-Exch-Notes-Rtr-Mailbox
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesRtrMailbox
+name: ms-Exch-Notes-Rtr-Mailbox
+schemaIDGUID: 144c28be-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Source-Books	  
+# A list of the Lotus Notes Name and Address Books exported to
+# Exchange for directory synchronization.
+#
+dn: CN=ms-Exch-Notes-Source-Books,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Source-Books
+distinguishedName: CN=ms-Exch-Notes-Source-Books,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1020
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Source-Books
+adminDescription: ms-Exch-Notes-Source-Books
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesSourceBooks
+name: ms-Exch-Notes-Source-Books
+schemaIDGUID: 12b6d8fa-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Target-Book	   
+# The name of the default Name and Address Book into which Exchange
+# users are imported.
+#
+dn: CN=ms-Exch-Notes-Target-Book,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Target-Book
+distinguishedName: CN=ms-Exch-Notes-Target-Book,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1018
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Target-Book
+adminDescription: ms-Exch-Notes-Target-Book
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesTargetBook
+name: ms-Exch-Notes-Target-Book
+schemaIDGUID: 13a07f6e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Notes-Target-Books	 
+# A list of domain-specific Lotus Notes Name and Address Books for
+# directory import.
+#
+dn: CN=ms-Exch-Notes-Target-Books,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Notes-Target-Books
+distinguishedName: CN=ms-Exch-Notes-Target-Books,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1019
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Notes-Target-Books
+adminDescription: ms-Exch-Notes-Target-Books
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNotesTargetBooks
+name: ms-Exch-Notes-Target-Books
+schemaIDGUID: aad1424c-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-No-PF-Connection    
+# Boolean state to determine if (MAPI) clients are allowed to connect
+# to public folder content in the target routing group. By default, if
+# not set, public folder referrals will be allowed over this
+# connector.
+#
+dn: CN=ms-Exch-No-PF-Connection,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-No-PF-Connection
+distinguishedName: CN=ms-Exch-No-PF-Connection,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11067
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-No-PF-Connection
+adminDescription: ms-Exch-No-PF-Connection
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchNoPFConnection
+name: ms-Exch-No-PF-Connection
+schemaIDGUID: 9ff15c41-1ec9-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Ntds-Export-Containers     
+# The GUID of NTDS containers or OUs to search in for objects to be
+# synchronized.
+#
+dn: CN=ms-Exch-Ntds-Export-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Ntds-Export-Containers
+distinguishedName: CN=ms-Exch-Ntds-Export-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.33
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Ntds-Export-Containers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Ntds-Export-Containers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchNtdsExportContainers
+name: ms-Exch-Ntds-Export-Containers
+schemaIDGUID: 155bf4d2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Ntds-Import-Container	     
+# The GUID of NTDS containers or OUs to write synchronized objects to.
+#
+dn: CN=ms-Exch-Ntds-Import-Container,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Ntds-Import-Container
+distinguishedName: CN=ms-Exch-Ntds-Import-Container,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.34
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Ntds-Import-Container
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Ntds-Import-Container
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchNtdsImportContainer
+name: ms-Exch-Ntds-Import-Container
+schemaIDGUID: 1592cae8-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-NT-Account-Options  
+#
+dn: CN=ms-Exch-NT-Account-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-NT-Account-Options
+distinguishedName: CN=ms-Exch-NT-Account-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.44
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-NT-Account-Options
+adminDescription: ms-Exch-NT-Account-Options
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchNTAccountOptions
+name: ms-Exch-NT-Account-Options
+schemaIDGUID: 14ebe64c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-NT-Authentication-Providers	     
+# A list of Security Support Provider Interface (SSPI) packages that
+# may be used to authenticate to this resource.
+#
+dn: CN=ms-Exch-NT-Authentication-Providers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-NT-Authentication-Providers
+distinguishedName: CN=ms-Exch-NT-Authentication-Providers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2009
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-NT-Authentication-Providers
+adminDescription: ms-Exch-NT-Authentication-Providers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchNTAuthenticationProviders
+name: ms-Exch-NT-Authentication-Providers
+schemaIDGUID: 15278116-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Num-Of-Open-Retries	      
+#
+dn: CN=ms-Exch-Num-Of-Open-Retries,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Num-Of-Open-Retries
+distinguishedName: CN=ms-Exch-Num-Of-Open-Retries,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.148
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33012
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Num-Of-Open-Retries
+adminDescription: ms-Exch-Num-Of-Open-Retries
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: numOfOpenRetries
+name: ms-Exch-Num-Of-Open-Retries
+schemaIDGUID: a8df743a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Num-Of-Transfer-Retries     
+#
+dn: CN=ms-Exch-Num-Of-Transfer-Retries,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Num-Of-Transfer-Retries
+distinguishedName: CN=ms-Exch-Num-Of-Transfer-Retries,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.134
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33013
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Num-Of-Transfer-Retries
+adminDescription: ms-Exch-Num-Of-Transfer-Retries
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: numOfTransferRetries
+name: ms-Exch-Num-Of-Transfer-Retries
+schemaIDGUID: a8df743b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-N-Address	
+#
+dn: CN=ms-Exch-N-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-N-Address
+distinguishedName: CN=ms-Exch-N-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.282
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 50
+mAPIID: 33009
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-N-Address
+adminDescription: ms-Exch-N-Address
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: nAddress
+name: ms-Exch-N-Address
+schemaIDGUID: a8df7434-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-N-Address-Type    
+#
+dn: CN=ms-Exch-N-Address-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-N-Address-Type
+distinguishedName: CN=ms-Exch-N-Address-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.222
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33010
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-N-Address-Type
+adminDescription: ms-Exch-N-Address-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: nAddressType
+name: ms-Exch-N-Address-Type
+schemaIDGUID: a8df7435-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-OAB-Default	    
+#
+dn: CN=ms-Exch-OAB-Default,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-OAB-Default
+distinguishedName: CN=ms-Exch-OAB-Default,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.67
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OAB-Default
+adminDescription: ms-Exch-OAB-Default
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchOABDefault
+name: ms-Exch-OAB-Default
+schemaIDGUID: 15c279f0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-OAB-Folder	    
+# The entry ID of the public folder that this offline address book
+# (OAB) is stored in.
+#
+dn: CN=ms-Exch-OAB-Folder,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-OAB-Folder
+distinguishedName: CN=ms-Exch-OAB-Folder,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.68
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OAB-Folder
+adminDescription: ms-Exch-OAB-Folder
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchOABFolder
+name: ms-Exch-OAB-Folder
+schemaIDGUID: 15f6edac-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Obj-View-Containers  
+#
+dn: CN=ms-Exch-Obj-View-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Obj-View-Containers
+distinguishedName: CN=ms-Exch-Obj-View-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.545
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33223
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Obj-View-Containers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Obj-View-Containers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: objViewContainers
+name: ms-Exch-Obj-View-Containers
+schemaIDGUID: 16775847-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Off-Line-AB-Containers   
+#
+dn: CN=ms-Exch-Off-Line-AB-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Off-Line-AB-Containers
+distinguishedName: CN=ms-Exch-Off-Line-AB-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.391
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33016
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Off-Line-AB-Containers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Off-Line-AB-Containers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: offLineABContainers
+name: ms-Exch-Off-Line-AB-Containers
+schemaIDGUID: a8df743c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Off-Line-AB-Schedule	   
+#
+dn: CN=ms-Exch-Off-Line-AB-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Off-Line-AB-Schedule
+distinguishedName: CN=ms-Exch-Off-Line-AB-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.389
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+mAPIID: 33017
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Off-Line-AB-Schedule
+adminDescription: ms-Exch-Off-Line-AB-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: offLineABSchedule
+name: ms-Exch-Off-Line-AB-Schedule
+schemaIDGUID: a8df743d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Off-Line-AB-Server	   
+#
+dn: CN=ms-Exch-Off-Line-AB-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Off-Line-AB-Server
+distinguishedName: CN=ms-Exch-Off-Line-AB-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.392
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33018
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Off-Line-AB-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Off-Line-AB-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: offLineABServer
+name: ms-Exch-Off-Line-AB-Server
+schemaIDGUID: a8df743e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Off-Line-AB-Style	   
+#
+dn: CN=ms-Exch-Off-Line-AB-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Off-Line-AB-Style
+distinguishedName: CN=ms-Exch-Off-Line-AB-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.390
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33019
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Off-Line-AB-Style
+adminDescription: ms-Exch-Off-Line-AB-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: offLineABStyle
+name: ms-Exch-Off-Line-AB-Style
+schemaIDGUID: a8df743f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Admin-Extended-Settings  
+#
+dn: CN=ms-Exch-Oma-Admin-Extended-Settings,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Admin-Extended-Settings
+distinguishedName: CN=ms-Exch-Oma-Admin-Extended-Settings,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.126
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Admin-Extended-Settings
+adminDescription: ms-Exch-Oma-Admin-Extended-Settings
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaAdminExtendedSettings
+name: ms-Exch-Oma-Admin-Extended-Settings
+schemaIDGUID: e60ae80d-7ac9-4e61-9bc3-98cbc0726a99
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Admin-Wireless-Enable    
+#
+dn: CN=ms-Exch-Oma-Admin-Wireless-Enable,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Admin-Wireless-Enable
+distinguishedName: CN=ms-Exch-Oma-Admin-Wireless-Enable,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.124
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Admin-Wireless-Enable
+adminDescription: ms-Exch-Oma-Admin-Wireless-Enable
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchOmaAdminWirelessEnable
+name: ms-Exch-Oma-Admin-Wireless-Enable
+schemaIDGUID: c1a7bfbe-116b-4737-8cd9-d29ef5b3690e
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Carrier-Address	       
+#
+dn: CN=ms-Exch-Oma-Carrier-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Carrier-Address
+distinguishedName: CN=ms-Exch-Oma-Carrier-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.139
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Carrier-Address
+adminDescription: ms-Exch-Oma-Carrier-Address
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaCarrierAddress
+name: ms-Exch-Oma-Carrier-Address
+schemaIDGUID: abe858b8-3daf-407e-b1a6-3a323ed3334b
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Carrier-Type	       
+#
+dn: CN=ms-Exch-Oma-Carrier-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Carrier-Type
+distinguishedName: CN=ms-Exch-Oma-Carrier-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.145
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Carrier-Type
+adminDescription: ms-Exch-Oma-Carrier-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaCarrierType
+name: ms-Exch-Oma-Carrier-Type
+schemaIDGUID: 1fb324ad-2da3-4548-8f5a-f34457f8af4a
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Carrier-Url	       
+#
+dn: CN=ms-Exch-Oma-Carrier-Url,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Carrier-Url
+distinguishedName: CN=ms-Exch-Oma-Carrier-Url,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.146
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Carrier-Url
+adminDescription: ms-Exch-Oma-Carrier-Url
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaCarrierUrl
+name: ms-Exch-Oma-Carrier-Url
+schemaIDGUID: aca0878d-89f1-45f5-a48f-680b7e550573
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Configuration	       
+#
+dn: CN=ms-Exch-Oma-Configuration,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Configuration
+distinguishedName: CN=ms-Exch-Oma-Configuration,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.137
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Configuration
+adminDescription: ms-Exch-Oma-Configuration
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaConfiguration
+name: ms-Exch-Oma-Configuration
+schemaIDGUID: d7e12bc7-4288-4866-bc91-f0ee18965c15
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Deliverer		       
+#
+dn: CN=ms-Exch-Oma-Deliverer,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Deliverer
+distinguishedName: CN=ms-Exch-Oma-Deliverer,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.144
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Deliverer
+adminDescription: ms-Exch-Oma-Deliverer
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaDeliverer
+name: ms-Exch-Oma-Deliverer
+schemaIDGUID: a231009f-9df2-403d-9fbd-99809049722d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Delivery-Provider-DN     
+#
+dn: CN=ms-Exch-Oma-Delivery-Provider-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Delivery-Provider-DN
+distinguishedName: CN=ms-Exch-Oma-Delivery-Provider-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.138
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Delivery-Provider-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Oma-Delivery-Provider-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOmaDeliveryProviderDN
+name: ms-Exch-Oma-Delivery-Provider-DN
+schemaIDGUID: 1f0e1a69-d62c-4105-991d-acaff4b07d71
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Device-Capability-DN     
+#
+dn: CN=ms-Exch-Oma-Device-Capability-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Device-Capability-DN
+distinguishedName: CN=ms-Exch-Oma-Device-Capability-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.133
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Device-Capability-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Oma-Device-Capability-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOmaDeviceCapabilityDN
+name: ms-Exch-Oma-Device-Capability-DN
+schemaIDGUID: 0510bdc4-9b19-4d67-93a1-8dda04c15568
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Oma-Extended-Properties      
+#
+dn: CN=ms-Exch-Oma-Extended-Properties,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Extended-Properties
+distinguishedName: CN=ms-Exch-Oma-Extended-Properties,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.143
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Extended-Properties
+adminDescription: ms-Exch-Oma-Extended-Properties
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaExtendedProperties
+name: ms-Exch-Oma-Extended-Properties
+schemaIDGUID: 9ebe537c-f882-473d-980b-ce52202a75d8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Formatter	
+#
+dn: CN=ms-Exch-Oma-Formatter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Formatter
+distinguishedName: CN=ms-Exch-Oma-Formatter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.135
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Formatter
+adminDescription: ms-Exch-Oma-Formatter
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaFormatter
+name: ms-Exch-Oma-Formatter
+schemaIDGUID: e827cd6a-b63c-4d44-961a-781a67949a36
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Translator    
+#
+dn: CN=ms-Exch-Oma-Translator,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Translator
+distinguishedName: CN=ms-Exch-Oma-Translator,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.136
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Translator
+adminDescription: ms-Exch-Oma-Translator
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaTranslator
+name: ms-Exch-Oma-Translator
+schemaIDGUID: d0f2588a-701e-4649-9379-062c62b93ef6
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Oma-Validater	    
+#
+dn: CN=ms-Exch-Oma-Validater,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Oma-Validater
+distinguishedName: CN=ms-Exch-Oma-Validater,${SCHEMADN}
+attributeID: 1.2.840.113556.1.6.20.1.134
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Oma-Validater
+adminDescription: ms-Exch-Oma-Validater
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOmaValidater
+name: ms-Exch-Oma-Validater
+schemaIDGUID: a87d0c40-cbbd-4da1-ba2e-704832fca5b1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-OOF-Reply-To-Originator    
+# Governs whether or not Out-Of-Office notifications should be sent to
+# a sender of a message to this DL.
+#
+dn: CN=ms-Exch-OOF-Reply-To-Originator,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-OOF-Reply-To-Originator
+distinguishedName: CN=ms-Exch-OOF-Reply-To-Originator,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.438
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33023
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OOF-Reply-To-Originator
+adminDescription: ms-Exch-OOF-Reply-To-Originator
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: oOFReplyToOriginator
+name: ms-Exch-OOF-Reply-To-Originator
+schemaIDGUID: a8df7440-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Open-Retry-Interval		   
+#
+dn: CN=ms-Exch-Open-Retry-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Open-Retry-Interval
+distinguishedName: CN=ms-Exch-Open-Retry-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.143
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33024
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Open-Retry-Interval
+adminDescription: ms-Exch-Open-Retry-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: openRetryInterval
+name: ms-Exch-Open-Retry-Interval
+schemaIDGUID: a8df7441-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Originating-Forest		   
+#
+dn: CN=ms-Exch-Originating-Forest,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Originating-Forest
+distinguishedName: CN=ms-Exch-Originating-Forest,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50300
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Originating-Forest
+adminDescription: ms-Exch-Originating-Forest
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchOriginatingForest
+name: ms-Exch-Originating-Forest
+schemaIDGUID: 16671de6-9753-47bf-9a12-be31abe0af08
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Orig-MDB 
+#
+dn: CN=ms-Exch-Orig-MDB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Orig-MDB
+distinguishedName: CN=ms-Exch-Orig-MDB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11093
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Orig-MDB
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Orig-MDB
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOrigMDB
+name: ms-Exch-Orig-MDB
+schemaIDGUID: f7b66927-7726-4e66-9ea8-efdf48d65201
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Other-Authentication-Flags	 
+#
+dn: CN=ms-Exch-Other-Authentication-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Other-Authentication-Flags
+distinguishedName: CN=ms-Exch-Other-Authentication-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2017
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Other-Authentication-Flags
+adminDescription: ms-Exch-Other-Authentication-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchOtherAuthenticationFlags
+name: ms-Exch-Other-Authentication-Flags
+schemaIDGUID: b4c7fe67-b523-4d2e-b56e-ac57b686c7e3
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Outbound-Sites   
+#
+dn: CN=ms-Exch-Outbound-Sites,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Outbound-Sites
+distinguishedName: CN=ms-Exch-Outbound-Sites,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.0
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33029
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Outbound-Sites
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Outbound-Sites
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: outboundSites
+name: ms-Exch-Outbound-Sites
+schemaIDGUID: a8df7445-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Outgoing-Msg-Size-Limit   
+#
+dn: CN=ms-Exch-Outgoing-Msg-Size-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Outgoing-Msg-Size-Limit
+distinguishedName: CN=ms-Exch-Outgoing-Msg-Size-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.490
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33167
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Outgoing-Msg-Size-Limit
+adminDescription: ms-Exch-Outgoing-Msg-Size-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: outgoingMsgSizeLimit
+name: ms-Exch-Outgoing-Msg-Size-Limit
+schemaIDGUID: a8df7446-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Overall-Age-Limit	    
+# Overall age limit for messages in public message databases
+# (MDBs). This is a store-wide setting.
+#
+dn: CN=ms-Exch-Overall-Age-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Overall-Age-Limit
+distinguishedName: CN=ms-Exch-Overall-Age-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11055
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Overall-Age-Limit
+adminDescription: ms-Exch-Overall-Age-Limit
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchOverallAgeLimit
+name: ms-Exch-Overall-Age-Limit
+schemaIDGUID: 9162c4ba-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-OWA-Server   
+#
+dn: CN=ms-Exch-OWA-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-OWA-Server
+distinguishedName: CN=ms-Exch-OWA-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.608
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 128
+mAPIID: 35942
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-OWA-Server
+adminDescription: ms-Exch-OWA-Server
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: oWAServer
+name: ms-Exch-OWA-Server
+schemaIDGUID: a8df7447-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Owning-Org   
+#
+dn: CN=ms-Exch-Owning-Org,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Owning-Org
+distinguishedName: CN=ms-Exch-Owning-Org,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11030
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Owning-Org
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Owning-Org
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOwningOrg
+name: ms-Exch-Owning-Org
+schemaIDGUID: 16f86ba4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Owning-PF-Tree   
+# The GUID of the public folder tree that is replicated to this store.
+#
+dn: CN=ms-Exch-Owning-PF-Tree,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Owning-PF-Tree
+distinguishedName: CN=ms-Exch-Owning-PF-Tree,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11031
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1008
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Owning-PF-Tree
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Owning-PF-Tree
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOwningPFTree
+name: ms-Exch-Owning-PF-Tree
+schemaIDGUID: 172a7d06-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Owning-PF-Tree-BL	
+# A read-only multivalued GUID list of public MDB instances of this
+# TLH.
+#
+dn: CN=ms-Exch-Owning-PF-Tree-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Owning-PF-Tree-BL
+distinguishedName: CN=ms-Exch-Owning-PF-Tree-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11032
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1009
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Owning-PF-Tree-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Owning-PF-Tree-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOwningPFTreeBL
+name: ms-Exch-Owning-PF-Tree-BL
+schemaIDGUID: 175a2c0e-b098-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Owning-Server	  
+# The DN of the Directory Service (DS) object for the server
+# containing this MDB.
+#
+dn: CN=ms-Exch-Owning-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Owning-Server
+distinguishedName: CN=ms-Exch-Owning-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11004
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Owning-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Owning-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchOwningServer
+name: ms-Exch-Owning-Server
+schemaIDGUID: 17910224-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Partner-CP	
+#
+dn: CN=ms-Exch-Partner-CP,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Partner-CP
+distinguishedName: CN=ms-Exch-Partner-CP,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1007
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Partner-CP
+adminDescription: ms-Exch-Partner-CP
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchPartnerCP
+name: ms-Exch-Partner-CP
+schemaIDGUID: 8a0c07b2-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Partner-Language  
+# The language (code page) of the connected foreign post office or
+# domain.
+#
+dn: CN=ms-Exch-Partner-Language,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Partner-Language
+distinguishedName: CN=ms-Exch-Partner-Language,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Partner-Language
+adminDescription: ms-Exch-Partner-Language
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchPartnerLanguage
+name: ms-Exch-Partner-Language
+schemaIDGUID: 17c7d83a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Patch-MDB 
+#
+dn: CN=ms-Exch-Patch-MDB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Patch-MDB
+distinguishedName: CN=ms-Exch-Patch-MDB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11086
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Patch-MDB
+adminDescription: ms-Exch-Patch-MDB
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchPatchMDB
+name: ms-Exch-Patch-MDB
+schemaIDGUID: bbdf5f8c-02d5-45ff-bab7-464d5452ebf4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-PF-Contacts	
+#
+dn: CN=ms-Exch-PF-Contacts,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-PF-Contacts
+distinguishedName: CN=ms-Exch-PF-Contacts,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.75
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32824
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PF-Contacts
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-PF-Contacts
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: pFContacts
+name: ms-Exch-PF-Contacts
+schemaIDGUID: f0f8ff98-1191-11d0-a060-00aa006c33ed
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Pf-Creation	
+#
+dn: CN=ms-Exch-Pf-Creation,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Pf-Creation
+distinguishedName: CN=ms-Exch-Pf-Creation,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.100
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Pf-Creation
+adminDescription: ms-Exch-Pf-Creation
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchPfCreation
+name: ms-Exch-Pf-Creation
+schemaIDGUID: ed1161ed-5d1e-4bb3-993f-11956d680ef6
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-PF-Default-Admin-ACL	 
+# On the TLH, this is the default set of rights for new Top Level
+# Folders. On the administrative group, this is the set of rights for
+# public folders that are homed on Exchange Server 5.5 that are
+# associated to this administrative group or site.
+#
+dn: CN=ms-Exch-PF-Default-Admin-ACL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-PF-Default-Admin-ACL
+distinguishedName: CN=ms-Exch-PF-Default-Admin-ACL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50035
+attributeSyntax: 2.5.5.15
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PF-Default-Admin-ACL
+adminDescription: ms-Exch-PF-Default-Admin-ACL
+oMSyntax: 66
+searchFlags: 0
+lDAPDisplayName: msExchPFDefaultAdminACL
+name: ms-Exch-PF-Default-Admin-ACL
+schemaIDGUID: 3de926b2-22af-11d3-aa62-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-PF-DS-Container   
+# The DN of the container into which message databases (MDBs) in this
+# domain will create folder objects.
+#
+dn: CN=ms-Exch-PF-DS-Container,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-PF-DS-Container
+distinguishedName: CN=ms-Exch-PF-DS-Container,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11034
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PF-DS-Container
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-PF-DS-Container
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchPFDSContainer
+name: ms-Exch-PF-DS-Container
+schemaIDGUID: 17feae50-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Pf-Root-Url	   
+# The URL to a user's public folder root.
+#
+dn: CN=ms-Exch-Pf-Root-Url,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Pf-Root-Url
+distinguishedName: CN=ms-Exch-Pf-Root-Url,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50086
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+mAPIID: 35970
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Pf-Root-Url
+adminDescription: ms-Exch-Pf-Root-Url
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchPfRootUrl
+name: ms-Exch-Pf-Root-Url
+schemaIDGUID: 3f50d651-bc97-47b3-aadc-c836d7fec446
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-PF-Tree-Type	  
+#
+dn: CN=ms-Exch-PF-Tree-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-PF-Tree-Type
+distinguishedName: CN=ms-Exch-PF-Tree-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11035
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PF-Tree-Type
+adminDescription: ms-Exch-PF-Tree-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchPFTreeType
+name: ms-Exch-PF-Tree-Type
+schemaIDGUID: 1830bfb2-b098-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policies-Excluded   
+#
+dn: CN=ms-Exch-Policies-Excluded,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policies-Excluded
+distinguishedName: CN=ms-Exch-Policies-Excluded,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50051
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policies-Excluded
+adminDescription: ms-Exch-Policies-Excluded
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchPoliciesExcluded
+name: ms-Exch-Policies-Excluded
+schemaIDGUID: 61c47258-454e-11d3-aa72-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policies-Included   
+#
+dn: CN=ms-Exch-Policies-Included,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policies-Included
+distinguishedName: CN=ms-Exch-Policies-Included,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50050
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policies-Included
+adminDescription: ms-Exch-Policies-Included
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchPoliciesIncluded
+name: ms-Exch-Policies-Included
+schemaIDGUID: 61c47253-454e-11d3-aa72-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-Default      
+#
+dn: CN=ms-Exch-Policy-Default,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Default
+distinguishedName: CN=ms-Exch-Policy-Default,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50007
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Default
+adminDescription: ms-Exch-Policy-Default
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchPolicyDefault
+name: ms-Exch-Policy-Default
+schemaIDGUID: 1865336e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-Enabled      
+# Specifies whether or not policies should be applied to this recipient.
+#
+dn: CN=ms-Exch-Policy-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Enabled
+distinguishedName: CN=ms-Exch-Policy-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50030
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Enabled
+adminDescription: ms-Exch-Policy-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchPolicyEnabled
+name: ms-Exch-Policy-Enabled
+schemaIDGUID: e32977dc-1d31-11d3-aa5e-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-Last-Applied-Time  
+# The time/date that this policy was applied.
+#
+dn: CN=ms-Exch-Policy-Last-Applied-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Last-Applied-Time
+distinguishedName: CN=ms-Exch-Policy-Last-Applied-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50023
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Last-Applied-Time
+adminDescription: ms-Exch-Policy-Last-Applied-Time
+oMSyntax: 24
+searchFlags: 0
+lDAPDisplayName: msExchPolicyLastAppliedTime
+name: ms-Exch-Policy-Last-Applied-Time
+schemaIDGUID: 92407f6c-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-List  
+# The list of policies a leaf object uses.
+#
+dn: CN=ms-Exch-Policy-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-List
+distinguishedName: CN=ms-Exch-Policy-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50004
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1012
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-List
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Policy-List
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchPolicyList
+name: ms-Exch-Policy-List
+schemaIDGUID: 18cbb88c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-List-BL   
+# A backlink to objects that use this policy.
+#
+dn: CN=ms-Exch-Policy-List-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-List-BL
+distinguishedName: CN=ms-Exch-Policy-List-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50005
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1013
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-List-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Policy-List-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchPolicyListBL
+name: ms-Exch-Policy-List-BL
+schemaIDGUID: 19028ea2-b098-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-LockDown   
+# If this is set, this policy cannot be removed from the object this
+# policy applies to.
+#
+dn: CN=ms-Exch-Policy-LockDown,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-LockDown
+distinguishedName: CN=ms-Exch-Policy-LockDown,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50008
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-LockDown
+adminDescription: ms-Exch-Policy-LockDown
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchPolicyLockDown
+name: ms-Exch-Policy-LockDown
+schemaIDGUID: 1934a004-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-Option-List  
+# The list that defines the set of property pages that are exposed on
+# this policy. Every property page (that will be policied) will be
+# assigned a GUID to uniquely identify it in this list.
+#
+dn: CN=ms-Exch-Policy-Option-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Option-List
+distinguishedName: CN=ms-Exch-Policy-Option-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50006
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Option-List
+adminDescription: ms-Exch-Policy-Option-List
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchPolicyOptionList
+name: ms-Exch-Policy-Option-List
+schemaIDGUID: 1966b166-b098-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Policy-Order	 
+# The order in which policies will be evaluated.
+#
+dn: CN=ms-Exch-Policy-Order,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Order
+distinguishedName: CN=ms-Exch-Policy-Order,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50027
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Order
+adminDescription: ms-Exch-Policy-Order
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchPolicyOrder
+name: ms-Exch-Policy-Order
+schemaIDGUID: e32977b1-1d31-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Policy-Roots	 
+# The list of distinguished names (DNs) of containers where policy
+# objects reside that the AL service will process.
+#
+dn: CN=ms-Exch-Policy-Roots,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Policy-Roots
+distinguishedName: CN=ms-Exch-Policy-Roots,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50028
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Policy-Roots
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Policy-Roots
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchPolicyRoots
+name: ms-Exch-Policy-Roots
+schemaIDGUID: e36ef110-1d40-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Poll-Interval	
+# The polling interval between scheduled runs if "Always" is selected.
+#
+dn: CN=ms-Exch-Poll-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Poll-Interval
+distinguishedName: CN=ms-Exch-Poll-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.58
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Poll-Interval
+adminDescription: ms-Exch-Poll-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchPollInterval
+name: ms-Exch-Poll-Interval
+schemaIDGUID: 1998c2c8-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-POP-Character-Set    
+#
+dn: CN=ms-Exch-POP-Character-Set,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-POP-Character-Set
+distinguishedName: CN=ms-Exch-POP-Character-Set,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.468
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 33145
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-POP-Character-Set
+adminDescription: ms-Exch-POP-Character-Set
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: pOPCharacterSet
+name: ms-Exch-POP-Character-Set
+schemaIDGUID: bf9679f8-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-POP-Content-Format   
+#
+dn: CN=ms-Exch-POP-Content-Format,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-POP-Content-Format
+distinguishedName: CN=ms-Exch-POP-Content-Format,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.466
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 33143
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-POP-Content-Format
+adminDescription: ms-Exch-POP-Content-Format
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: pOPContentFormat
+name: ms-Exch-POP-Content-Format
+schemaIDGUID: bf9679f9-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Port-Number	       
+#
+dn: CN=ms-Exch-Port-Number,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Port-Number
+distinguishedName: CN=ms-Exch-Port-Number,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.527
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+mAPIID: 33205
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Port-Number
+adminDescription: ms-Exch-Port-Number
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: portNumber
+name: ms-Exch-Port-Number
+schemaIDGUID: a8df744a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Preferred-Backfill-Source	
+#
+dn: CN=ms-Exch-Preferred-Backfill-Source,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Preferred-Backfill-Source
+distinguishedName: CN=ms-Exch-Preferred-Backfill-Source,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11094
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Preferred-Backfill-Source
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Preferred-Backfill-Source
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchPreferredBackfillSource
+name: ms-Exch-Preferred-Backfill-Source
+schemaIDGUID: 5e03e654-d85d-4908-83a1-6141048c5c62
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Preserve-Internet-Content	
+#
+dn: CN=ms-Exch-Preserve-Internet-Content,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Preserve-Internet-Content
+distinguishedName: CN=ms-Exch-Preserve-Internet-Content,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.556
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35874
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Preserve-Internet-Content
+adminDescription: ms-Exch-Preserve-Internet-Content
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: preserveInternetContent
+name: ms-Exch-Preserve-Internet-Content
+schemaIDGUID: a8df744c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Previous-Account-Sid		
+#
+dn: CN=ms-Exch-Previous-Account-Sid,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Previous-Account-Sid
+distinguishedName: CN=ms-Exch-Previous-Account-Sid,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.93
+attributeSyntax: 2.5.5.17
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 28
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Previous-Account-Sid
+adminDescription: ms-Exch-Previous-Account-Sid
+oMSyntax: 4
+searchFlags: 9
+lDAPDisplayName: msExchPreviousAccountSid
+name: ms-Exch-Previous-Account-Sid
+schemaIDGUID: 9f7f4160-8942-4e87-a3fd-165b7711e433
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Prev-Export-DLs		
+# A flag indicating whether DL names are propagated to foreign systems
+# via directory synchronization.
+#
+dn: CN=ms-Exch-Prev-Export-DLs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Prev-Export-DLs
+distinguishedName: CN=ms-Exch-Prev-Export-DLs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1002
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Prev-Export-DLs
+adminDescription: ms-Exch-Prev-Export-DLs
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchPrevExportDLs
+name: ms-Exch-Prev-Export-DLs
+schemaIDGUID: 48464774-30ca-11d3-aa6d-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-PRMD	  
+#
+dn: CN=ms-Exch-PRMD,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-PRMD
+distinguishedName: CN=ms-Exch-PRMD,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.224
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 33038
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-PRMD
+adminDescription: ms-Exch-PRMD
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: pRMD
+name: ms-Exch-PRMD
+schemaIDGUID: a8df744d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Processed-Sids   
+# A list of security identifiers (SIDs) that have already been
+# processed.
+#
+dn: CN=ms-Exch-Processed-Sids,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Processed-Sids
+distinguishedName: CN=ms-Exch-Processed-Sids,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.89
+attributeSyntax: 2.5.5.17
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Processed-Sids
+adminDescription: ms-Exch-Processed-Sids
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchProcessedSids
+name: ms-Exch-Processed-Sids
+schemaIDGUID: 5ab6a4b0-7d6c-4e84-848e-10d52b1eb735
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Promo-Expiration    
+#
+dn: CN=ms-Exch-Promo-Expiration,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Promo-Expiration
+distinguishedName: CN=ms-Exch-Promo-Expiration,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.540
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 33218
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Promo-Expiration
+adminDescription: ms-Exch-Promo-Expiration
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: promoExpiration
+name: ms-Exch-Promo-Expiration
+schemaIDGUID: 1677585d-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Protocol-Settings   
+# Exchange Internet protocol settings.
+#
+dn: CN=ms-Exch-Protocol-Settings,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Protocol-Settings
+distinguishedName: CN=ms-Exch-Protocol-Settings,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.528
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 0
+rangeUpper: 256
+mAPIID: 33206
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Protocol-Settings
+adminDescription: ms-Exch-Protocol-Settings
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: protocolSettings
+name: ms-Exch-Protocol-Settings
+schemaIDGUID: 1677585e-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Proxy-Custom-Proxy	
+#
+dn: CN=ms-Exch-Proxy-Custom-Proxy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Proxy-Custom-Proxy
+distinguishedName: CN=ms-Exch-Proxy-Custom-Proxy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50048
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Proxy-Custom-Proxy
+adminDescription: ms-Exch-Proxy-Custom-Proxy
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchProxyCustomProxy
+name: ms-Exch-Proxy-Custom-Proxy
+schemaIDGUID: 47bc3aa6-3634-11d3-aa6e-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Proxy-Generator-DLL	
+#
+dn: CN=ms-Exch-Proxy-Generator-DLL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Proxy-Generator-DLL
+distinguishedName: CN=ms-Exch-Proxy-Generator-DLL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.328
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 255
+mAPIID: 33039
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Proxy-Generator-DLL
+adminDescription: ms-Exch-Proxy-Generator-DLL
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: proxyGeneratorDLL
+name: ms-Exch-Proxy-Generator-DLL
+schemaIDGUID: a8df744e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Proxy-Gen-Server	
+# The time/date that this policy was applied.
+#
+dn: CN=ms-Exch-Proxy-Gen-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Proxy-Gen-Server
+distinguishedName: CN=ms-Exch-Proxy-Gen-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50013
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Proxy-Gen-Server
+adminDescription: ms-Exch-Proxy-Gen-Server
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchProxyGenServer
+name: ms-Exch-Proxy-Gen-Server
+schemaIDGUID: 1a2a323a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Proxy-Name   
+# The data conference proxy name.
+#
+dn: CN=ms-Exch-Proxy-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Proxy-Name
+distinguishedName: CN=ms-Exch-Proxy-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9018
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Proxy-Name
+adminDescription: ms-Exch-Proxy-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchProxyName
+name: ms-Exch-Proxy-Name
+schemaIDGUID: 1a610850-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-Delegates	
+# The DN of other mailboxes that can send on behalf of this mailbox.
+#
+dn: CN=ms-Exch-Public-Delegates,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Public-Delegates
+distinguishedName: CN=ms-Exch-Public-Delegates,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.238
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 32789
+linkID: 14
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-Delegates
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Public-Delegates
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: publicDelegates
+name: ms-Exch-Public-Delegates
+schemaIDGUID: f0f8ff9a-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: 77b5b886-944a-11d1-aebd-0000f80367c1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Public-Delegates-BL	
+#
+dn: CN=ms-Exch-Public-Delegates-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Public-Delegates-BL
+distinguishedName: CN=ms-Exch-Public-Delegates-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.295
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33040
+linkID: 15
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Public-Delegates-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Public-Delegates-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: publicDelegatesBL
+name: ms-Exch-Public-Delegates-BL
+schemaIDGUID: bf967a08-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Purported-Search-UI	
+# Stores the UI settings that set the purported search attribute.
+#
+dn: CN=ms-Exch-Purported-Search-UI,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Purported-Search-UI
+distinguishedName: CN=ms-Exch-Purported-Search-UI,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.66
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Purported-Search-UI
+adminDescription: ms-Exch-Purported-Search-UI
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchPurportedSearchUI
+name: ms-Exch-Purported-Search-UI
+schemaIDGUID: 1d86e324-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-P-Selector	
+#
+dn: CN=ms-Exch-P-Selector,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-P-Selector
+distinguishedName: CN=ms-Exch-P-Selector,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.285
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 33030
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-P-Selector
+adminDescription: ms-Exch-P-Selector
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: pSelector
+name: ms-Exch-P-Selector
+schemaIDGUID: a8df7448-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-P-Selector-Inbound	 
+#
+dn: CN=ms-Exch-P-Selector-Inbound,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-P-Selector-Inbound
+distinguishedName: CN=ms-Exch-P-Selector-Inbound,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.52
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 33031
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-P-Selector-Inbound
+adminDescription: ms-Exch-P-Selector-Inbound
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: pSelectorInbound
+name: ms-Exch-P-Selector-Inbound
+schemaIDGUID: a8df7449-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Query-Base-DN		 
+# Defines the scope for client queries on address lists.
+#
+dn: CN=ms-Exch-Query-Base-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Query-Base-DN
+distinguishedName: CN=ms-Exch-Query-Base-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15008
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Query-Base-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Query-Base-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchQueryBaseDN
+name: ms-Exch-Query-Base-DN
+schemaIDGUID: 399eb12c-e120-473c-b0f7-97ae7ca4988b
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Queuing-MDB	     
+#
+dn: CN=ms-Exch-Queuing-MDB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Queuing-MDB
+distinguishedName: CN=ms-Exch-Queuing-MDB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11054
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Queuing-MDB
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Queuing-MDB
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchQueuingMDB
+name: ms-Exch-Queuing-MDB
+schemaIDGUID: 8afa72da-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Quota-Notification-Schedule 
+#
+dn: CN=ms-Exch-Quota-Notification-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Quota-Notification-Schedule
+distinguishedName: CN=ms-Exch-Quota-Notification-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.98
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 84
+rangeUpper: 84
+mAPIID: 33041
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Quota-Notification-Schedule
+adminDescription: ms-Exch-Quota-Notification-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: quotaNotificationSchedule
+name: ms-Exch-Quota-Notification-Schedule
+schemaIDGUID: a8df744f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Quota-Notification-Style    
+#
+dn: CN=ms-Exch-Quota-Notification-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Quota-Notification-Style
+distinguishedName: CN=ms-Exch-Quota-Notification-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.388
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33042
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Quota-Notification-Style
+adminDescription: ms-Exch-Quota-Notification-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: quotaNotificationStyle
+name: ms-Exch-Quota-Notification-Style
+schemaIDGUID: a8df7450-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RAS-Callback-Number	      
+#
+dn: CN=ms-Exch-RAS-Callback-Number,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RAS-Callback-Number
+distinguishedName: CN=ms-Exch-RAS-Callback-Number,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.315
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 48
+mAPIID: 33045
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-Callback-Number
+adminDescription: ms-Exch-RAS-Callback-Number
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: rASCallbackNumber
+name: ms-Exch-RAS-Callback-Number
+schemaIDGUID: a8df7452-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RAS-Phonebook-Entry-Name    
+#
+dn: CN=ms-Exch-RAS-Phonebook-Entry-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RAS-Phonebook-Entry-Name
+distinguishedName: CN=ms-Exch-RAS-Phonebook-Entry-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.313
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 33047
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-Phonebook-Entry-Name
+adminDescription: ms-Exch-RAS-Phonebook-Entry-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: rASPhonebookEntryName
+name: ms-Exch-RAS-Phonebook-Entry-Name
+schemaIDGUID: a8df7455-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RAS-Phone-Number	      
+#
+dn: CN=ms-Exch-RAS-Phone-Number,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RAS-Phone-Number
+distinguishedName: CN=ms-Exch-RAS-Phone-Number,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.314
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33046
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-Phone-Number
+adminDescription: ms-Exch-RAS-Phone-Number
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: rASPhoneNumber
+name: ms-Exch-RAS-Phone-Number
+schemaIDGUID: a8df7454-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RAS-Remote-SRVR-Name	      
+#
+dn: CN=ms-Exch-RAS-Remote-SRVR-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RAS-Remote-SRVR-Name
+distinguishedName: CN=ms-Exch-RAS-Remote-SRVR-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.78
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 15
+mAPIID: 33048
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RAS-Remote-SRVR-Name
+adminDescription: ms-Exch-RAS-Remote-SRVR-Name
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: rASRemoteSRVRName
+name: ms-Exch-RAS-Remote-SRVR-Name
+schemaIDGUID: a8df7456-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Recip-Limit		      
+# The maximum number of recipients this user may send to, or a global
+# maximum for the organization.
+#
+dn: CN=ms-Exch-Recip-Limit,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Recip-Limit
+distinguishedName: CN=ms-Exch-Recip-Limit,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12523
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recip-Limit
+adminDescription: ms-Exch-Recip-Limit
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: msExchRecipLimit
+name: ms-Exch-Recip-Limit
+schemaIDGUID: 1dd7f318-b098-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Recip-Turf-List-Names	   
+#
+dn: CN=ms-Exch-Recip-Turf-List-Names,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Recip-Turf-List-Names
+distinguishedName: CN=ms-Exch-Recip-Turf-List-Names,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5070
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recip-Turf-List-Names
+adminDescription: ms-Exch-Recip-Turf-List-Names
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchRecipTurfListNames
+name: ms-Exch-Recip-Turf-List-Names
+schemaIDGUID: 2e0a68e1-bdd7-4899-8bb2-d6ea007558c7
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Recip-Turf-List-Options  
+#
+dn: CN=ms-Exch-Recip-Turf-List-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Recip-Turf-List-Options
+distinguishedName: CN=ms-Exch-Recip-Turf-List-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5071
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recip-Turf-List-Options
+adminDescription: ms-Exch-Recip-Turf-List-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchRecipTurfListOptions
+name: ms-Exch-Recip-Turf-List-Options
+schemaIDGUID: 870b36b3-d035-402d-b873-ced07b173763
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Recovery	
+# If recovery is on, log files are generated.
+#
+dn: CN=ms-Exch-Recovery,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Recovery
+distinguishedName: CN=ms-Exch-Recovery,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11046
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Recovery
+adminDescription: ms-Exch-Recovery
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchRecovery
+name: ms-Exch-Recovery
+schemaIDGUID: 1e007b12-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Referral-List	 
+#
+dn: CN=ms-Exch-Referral-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Referral-List
+distinguishedName: CN=ms-Exch-Referral-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.510
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33187
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Referral-List
+adminDescription: ms-Exch-Referral-List
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: referralList
+name: ms-Exch-Referral-List
+schemaIDGUID: a8df7457-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Remote-Bridge-Head 
+#
+dn: CN=ms-Exch-Remote-Bridge-Head,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Remote-Bridge-Head
+distinguishedName: CN=ms-Exch-Remote-Bridge-Head,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.191
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 33050
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-Bridge-Head
+adminDescription: ms-Exch-Remote-Bridge-Head
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: remoteBridgeHead
+name: ms-Exch-Remote-Bridge-Head
+schemaIDGUID: a8df7458-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Remote-Bridge-Head-Address  
+#
+dn: CN=ms-Exch-Remote-Bridge-Head-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Remote-Bridge-Head-Address
+distinguishedName: CN=ms-Exch-Remote-Bridge-Head-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.94
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 1118
+mAPIID: 33051
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-Bridge-Head-Address
+adminDescription: ms-Exch-Remote-Bridge-Head-Address
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: remoteBridgeHeadAddress
+name: ms-Exch-Remote-Bridge-Head-Address
+schemaIDGUID: a8df7459-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Remote-Private-IS-List      
+# A flat delimited set of distinguished names (DNs) of remote Exchange
+# private stores. Used to set home-mdb on user objects.
+#
+dn: CN=ms-Exch-Remote-Private-IS-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Remote-Private-IS-List
+distinguishedName: CN=ms-Exch-Remote-Private-IS-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.46
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-Private-IS-List
+adminDescription: ms-Exch-Remote-Private-IS-List
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchRemotePrivateISList
+name: ms-Exch-Remote-Private-IS-List
+schemaIDGUID: 1e29030c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Remote-Server-List  
+# A flat delimited set of distinguished names (DNs) of remote Exchange
+# servers. Used to set home-mta on DL objects.
+#
+dn: CN=ms-Exch-Remote-Server-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Remote-Server-List
+distinguishedName: CN=ms-Exch-Remote-Server-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.45
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-Server-List
+adminDescription: ms-Exch-Remote-Server-List
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchRemoteServerList
+name: ms-Exch-Remote-Server-List
+schemaIDGUID: 1e58b214-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Remote-Site	      
+#
+dn: CN=ms-Exch-Remote-Site,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Remote-Site
+distinguishedName: CN=ms-Exch-Remote-Site,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.27
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33053
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Remote-Site
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Remote-Site
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: remoteSite
+name: ms-Exch-Remote-Site
+schemaIDGUID: a8df745b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replicated-Object-Version    
+#
+dn: CN=ms-Exch-Replicated-Object-Version,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replicated-Object-Version
+distinguishedName: CN=ms-Exch-Replicated-Object-Version,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.604
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 35938
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replicated-Object-Version
+adminDescription: ms-Exch-Replicated-Object-Version
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: replicatedObjectVersion
+name: ms-Exch-Replicated-Object-Version
+schemaIDGUID: 1677586c-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Replicate-Now	      
+# A flag that notifies the service to replicate this connection
+# agreement immediately.
+#
+dn: CN=ms-Exch-Replicate-Now,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replicate-Now
+distinguishedName: CN=ms-Exch-Replicate-Now,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.53
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replicate-Now
+adminDescription: ms-Exch-Replicate-Now
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchReplicateNow
+name: ms-Exch-Replicate-Now
+schemaIDGUID: 1eac2462-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Replication-Mail-Msg-Size
+#
+dn: CN=ms-Exch-Replication-Mail-Msg-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Mail-Msg-Size
+distinguishedName: CN=ms-Exch-Replication-Mail-Msg-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.103
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33128
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Mail-Msg-Size
+adminDescription: ms-Exch-Replication-Mail-Msg-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: replicationMailMsgSize
+name: ms-Exch-Replication-Mail-Msg-Size
+schemaIDGUID: a8df745c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Replication-Msg-Size	
+# The replication message size limit.
+dn: CN=ms-Exch-Replication-Msg-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Msg-Size
+distinguishedName: CN=ms-Exch-Replication-Msg-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11047
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Msg-Size
+adminDescription: ms-Exch-Replication-Msg-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchReplicationMsgSize
+name: ms-Exch-Replication-Msg-Size
+schemaIDGUID: 1ed70eb6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Replication-Schedule	
+# The schedule of when to replicate public folder changes.
+#
+dn: CN=ms-Exch-Replication-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Schedule
+distinguishedName: CN=ms-Exch-Replication-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11048
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Schedule
+adminDescription: ms-Exch-Replication-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchReplicationSchedule
+name: ms-Exch-Replication-Schedule
+schemaIDGUID: 1f01f90a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replication-Sensitivity	
+# Used by Exchange on legacy Exchange Server 5.5 connectors to govern
+# their use by replication.
+#
+dn: CN=ms-Exch-Replication-Sensitivity,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Sensitivity
+distinguishedName: CN=ms-Exch-Replication-Sensitivity,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.223
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 100
+mAPIID: 33054
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Sensitivity
+adminDescription: ms-Exch-Replication-Sensitivity
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: replicationSensitivity
+name: ms-Exch-Replication-Sensitivity
+schemaIDGUID: bf967a1b-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replication-Signature	   
+# Signature used for replication purposes by the Active Directory Connector.
+# 
+dn: CN=ms-Exch-Replication-Signature,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Signature
+distinguishedName: CN=ms-Exch-Replication-Signature,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.52
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Signature
+adminDescription: ms-Exch-Replication-Signature
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: replicationSignature
+name: ms-Exch-Replication-Signature
+schemaIDGUID: 9909d92a-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Replication-Stagger	
+#
+dn: CN=ms-Exch-Replication-Stagger,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Stagger
+distinguishedName: CN=ms-Exch-Replication-Stagger,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.349
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33055
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Stagger
+adminDescription: ms-Exch-Replication-Stagger
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: replicationStagger
+name: ms-Exch-Replication-Stagger
+schemaIDGUID: a8df745d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Replication-Style	
+# The style for replicating public folder changes, such as Always or Never.
+#
+dn: CN=ms-Exch-Replication-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Replication-Style
+distinguishedName: CN=ms-Exch-Replication-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11049
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Replication-Style
+adminDescription: ms-Exch-Replication-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchReplicationStyle
+name: ms-Exch-Replication-Style
+schemaIDGUID: 1f2ce35e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Report-To-Originator	
+#
+dn: CN=ms-Exch-Report-To-Originator,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Report-To-Originator
+distinguishedName: CN=ms-Exch-Report-To-Originator,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.206
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33056
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Report-To-Originator
+adminDescription: ms-Exch-Report-To-Originator
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: reportToOriginator
+name: ms-Exch-Report-To-Originator
+schemaIDGUID: a8df745e-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Report-To-Owner	
+# Governs whether or not read receipts and delivery receipts will be sent to the sender of messages sent to this DL.
+#
+dn: CN=ms-Exch-Report-To-Owner,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Report-To-Owner
+distinguishedName: CN=ms-Exch-Report-To-Owner,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.207
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33057
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Report-To-Owner
+adminDescription: ms-Exch-Report-To-Owner
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: reportToOwner
+name: ms-Exch-Report-To-Owner
+schemaIDGUID: a8df745f-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-RequireAuthToSendTo	 
+#
+dn: CN=ms-Exch-RequireAuthToSendTo,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RequireAuthToSendTo
+distinguishedName: CN=ms-Exch-RequireAuthToSendTo,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.5062
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RequireAuthToSendTo
+adminDescription: ms-Exch-RequireAuthToSendTo
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchRequireAuthToSendTo
+name: ms-Exch-RequireAuthToSendTo
+schemaIDGUID: f533eb3b-f75b-4fb3-b2fb-08cd537a84d1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Require-SSL		 
+#
+dn: CN=ms-Exch-Require-SSL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Require-SSL
+distinguishedName: CN=ms-Exch-Require-SSL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.560
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35877
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Require-SSL
+adminDescription: ms-Exch-Require-SSL
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: requireSSL
+name: ms-Exch-Require-SSL
+schemaIDGUID: a8df7461-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Req-Seq		 
+#
+dn: CN=ms-Exch-Req-Seq,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Req-Seq
+distinguishedName: CN=ms-Exch-Req-Seq,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.173
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33058
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Req-Seq
+adminDescription: ms-Exch-Req-Seq
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: reqSeq
+name: ms-Exch-Req-Seq
+schemaIDGUID: a8df7460-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Resolve-P2		 
+#
+dn: CN=ms-Exch-Resolve-P2,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Resolve-P2
+distinguishedName: CN=ms-Exch-Resolve-P2,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12538
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Resolve-P2
+adminDescription: ms-Exch-Resolve-P2
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchResolveP2
+name: ms-Exch-Resolve-P2
+schemaIDGUID: e24d7aa1-439d-11d3-aa72-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Resource-GUID		 
+# The CTP GUID.
+#
+dn: CN=ms-Exch-Resource-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Resource-GUID
+distinguishedName: CN=ms-Exch-Resource-GUID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9001
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Resource-GUID
+adminDescription: ms-Exch-Resource-GUID
+oMSyntax: 64
+searchFlags: 17
+lDAPDisplayName: msExchResourceGUID
+name: ms-Exch-Resource-GUID
+schemaIDGUID: 1f57cdb2-b098-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Resource-Properties	
+# Resource values specific to the CTP.
+#
+dn: CN=ms-Exch-Resource-Properties,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Resource-Properties
+distinguishedName: CN=ms-Exch-Resource-Properties,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9025
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Resource-Properties
+adminDescription: ms-Exch-Resource-Properties
+oMSyntax: 64
+searchFlags: 16
+lDAPDisplayName: msExchResourceProperties
+name: ms-Exch-Resource-Properties
+schemaIDGUID: 912beea4-b09e-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Responsible-Local-DXA	
+#
+dn: CN=ms-Exch-Responsible-Local-DXA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Responsible-Local-DXA
+distinguishedName: CN=ms-Exch-Responsible-Local-DXA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.298
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33059
+linkID: 122
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Responsible-Local-DXA
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Responsible-Local-DXA
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: responsibleLocalDXA
+name: ms-Exch-Responsible-Local-DXA
+schemaIDGUID: a8df7462-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Responsible-MTA-Server    
+#
+dn: CN=ms-Exch-Responsible-MTA-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Responsible-MTA-Server
+distinguishedName: CN=ms-Exch-Responsible-MTA-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50033
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1030
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Responsible-MTA-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Responsible-MTA-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchResponsibleMTAServer
+name: ms-Exch-Responsible-MTA-Server
+schemaIDGUID: 9ff15c37-1ec9-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Responsible-MTA-Server-BL	 
+#
+dn: CN=ms-Exch-Responsible-MTA-Server-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Responsible-MTA-Server-BL
+distinguishedName: CN=ms-Exch-Responsible-MTA-Server-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50034
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1031
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Responsible-MTA-Server-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Responsible-MTA-Server-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchResponsibleMTAServerBL
+name: ms-Exch-Responsible-MTA-Server-BL
+schemaIDGUID: 9ff15c3c-1ec9-11d3-aa5e-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Restore	  
+#
+dn: CN=ms-Exch-Restore,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Restore
+distinguishedName: CN=ms-Exch-Restore,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11092
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Restore
+adminDescription: ms-Exch-Restore
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchRestore
+name: ms-Exch-Restore
+schemaIDGUID: a1edcb4c-5c45-4d4a-b128-880392e9dcc6
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Return-Exact-Msg-Size	   
+#
+dn: CN=ms-Exch-Return-Exact-Msg-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Return-Exact-Msg-Size
+distinguishedName: CN=ms-Exch-Return-Exact-Msg-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.594
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35922
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Return-Exact-Msg-Size
+adminDescription: ms-Exch-Return-Exact-Msg-Size
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: returnExactMsgSize
+name: ms-Exch-Return-Exact-Msg-Size
+schemaIDGUID: a8df7463-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Rid-Server  
+# A pointer to the server that maintains the Gateway Address
+# Resolution Table (GWART) for this site or administrative group.
+#
+dn: CN=ms-Exch-Rid-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Rid-Server
+distinguishedName: CN=ms-Exch-Rid-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.346
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33060
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Rid-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Rid-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: ridServer
+name: ms-Exch-Rid-Server
+schemaIDGUID: a8df7464-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Role-Includes	       
+# The set of other roles that this role includes.
+#
+dn: CN=ms-Exch-Role-Includes,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Role-Includes
+distinguishedName: CN=ms-Exch-Role-Includes,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50020
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Role-Includes
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Role-Includes
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchRoleIncludes
+name: ms-Exch-Role-Includes
+schemaIDGUID: 1f8055ac-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Role-Localized-Names	
+# The OAB that this mailbox store or this user uses.
+#
+dn: CN=ms-Exch-Role-Localized-Names,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Role-Localized-Names
+distinguishedName: CN=ms-Exch-Role-Localized-Names,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50021
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Role-Localized-Names
+adminDescription: ms-Exch-Role-Localized-Names
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchRoleLocalizedNames
+name: ms-Exch-Role-Localized-Names
+schemaIDGUID: 1fa8dda6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Role-Rights	
+# The set of rights, per objectClass, that this role includes.
+#
+dn: CN=ms-Exch-Role-Rights,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Role-Rights
+distinguishedName: CN=ms-Exch-Role-Rights,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50018
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Role-Rights
+adminDescription: ms-Exch-Role-Rights
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchRoleRights
+name: ms-Exch-Role-Rights
+schemaIDGUID: 1fd165a0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Root-Newsgroups-Folder-ID   
+#
+dn: CN=ms-Exch-Root-Newsgroups-Folder-ID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Root-Newsgroups-Folder-ID
+distinguishedName: CN=ms-Exch-Root-Newsgroups-Folder-ID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.524
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33202
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Root-Newsgroups-Folder-ID
+adminDescription: ms-Exch-Root-Newsgroups-Folder-ID
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: rootNewsgroupsFolderID
+name: ms-Exch-Root-Newsgroups-Folder-ID
+schemaIDGUID: a8df7466-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Accept-Message-Type 
+#
+dn: CN=ms-Exch-Routing-Accept-Message-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Accept-Message-Type
+distinguishedName: CN=ms-Exch-Routing-Accept-Message-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12517
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Accept-Message-Type
+adminDescription: ms-Exch-Routing-Accept-Message-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchRoutingAcceptMessageType
+name: ms-Exch-Routing-Accept-Message-Type
+schemaIDGUID: 881759de-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Disallow-Priority   
+#
+dn: CN=ms-Exch-Routing-Disallow-Priority,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Disallow-Priority
+distinguishedName: CN=ms-Exch-Routing-Disallow-Priority,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12529
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Disallow-Priority
+adminDescription: ms-Exch-Routing-Disallow-Priority
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchRoutingDisallowPriority
+name: ms-Exch-Routing-Disallow-Priority
+schemaIDGUID: 909a7f32-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Routing-Display-Sender-Enabled  
+#
+dn: CN=ms-Exch-Routing-Display-Sender-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Display-Sender-Enabled
+distinguishedName: CN=ms-Exch-Routing-Display-Sender-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12519
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Display-Sender-Enabled
+adminDescription: ms-Exch-Routing-Display-Sender-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchRoutingDisplaySenderEnabled
+name: ms-Exch-Routing-Display-Sender-Enabled
+schemaIDGUID: 88dadab2-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Enabled      
+# This flag enables or disables the routing for the entire
+# organization.
+#
+dn: CN=ms-Exch-Routing-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Enabled
+distinguishedName: CN=ms-Exch-Routing-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12528
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Enabled
+adminDescription: ms-Exch-Routing-Enabled
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchRoutingEnabled
+name: ms-Exch-Routing-Enabled
+schemaIDGUID: 89f1cdd4-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Routing-ETRN-Domains	  
+# Contains the list of domain names (such as example.com) for which an
+# ETRN command should be issued.
+#
+dn: CN=ms-Exch-Routing-ETRN-Domains,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-ETRN-Domains
+distinguishedName: CN=ms-Exch-Routing-ETRN-Domains,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12530
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-ETRN-Domains
+adminDescription: ms-Exch-Routing-ETRN-Domains
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchRoutingETRNDomains
+name: ms-Exch-Routing-ETRN-Domains
+schemaIDGUID: 62a383c0-2d9d-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Group-Members-BL 
+#
+dn: CN=ms-Exch-Routing-Group-Members-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Group-Members-BL
+distinguishedName: CN=ms-Exch-Routing-Group-Members-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12540
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1051
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Group-Members-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Routing-Group-Members-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchRoutingGroupMembersBL
+name: ms-Exch-Routing-Group-Members-BL
+schemaIDGUID: fa9635c0-4acb-47de-ad00-1880b590481b
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Group-Members-DN 
+# Pointers to virtual servers of servers in a Exchange Routing Group.
+#
+dn: CN=ms-Exch-Routing-Group-Members-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Group-Members-DN
+distinguishedName: CN=ms-Exch-Routing-Group-Members-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12506
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1000
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Group-Members-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Routing-Group-Members-DN
+oMSyntax: 127
+searchFlags: 1
+lDAPDisplayName: msExchRoutingGroupMembersDN
+name: ms-Exch-Routing-Group-Members-DN
+schemaIDGUID: 1ff9ed9a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-List 
+# The address space of addresses allowed to be used on the connector.
+#
+dn: CN=ms-Exch-Routing-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-List
+distinguishedName: CN=ms-Exch-Routing-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.354
+attributeSyntax: 2.5.5.4
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 2243
+mAPIID: 33062
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-List
+adminDescription: ms-Exch-Routing-List
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: routingList
+name: ms-Exch-Routing-List
+schemaIDGUID: a8df7467-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Master-DN    
+# A pointer to the virtual server of the master of the Exchange
+# Routing Group.
+#
+dn: CN=ms-Exch-Routing-Master-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Master-DN
+distinguishedName: CN=ms-Exch-Routing-Master-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12505
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Master-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Routing-Master-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchRoutingMasterDN
+name: ms-Exch-Routing-Master-DN
+schemaIDGUID: 2024d7ee-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Routing-Oversized-Schedule  
+#
+dn: CN=ms-Exch-Routing-Oversized-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Oversized-Schedule
+distinguishedName: CN=ms-Exch-Routing-Oversized-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12520
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Oversized-Schedule
+adminDescription: ms-Exch-Routing-Oversized-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchRoutingOversizedSchedule
+name: ms-Exch-Routing-Oversized-Schedule
+schemaIDGUID: 88f51490-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Routing-Oversized-Style     
+#
+dn: CN=ms-Exch-Routing-Oversized-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Oversized-Style
+distinguishedName: CN=ms-Exch-Routing-Oversized-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12521
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Oversized-Style
+adminDescription: ms-Exch-Routing-Oversized-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchRoutingOversizedStyle
+name: ms-Exch-Routing-Oversized-Style
+schemaIDGUID: 89141322-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Routing-Triggered-Schedule  
+#
+dn: CN=ms-Exch-Routing-Triggered-Schedule,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Triggered-Schedule
+distinguishedName: CN=ms-Exch-Routing-Triggered-Schedule,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12526
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Triggered-Schedule
+adminDescription: ms-Exch-Routing-Triggered-Schedule
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchRoutingTriggeredSchedule
+name: ms-Exch-Routing-Triggered-Schedule
+schemaIDGUID: 892e4d00-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Routing-Triggered-Style     
+#
+dn: CN=ms-Exch-Routing-Triggered-Style,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Routing-Triggered-Style
+distinguishedName: CN=ms-Exch-Routing-Triggered-Style,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12525
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Routing-Triggered-Style
+adminDescription: ms-Exch-Routing-Triggered-Style
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchRoutingTriggeredStyle
+name: ms-Exch-Routing-Triggered-Style
+schemaIDGUID: 894ae938-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-RTS-Checkpoint-Size	      
+#
+dn: CN=ms-Exch-RTS-Checkpoint-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RTS-Checkpoint-Size
+distinguishedName: CN=ms-Exch-RTS-Checkpoint-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.152
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 100
+mAPIID: 33063
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RTS-Checkpoint-Size
+adminDescription: ms-Exch-RTS-Checkpoint-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: rTSCheckpointSize
+name: ms-Exch-RTS-Checkpoint-Size
+schemaIDGUID: a8df7468-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-RTS-Recovery-Timeout	      
+#
+dn: CN=ms-Exch-RTS-Recovery-Timeout,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RTS-Recovery-Timeout
+distinguishedName: CN=ms-Exch-RTS-Recovery-Timeout,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.151
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33064
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RTS-Recovery-Timeout
+adminDescription: ms-Exch-RTS-Recovery-Timeout
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: rTSRecoveryTimeout
+name: ms-Exch-RTS-Recovery-Timeout
+schemaIDGUID: a8df7469-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-RTS-Window-Size	      
+#
+dn: CN=ms-Exch-RTS-Window-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-RTS-Window-Size
+distinguishedName: CN=ms-Exch-RTS-Window-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.153
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 10
+mAPIID: 33065
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-RTS-Window-Size
+adminDescription: ms-Exch-RTS-Window-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: rTSWindowSize
+name: ms-Exch-RTS-Window-Size
+schemaIDGUID: a8df746a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Runs-On		      
+#
+dn: CN=ms-Exch-Runs-On,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Runs-On
+distinguishedName: CN=ms-Exch-Runs-On,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.185
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33066
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Runs-On
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Runs-On
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: runsOn
+name: ms-Exch-Runs-On
+schemaIDGUID: a8df746b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Sasl-Logon-Domain	      
+# The logon domain used for SASL.
+dn: CN=ms-Exch-Sasl-Logon-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Sasl-Logon-Domain
+distinguishedName: CN=ms-Exch-Sasl-Logon-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2008
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Sasl-Logon-Domain
+adminDescription: ms-Exch-Sasl-Logon-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSaslLogonDomain
+name: ms-Exch-Sasl-Logon-Domain
+schemaIDGUID: 209c0d82-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-SASL-Mechanisms	
+#
+dn: CN=ms-Exch-SASL-Mechanisms,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SASL-Mechanisms
+distinguishedName: CN=ms-Exch-SASL-Mechanisms,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2018
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SASL-Mechanisms
+adminDescription: ms-Exch-SASL-Mechanisms
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSASLMechanisms
+name: ms-Exch-SASL-Mechanisms
+schemaIDGUID: d93571b4-c99a-4cfc-aaba-2d809fd68e79
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Sched-Plus-AG-Only	
+#
+dn: CN=ms-Exch-Sched-Plus-AG-Only,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Sched-Plus-AG-Only
+distinguishedName: CN=ms-Exch-Sched-Plus-AG-Only,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1191
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Sched-Plus-AG-Only
+adminDescription: ms-Exch-Sched-Plus-AG-Only
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSchedPlusAGOnly
+name: ms-Exch-Sched-Plus-AG-Only
+schemaIDGUID: b1fce956-1d44-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Sched-Plus-Full-Update   
+#
+dn: CN=ms-Exch-Sched-Plus-Full-Update,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Sched-Plus-Full-Update
+distinguishedName: CN=ms-Exch-Sched-Plus-Full-Update,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1190
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Sched-Plus-Full-Update
+adminDescription: ms-Exch-Sched-Plus-Full-Update
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSchedPlusFullUpdate
+name: ms-Exch-Sched-Plus-Full-Update
+schemaIDGUID: b1fce950-1d44-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Sched-Plus-Schedist 
+#
+dn: CN=ms-Exch-Sched-Plus-Schedist,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Sched-Plus-Schedist
+distinguishedName: CN=ms-Exch-Sched-Plus-Schedist,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1192
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Sched-Plus-Schedist
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Sched-Plus-Schedist
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchSchedPlusSchedist
+name: ms-Exch-Sched-Plus-Schedist
+schemaIDGUID: b1fce94c-1d44-11d3-aa5e-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Schema-Policy-Consumers  
+# A link to all CAs that use this schema policy.
+#
+dn: CN=ms-Exch-Schema-Policy-Consumers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Schema-Policy-Consumers
+distinguishedName: CN=ms-Exch-Schema-Policy-Consumers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.57
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1007
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Schema-Policy-Consumers
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Schema-Policy-Consumers
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchSchemaPolicyConsumers
+name: ms-Exch-Schema-Policy-Consumers
+schemaIDGUID: 20c6f7d6-b098-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Schema-Version-Adc	   
+#
+dn: CN=ms-Exch-Schema-Version-Adc,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Schema-Version-Adc
+distinguishedName: CN=ms-Exch-Schema-Version-Adc,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.98
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 4197
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Schema-Version-Adc
+adminDescription: ms-Exch-Schema-Version-Adc
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSchemaVersionAdc
+name: ms-Exch-Schema-Version-Adc
+schemaIDGUID: 60735c93-c60e-405e-b5ea-cb31f68ad548
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Schema-Version-Pt	   
+#
+dn: CN=ms-Exch-Schema-Version-Pt,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Schema-Version-Pt
+distinguishedName: CN=ms-Exch-Schema-Version-Pt,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.97
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 6870
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Schema-Version-Pt
+adminDescription: ms-Exch-Schema-Version-Pt
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSchemaVersionPt
+name: ms-Exch-Schema-Version-Pt
+schemaIDGUID: 5f8198d5-e7c9-4560-b166-08dc7cfc17c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Scope-Mask		   
+# Defines the networks that will accept and send client connections.
+#
+dn: CN=ms-Exch-Scope-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Scope-Mask
+distinguishedName: CN=ms-Exch-Scope-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9014
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Scope-Mask
+adminDescription: ms-Exch-Scope-Mask
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchScopeMask
+name: ms-Exch-Scope-Mask
+schemaIDGUID: 20fb6b92-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Search-Base  
+#
+dn: CN=ms-Exch-Search-Base,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Search-Base
+distinguishedName: CN=ms-Exch-Search-Base,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.91
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Search-Base
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Search-Base
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchSearchBase
+name: ms-Exch-Search-Base
+schemaIDGUID: 1884a3fe-efcb-47b0-bbd4-a91ef8cd4cb4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Search-Scope 
+#
+dn: CN=ms-Exch-Search-Scope,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Search-Scope
+distinguishedName: CN=ms-Exch-Search-Scope,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.92
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Search-Scope
+adminDescription: ms-Exch-Search-Scope
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSearchScope
+name: ms-Exch-Search-Scope
+schemaIDGUID: 05ed1e50-31c8-4ed2-b01e-732dbf6dd344
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Secure-Bindings  
+# The IP port binding for non-secure connections.
+#
+dn: CN=ms-Exch-Secure-Bindings,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Secure-Bindings
+distinguishedName: CN=ms-Exch-Secure-Bindings,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2002
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 512
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Secure-Bindings
+adminDescription: ms-Exch-Secure-Bindings
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSecureBindings
+name: ms-Exch-Secure-Bindings
+schemaIDGUID: 216ddc72-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Security-Password	
+# Password for outbound security.
+#
+dn: CN=ms-Exch-Security-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Security-Password
+distinguishedName: CN=ms-Exch-Security-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5052
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Security-Password
+adminDescription: ms-Exch-Security-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchSecurityPassword
+name: ms-Exch-Security-Password
+schemaIDGUID: b8d47e4e-4b78-11d3-aa75-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Security-Policy	
+#
+dn: CN=ms-Exch-Security-Policy,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Security-Policy
+distinguishedName: CN=ms-Exch-Security-Policy,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.589
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 32767
+mAPIID: 35911
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Security-Policy
+adminDescription: ms-Exch-Security-Policy
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: securityPolicy
+name: ms-Exch-Security-Policy
+schemaIDGUID: 1677587b-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Security-Protocol	
+#
+dn: CN=ms-Exch-Security-Protocol,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Security-Protocol
+distinguishedName: CN=ms-Exch-Security-Protocol,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.82
+attributeSyntax: 2.5.5.10
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 32823
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Security-Protocol
+adminDescription: ms-Exch-Security-Protocol
+oMSyntax: 4
+searchFlags: 16
+lDAPDisplayName: securityProtocol
+name: ms-Exch-Security-Protocol
+schemaIDGUID: bf967a30-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Send-EMail-Message	
+#
+dn: CN=ms-Exch-Send-EMail-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Send-EMail-Message
+distinguishedName: CN=ms-Exch-Send-EMail-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.566
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35889
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Send-EMail-Message
+adminDescription: ms-Exch-Send-EMail-Message
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: sendEMailMessage
+name: ms-Exch-Send-EMail-Message
+schemaIDGUID: a8df746e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Send-TNEF		
+# Determines whether or not Exchange Rich Text is sent to the domain
+# specified in the domain content configuration object.
+#
+dn: CN=ms-Exch-Send-TNEF,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Send-TNEF
+distinguishedName: CN=ms-Exch-Send-TNEF,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.492
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33169
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Send-TNEF
+adminDescription: ms-Exch-Send-TNEF
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: sendTNEF
+name: ms-Exch-Send-TNEF
+schemaIDGUID: a8df746f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Always-Create-As   
+# How X.500 objects are synchronized to this directory.
+#
+dn: CN=ms-Exch-Server1-Always-Create-As,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Always-Create-As
+distinguishedName: CN=ms-Exch-Server1-Always-Create-As,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.27
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Always-Create-As
+adminDescription: ms-Exch-Server1-Always-Create-As
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer1AlwaysCreateAs
+name: ms-Exch-Server1-Always-Create-As
+schemaIDGUID: 222efaec-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Authentication-Credentials	
+# The user name to use to log on to the server for this directory.
+#
+dn: CN=ms-Exch-Server1-Authentication-Credentials,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Authentication-Credentials
+distinguishedName: CN=ms-Exch-Server1-Authentication-Credentials,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Authentication-Credentials
+adminDescription: ms-Exch-Server1-Authentication-Credentials
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1AuthenticationCredentials
+name: ms-Exch-Server1-Authentication-Credentials
+schemaIDGUID: 225ea9f4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Authentication-Password     
+# The password for the credentials specified for this directory.
+#
+dn: CN=ms-Exch-Server1-Authentication-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Authentication-Password
+distinguishedName: CN=ms-Exch-Server1-Authentication-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Authentication-Password
+adminDescription: ms-Exch-Server1-Authentication-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchServer1AuthenticationPassword
+name: ms-Exch-Server1-Authentication-Password
+schemaIDGUID: 228bf6a2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Server1-Authentication-Type  
+# The type of authentication to the server for this directory.
+#
+dn: CN=ms-Exch-Server1-Authentication-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Authentication-Type
+distinguishedName: CN=ms-Exch-Server1-Authentication-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.7
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 5
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Authentication-Type
+adminDescription: ms-Exch-Server1-Authentication-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer1AuthenticationType
+name: ms-Exch-Server1-Authentication-Type
+schemaIDGUID: 22b94350-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Deletion-Option    
+# A flag used to determine how deletions are synchronized into this directory.
+#
+dn: CN=ms-Exch-Server1-Deletion-Option,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Deletion-Option
+distinguishedName: CN=ms-Exch-Server1-Deletion-Option,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.21
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Deletion-Option
+adminDescription: ms-Exch-Server1-Deletion-Option
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer1DeletionOption
+name: ms-Exch-Server1-Deletion-Option
+schemaIDGUID: 22edb70c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Export-Containers		
+# The DN of the default container to search for objects to synchronize.
+#
+dn: CN=ms-Exch-Server1-Export-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Export-Containers
+distinguishedName: CN=ms-Exch-Server1-Export-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.13
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Export-Containers
+adminDescription: ms-Exch-Server1-Export-Containers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1ExportContainers
+name: ms-Exch-Server1-Export-Containers
+schemaIDGUID: 231b03ba-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Flags	
+# Flags used for transitive replication work.
+#
+dn: CN=ms-Exch-Server1-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Flags
+distinguishedName: CN=ms-Exch-Server1-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.61
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Flags
+adminDescription: ms-Exch-Server1-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer1Flags
+name: ms-Exch-Server1-Flags
+schemaIDGUID: 234d151c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Highest-USN 
+# The highwater mark update sequence number (USN) from the last
+# successful synchronization from this directory.
+#
+dn: CN=ms-Exch-Server1-Highest-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Highest-USN
+distinguishedName: CN=ms-Exch-Server1-Highest-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.29
+attributeSyntax: 2.5.5.16
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Highest-USN
+adminDescription: ms-Exch-Server1-Highest-USN
+oMSyntax: 65
+searchFlags: 0
+lDAPDisplayName: msExchServer1HighestUSN
+name: ms-Exch-Server1-Highest-USN
+schemaIDGUID: 237f267e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Highest-USN-Vector	
+# Stores the vectors of update sequence numbers (USNs) and servers for
+# a given naming context (NC).
+#
+dn: CN=ms-Exch-Server1-Highest-USN-Vector,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Highest-USN-Vector
+distinguishedName: CN=ms-Exch-Server1-Highest-USN-Vector,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.86
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Highest-USN-Vector
+adminDescription: ms-Exch-Server1-Highest-USN-Vector
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1HighestUSNVector
+name: ms-Exch-Server1-Highest-USN-Vector
+schemaIDGUID: 7fb58cd4-2a6e-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Import-Container    
+# The DN of the default container to write synchronized objects to.
+#
+dn: CN=ms-Exch-Server1-Import-Container,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Import-Container
+distinguishedName: CN=ms-Exch-Server1-Import-Container,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Import-Container
+adminDescription: ms-Exch-Server1-Import-Container
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1ImportContainer
+name: ms-Exch-Server1-Import-Container
+schemaIDGUID: 23aed586-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Is-Bridgehead	 
+# A flag to determine whether non-mailbox associated objects are
+# replicated over this particular connection agreement.
+#
+dn: CN=ms-Exch-Server1-Is-Bridgehead,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Is-Bridgehead
+distinguishedName: CN=ms-Exch-Server1-Is-Bridgehead,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.77
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Is-Bridgehead
+adminDescription: ms-Exch-Server1-Is-Bridgehead
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchServer1IsBridgehead
+name: ms-Exch-Server1-Is-Bridgehead
+schemaIDGUID: 90b71b6a-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Last-Update-Time	   
+# The time of the most recent update from the last successful
+# synchronization from this directory.
+#
+dn: CN=ms-Exch-Server1-Last-Update-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Last-Update-Time
+distinguishedName: CN=ms-Exch-Server1-Last-Update-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.31
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Last-Update-Time
+adminDescription: ms-Exch-Server1-Last-Update-Time
+oMSyntax: 24
+searchFlags: 0
+lDAPDisplayName: msExchServer1LastUpdateTime
+name: ms-Exch-Server1-Last-Update-Time
+schemaIDGUID: 23e34942-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Server1-Network-Address   
+# The network address of the server participating in this connection
+# agreement.
+#
+dn: CN=ms-Exch-Server1-Network-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Network-Address
+distinguishedName: CN=ms-Exch-Server1-Network-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.3
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Network-Address
+adminDescription: ms-Exch-Server1-Network-Address
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1NetworkAddress
+name: ms-Exch-Server1-Network-Address
+schemaIDGUID: 2412f84a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-NT-Account-Domain	
+# Domain in which Active Directory accounts should be created.
+#
+dn: CN=ms-Exch-Server1-NT-Account-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-NT-Account-Domain
+distinguishedName: CN=ms-Exch-Server1-NT-Account-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-NT-Account-Domain
+adminDescription: ms-Exch-Server1-NT-Account-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1NTAccountDomain
+name: ms-Exch-Server1-NT-Account-Domain
+schemaIDGUID: 2449ce60-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Object-Match	  
+# Contains the matching rules for this server.
+#
+dn: CN=ms-Exch-Server1-Object-Match,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Object-Match
+distinguishedName: CN=ms-Exch-Server1-Object-Match,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.54
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Object-Match
+adminDescription: ms-Exch-Server1-Object-Match
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1ObjectMatch
+name: ms-Exch-Server1-Object-Match
+schemaIDGUID: 247bdfc2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Page-Size  
+# The page size to request when searching this directory.
+#
+dn: CN=ms-Exch-Server1-Page-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Page-Size
+distinguishedName: CN=ms-Exch-Server1-Page-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.25
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Page-Size
+adminDescription: ms-Exch-Server1-Page-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer1PageSize
+name: ms-Exch-Server1-Page-Size
+schemaIDGUID: 24b0537e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-Port		
+# The LDAP port of the server for this directory.
+#
+dn: CN=ms-Exch-Server1-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Port
+distinguishedName: CN=ms-Exch-Server1-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Port
+adminDescription: ms-Exch-Server1-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer1Port
+name: ms-Exch-Server1-Port
+schemaIDGUID: 24e264e0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Schema-Map 
+# The schema map to use when mapping from Active Directory to the
+# Exchange Directory Service (DS).
+#
+dn: CN=ms-Exch-Server1-Schema-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Schema-Map
+distinguishedName: CN=ms-Exch-Server1-Schema-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Schema-Map
+adminDescription: ms-Exch-Server1-Schema-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1SchemaMap
+name: ms-Exch-Server1-Schema-Map
+schemaIDGUID: 25193af6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server1-Search-Filter	
+# The search filter to use when searching this directory.
+#
+dn: CN=ms-Exch-Server1-Search-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Search-Filter
+distinguishedName: CN=ms-Exch-Server1-Search-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.19
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Search-Filter
+adminDescription: ms-Exch-Server1-Search-Filter
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer1SearchFilter
+name: ms-Exch-Server1-Search-Filter
+schemaIDGUID: 254daeb2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server1-SSL-Port	
+# The port to connect to for Secure Sockets Layer (SSL) connections.
+#
+dn: CN=ms-Exch-Server1-SSL-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-SSL-Port
+distinguishedName: CN=ms-Exch-Server1-SSL-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.39
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-SSL-Port
+adminDescription: ms-Exch-Server1-SSL-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer1SSLPort
+name: ms-Exch-Server1-SSL-Port
+schemaIDGUID: 258484c8-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Server1-Type	  
+# Identifies the type of server being connected to.
+#
+dn: CN=ms-Exch-Server1-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server1-Type
+distinguishedName: CN=ms-Exch-Server1-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.23
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 5
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server1-Type
+adminDescription: ms-Exch-Server1-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer1Type
+name: ms-Exch-Server1-Type
+schemaIDGUID: 25bb5ade-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Always-Create-As    
+# How X.500 objects are synchronized to this directory.
+#
+dn: CN=ms-Exch-Server2-Always-Create-As,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Always-Create-As
+distinguishedName: CN=ms-Exch-Server2-Always-Create-As,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.28
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Always-Create-As
+adminDescription: ms-Exch-Server2-Always-Create-As
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer2AlwaysCreateAs
+name: ms-Exch-Server2-Always-Create-As
+schemaIDGUID: 25f95802-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Authentication-Credentials	
+# The user name to use to log on to the server for this directory.
+dn: CN=ms-Exch-Server2-Authentication-Credentials,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Authentication-Credentials
+distinguishedName: CN=ms-Exch-Server2-Authentication-Credentials,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.10
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Authentication-Credentials
+adminDescription: ms-Exch-Server2-Authentication-Credentials
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2AuthenticationCredentials
+name: ms-Exch-Server2-Authentication-Credentials
+schemaIDGUID: 26329072-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Authentication-Password     
+# The password for the credentials specified for this directory.
+dn: CN=ms-Exch-Server2-Authentication-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Authentication-Password
+distinguishedName: CN=ms-Exch-Server2-Authentication-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Authentication-Password
+adminDescription: ms-Exch-Server2-Authentication-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchServer2AuthenticationPassword
+name: ms-Exch-Server2-Authentication-Password
+schemaIDGUID: 266bc8e2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Authentication-Type  
+# The type of authentication to the server for this directory.
+#
+dn: CN=ms-Exch-Server2-Authentication-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Authentication-Type
+distinguishedName: CN=ms-Exch-Server2-Authentication-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.8
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 5
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Authentication-Type
+adminDescription: ms-Exch-Server2-Authentication-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer2AuthenticationType
+name: ms-Exch-Server2-Authentication-Type
+schemaIDGUID: 26a50152-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Deletion-Option    
+# A flag used to determine how deletions are synchronized into this
+# directory.
+#
+dn: CN=ms-Exch-Server2-Deletion-Option,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Deletion-Option
+distinguishedName: CN=ms-Exch-Server2-Deletion-Option,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.22
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Deletion-Option
+adminDescription: ms-Exch-Server2-Deletion-Option
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer2DeletionOption
+name: ms-Exch-Server2-Deletion-Option
+schemaIDGUID: 26e09c1c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Server2-Export-Containers		
+# The DN of the default container to search for objects to
+# synchronize.
+#
+dn: CN=ms-Exch-Server2-Export-Containers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Export-Containers
+distinguishedName: CN=ms-Exch-Server2-Export-Containers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.14
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Export-Containers
+adminDescription: ms-Exch-Server2-Export-Containers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2ExportContainers
+name: ms-Exch-Server2-Export-Containers
+schemaIDGUID: 27cca4ea-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Flags	
+# Flags for transitive replication work.
+#
+dn: CN=ms-Exch-Server2-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Flags
+distinguishedName: CN=ms-Exch-Server2-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.62
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Flags
+adminDescription: ms-Exch-Server2-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer2Flags
+name: ms-Exch-Server2-Flags
+schemaIDGUID: 28083fb4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Highest-USN	
+# The highwater mark update sequence number (USN) from the last
+# successful synchronization from this directory.
+#
+dn: CN=ms-Exch-Server2-Highest-USN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Highest-USN
+distinguishedName: CN=ms-Exch-Server2-Highest-USN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.30
+attributeSyntax: 2.5.5.16
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Highest-USN
+adminDescription: ms-Exch-Server2-Highest-USN
+oMSyntax: 65
+searchFlags: 0
+lDAPDisplayName: msExchServer2HighestUSN
+name: ms-Exch-Server2-Highest-USN
+schemaIDGUID: 283a5116-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Highest-USN-Vector	
+# Stores the vectors of update sequence numbers (USNs) and servers for
+# a given naming context (NC).
+#
+dn: CN=ms-Exch-Server2-Highest-USN-Vector,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Highest-USN-Vector
+distinguishedName: CN=ms-Exch-Server2-Highest-USN-Vector,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.87
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Highest-USN-Vector
+adminDescription: ms-Exch-Server2-Highest-USN-Vector
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2HighestUSNVector
+name: ms-Exch-Server2-Highest-USN-Vector
+schemaIDGUID: 7fb58cda-2a6e-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Import-Container    
+# The DN of the default container to write syncronized objects to.
+#
+dn: CN=ms-Exch-Server2-Import-Container,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Import-Container
+distinguishedName: CN=ms-Exch-Server2-Import-Container,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.16
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Import-Container
+adminDescription: ms-Exch-Server2-Import-Container
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2ImportContainer
+name: ms-Exch-Server2-Import-Container
+schemaIDGUID: 286c6278-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Is-Bridgehead	 
+# A flag to determine whether non-mailbox associated objects are
+# replicated over this particular connection agreement.
+#
+dn: CN=ms-Exch-Server2-Is-Bridgehead,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Is-Bridgehead
+distinguishedName: CN=ms-Exch-Server2-Is-Bridgehead,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.78
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Is-Bridgehead
+adminDescription: ms-Exch-Server2-Is-Bridgehead
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchServer2IsBridgehead
+name: ms-Exch-Server2-Is-Bridgehead
+schemaIDGUID: 90d619fc-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Last-Update-Time	   
+# The time of the most recent update from last successful
+# syncronization from this directory.
+#
+dn: CN=ms-Exch-Server2-Last-Update-Time,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Last-Update-Time
+distinguishedName: CN=ms-Exch-Server2-Last-Update-Time,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.32
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Last-Update-Time
+adminDescription: ms-Exch-Server2-Last-Update-Time
+oMSyntax: 24
+searchFlags: 0
+lDAPDisplayName: msExchServer2LastUpdateTime
+name: ms-Exch-Server2-Last-Update-Time
+schemaIDGUID: 28a3388e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Network-Address    
+# The network address of the server participating in the connection
+# agreement.
+#
+dn: CN=ms-Exch-Server2-Network-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Network-Address
+distinguishedName: CN=ms-Exch-Server2-Network-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.4
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Network-Address
+adminDescription: ms-Exch-Server2-Network-Address
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2NetworkAddress
+name: ms-Exch-Server2-Network-Address
+schemaIDGUID: 28d549f0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Server2-NT-Account-Domain	
+# The domain in which Active Directory accounts should be created.
+#
+dn: CN=ms-Exch-Server2-NT-Account-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-NT-Account-Domain
+distinguishedName: CN=ms-Exch-Server2-NT-Account-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.51
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-NT-Account-Domain
+adminDescription: ms-Exch-Server2-NT-Account-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2NTAccountDomain
+name: ms-Exch-Server2-NT-Account-Domain
+schemaIDGUID: 2909bdac-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Object-Match	      
+# Contains the matching rules for this server.
+#
+dn: CN=ms-Exch-Server2-Object-Match,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Object-Match
+distinguishedName: CN=ms-Exch-Server2-Object-Match,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.55
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Object-Match
+adminDescription: ms-Exch-Server2-Object-Match
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2ObjectMatch
+name: ms-Exch-Server2-Object-Match
+schemaIDGUID: 293e3168-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Page-Size  
+# The page size to request when searching this directory.
+#
+dn: CN=ms-Exch-Server2-Page-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Page-Size
+distinguishedName: CN=ms-Exch-Server2-Page-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.26
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Page-Size
+adminDescription: ms-Exch-Server2-Page-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer2PageSize
+name: ms-Exch-Server2-Page-Size
+schemaIDGUID: 296de070-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Port		
+# The LDAP port of the server for this directory.
+#
+dn: CN=ms-Exch-Server2-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Port
+distinguishedName: CN=ms-Exch-Server2-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.6
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Port
+adminDescription: ms-Exch-Server2-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer2Port
+name: ms-Exch-Server2-Port
+schemaIDGUID: 29a4b686-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server2-Schema-Map 
+# The schema map to use when mapping from the Exchange Directory
+# Service (DS) to Active Directory.
+#
+dn: CN=ms-Exch-Server2-Schema-Map,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Schema-Map
+distinguishedName: CN=ms-Exch-Server2-Schema-Map,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.18
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Schema-Map
+adminDescription: ms-Exch-Server2-Schema-Map
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2SchemaMap
+name: ms-Exch-Server2-Schema-Map
+schemaIDGUID: 29d6c7e8-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Search-Filter	
+# The search filter to use when searching this directory.
+#
+dn: CN=ms-Exch-Server2-Search-Filter,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Search-Filter
+distinguishedName: CN=ms-Exch-Server2-Search-Filter,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.20
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Search-Filter
+adminDescription: ms-Exch-Server2-Search-Filter
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServer2SearchFilter
+name: ms-Exch-Server2-Search-Filter
+schemaIDGUID: 2a0b3ba4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-SSL-Port	
+# The port to connect to for SSL connections.
+#
+dn: CN=ms-Exch-Server2-SSL-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-SSL-Port
+distinguishedName: CN=ms-Exch-Server2-SSL-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.40
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 65535
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-SSL-Port
+adminDescription: ms-Exch-Server2-SSL-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServer2SSLPort
+name: ms-Exch-Server2-SSL-Port
+schemaIDGUID: 2a3faf60-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server2-Type 
+# Identifies the type of server being connected to.
+#
+dn: CN=ms-Exch-Server2-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server2-Type
+distinguishedName: CN=ms-Exch-Server2-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.24
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 5
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server2-Type
+adminDescription: ms-Exch-Server2-Type
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchServer2Type
+name: ms-Exch-Server2-Type
+schemaIDGUID: 2a74231c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Auto-Start 
+# Starts the service when the operating system is booted.
+dn: CN=ms-Exch-Server-Auto-Start,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Auto-Start
+distinguishedName: CN=ms-Exch-Server-Auto-Start,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2007
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Auto-Start
+adminDescription: ms-Exch-Server-Auto-Start
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchServerAutoStart
+name: ms-Exch-Server-Auto-Start
+schemaIDGUID: 21cf9cdc-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server-Bindings     
+# The IP port binding for SSL connections.
+#
+dn: CN=ms-Exch-Server-Bindings,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Bindings
+distinguishedName: CN=ms-Exch-Server-Bindings,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.2001
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 512
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Bindings
+adminDescription: ms-Exch-Server-Bindings
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServerBindings
+name: ms-Exch-Server-Bindings
+schemaIDGUID: 2201ae3e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Bindings-Filtering	
+#
+dn: CN=ms-Exch-Server-Bindings-Filtering,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Bindings-Filtering
+distinguishedName: CN=ms-Exch-Server-Bindings-Filtering,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5072
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Bindings-Filtering
+adminDescription: ms-Exch-Server-Bindings-Filtering
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServerBindingsFiltering
+name: ms-Exch-Server-Bindings-Filtering
+schemaIDGUID: 61aedffa-34b4-4170-8bab-b8794e1cb4f4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Bindings-Turflist	
+#
+dn: CN=ms-Exch-Server-Bindings-Turflist,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Bindings-Turflist
+distinguishedName: CN=ms-Exch-Server-Bindings-Turflist,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12533
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Bindings-Turflist
+adminDescription: ms-Exch-Server-Bindings-Turflist
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServerBindingsTurflist
+name: ms-Exch-Server-Bindings-Turflist
+schemaIDGUID: 0b836d98-3b20-11d3-aa6f-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server-Global-Groups	   
+#
+dn: CN=ms-Exch-Server-Global-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Global-Groups
+distinguishedName: CN=ms-Exch-Server-Global-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50083
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Global-Groups
+adminDescription: ms-Exch-Server-Global-Groups
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchServerGlobalGroups
+name: ms-Exch-Server-Global-Groups
+schemaIDGUID: 419f00f6-fb22-4ea9-8113-ed928767baa5
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Groups		   
+# A link to all Exchange server groups within the organization.
+#
+dn: CN=ms-Exch-Server-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Groups
+distinguishedName: CN=ms-Exch-Server-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50055
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Groups
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Server-Groups
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchServerGroups
+name: ms-Exch-Server-Groups
+schemaIDGUID: 5fd75fb9-3819-4d25-b18e-7bce391d4767
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Local-Groups	    
+# Contains the domain local groups for each prepared domain.
+#
+dn: CN=ms-Exch-Server-Local-Groups,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Local-Groups
+distinguishedName: CN=ms-Exch-Server-Local-Groups,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50082
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Local-Groups
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Server-Local-Groups
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchServerLocalGroups
+name: ms-Exch-Server-Local-Groups
+schemaIDGUID: 924a0b14-ea4f-4627-abd1-adbc801c4b0b
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Server-Public-Key  
+#
+dn: CN=ms-Exch-Server-Public-Key,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Public-Key
+distinguishedName: CN=ms-Exch-Server-Public-Key,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50063
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Public-Key
+adminDescription: ms-Exch-Server-Public-Key
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchServerPublicKey
+name: ms-Exch-Server-Public-Key
+schemaIDGUID: b83df2df-c304-4563-90fd-d38ec81b04cb
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Server-Role	  
+# Determines if this server is a front-end or back-end server.
+dn: CN=ms-Exch-Server-Role,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Server-Role
+distinguishedName: CN=ms-Exch-Server-Role,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Server-Role
+adminDescription: ms-Exch-Server-Role
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchServerRole
+name: ms-Exch-Server-Role
+schemaIDGUID: 8c8fc29e-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Service-Action-First	 
+#
+dn: CN=ms-Exch-Service-Action-First,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Service-Action-First
+distinguishedName: CN=ms-Exch-Service-Action-First,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.161
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33073
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Service-Action-First
+adminDescription: ms-Exch-Service-Action-First
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: serviceActionFirst
+name: ms-Exch-Service-Action-First
+schemaIDGUID: a8df7470-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Service-Action-Other	 
+#
+dn: CN=ms-Exch-Service-Action-Other,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Service-Action-Other
+distinguishedName: CN=ms-Exch-Service-Action-Other,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.59
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33074
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Service-Action-Other
+adminDescription: ms-Exch-Service-Action-Other
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: serviceActionOther
+name: ms-Exch-Service-Action-Other
+schemaIDGUID: a8df7471-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Service-Action-Second	 
+#
+dn: CN=ms-Exch-Service-Action-Second,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Service-Action-Second
+distinguishedName: CN=ms-Exch-Service-Action-Second,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.60
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+mAPIID: 33075
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Service-Action-Second
+adminDescription: ms-Exch-Service-Action-Second
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: serviceActionSecond
+name: ms-Exch-Service-Action-Second
+schemaIDGUID: a8df7472-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Service-Restart-Delay	 
+#
+dn: CN=ms-Exch-Service-Restart-Delay,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Service-Restart-Delay
+distinguishedName: CN=ms-Exch-Service-Restart-Delay,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.162
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33076
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Service-Restart-Delay
+adminDescription: ms-Exch-Service-Restart-Delay
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: serviceRestartDelay
+name: ms-Exch-Service-Restart-Delay
+schemaIDGUID: a8df7473-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Service-Restart-Message    
+#
+dn: CN=ms-Exch-Service-Restart-Message,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Service-Restart-Message
+distinguishedName: CN=ms-Exch-Service-Restart-Message,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.58
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 120
+mAPIID: 33077
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Service-Restart-Message
+adminDescription: ms-Exch-Service-Restart-Message
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: serviceRestartMessage
+name: ms-Exch-Service-Restart-Message
+schemaIDGUID: a8df7474-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Session-Disconnect-Timer   
+#
+dn: CN=ms-Exch-Session-Disconnect-Timer,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Session-Disconnect-Timer
+distinguishedName: CN=ms-Exch-Session-Disconnect-Timer,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.154
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33078
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Session-Disconnect-Timer
+adminDescription: ms-Exch-Session-Disconnect-Timer
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: sessionDisconnectTimer
+name: ms-Exch-Session-Disconnect-Timer
+schemaIDGUID: a8df7475-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Site-Folder-GUID	     
+# Contains a random unused GUID which is used by the store when
+# creating the public folder for this OAB.
+#
+dn: CN=ms-Exch-Site-Folder-GUID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Site-Folder-GUID
+distinguishedName: CN=ms-Exch-Site-Folder-GUID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.456
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 33126
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Folder-GUID
+adminDescription: ms-Exch-Site-Folder-GUID
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: siteFolderGUID
+name: ms-Exch-Site-Folder-GUID
+schemaIDGUID: a8df7477-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Site-Folder-Server   
+#
+dn: CN=ms-Exch-Site-Folder-Server,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Site-Folder-Server
+distinguishedName: CN=ms-Exch-Site-Folder-Server,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.457
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+mAPIID: 33127
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Folder-Server
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Site-Folder-Server
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: siteFolderServer
+name: ms-Exch-Site-Folder-Server
+schemaIDGUID: a8df7478-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Site-Proxy-Space     
+#
+dn: CN=ms-Exch-Site-Proxy-Space,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Site-Proxy-Space
+distinguishedName: CN=ms-Exch-Site-Proxy-Space,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.385
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 1123
+mAPIID: 33080
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Site-Proxy-Space
+adminDescription: ms-Exch-Site-Proxy-Space
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: siteProxySpace
+name: ms-Exch-Site-Proxy-Space
+schemaIDGUID: a8df7479-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SLV-File	       
+# The database file location for this store.
+dn: CN=ms-Exch-SLV-File,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SLV-File
+distinguishedName: CN=ms-Exch-SLV-File,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11036
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SLV-File
+adminDescription: ms-Exch-SLV-File
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchSLVFile
+name: ms-Exch-SLV-File
+schemaIDGUID: 2aaaf932-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-SMIME-Alg-List-NA 
+# The list of supported algorithms in North America by Microsoft
+# Outlook clients. This list should never be modified.
+#
+dn: CN=ms-Exch-SMIME-Alg-List-NA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMIME-Alg-List-NA
+distinguishedName: CN=ms-Exch-SMIME-Alg-List-NA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.568
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 35891
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMIME-Alg-List-NA
+adminDescription: ms-Exch-SMIME-Alg-List-NA
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: sMIMEAlgListNA
+name: ms-Exch-SMIME-Alg-List-NA
+schemaIDGUID: a8df747a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-SMIME-Alg-List-Other	  
+# The list of non-North America algorithms supported by Outlook.
+#
+dn: CN=ms-Exch-SMIME-Alg-List-Other,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMIME-Alg-List-Other
+distinguishedName: CN=ms-Exch-SMIME-Alg-List-Other,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.569
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 35892
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMIME-Alg-List-Other
+adminDescription: ms-Exch-SMIME-Alg-List-Other
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: sMIMEAlgListOther
+name: ms-Exch-SMIME-Alg-List-Other
+schemaIDGUID: a8df747b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-SMIME-Alg-Selected-NA	 
+# The currently-selected algorithm for North America Outlook users.
+#
+dn: CN=ms-Exch-SMIME-Alg-Selected-NA,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMIME-Alg-Selected-NA
+distinguishedName: CN=ms-Exch-SMIME-Alg-Selected-NA,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.570
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 35893
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMIME-Alg-Selected-NA
+adminDescription: ms-Exch-SMIME-Alg-Selected-NA
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: sMIMEAlgSelectedNA
+name: ms-Exch-SMIME-Alg-Selected-NA
+schemaIDGUID: a8df747c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-SMIME-Alg-Selected-Other 
+# The selected algorithm for non-North America Outlook users.
+#
+dn: CN=ms-Exch-SMIME-Alg-Selected-Other,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMIME-Alg-Selected-Other
+distinguishedName: CN=ms-Exch-SMIME-Alg-Selected-Other,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.571
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 35894
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMIME-Alg-Selected-Other
+adminDescription: ms-Exch-SMIME-Alg-Selected-Other
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: sMIMEAlgSelectedOther
+name: ms-Exch-SMIME-Alg-Selected-Other
+schemaIDGUID: a8df747d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Authorized-TRN-Accounts	     
+# The list of all accounts that are authorized to use TRN.
+#
+dn: CN=ms-Exch-Smtp-Authorized-TRN-Accounts,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Authorized-TRN-Accounts
+distinguishedName: CN=ms-Exch-Smtp-Authorized-TRN-Accounts,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5047
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Authorized-TRN-Accounts
+adminDescription: ms-Exch-Smtp-Authorized-TRN-Accounts
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpAuthorizedTRNAccounts
+name: ms-Exch-Smtp-Authorized-TRN-Accounts
+schemaIDGUID: 2b164304-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Bad-Mail-Directory    
+# Location where bad mail messages are stored.
+#
+dn: CN=ms-Exch-Smtp-Bad-Mail-Directory,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Bad-Mail-Directory
+distinguishedName: CN=ms-Exch-Smtp-Bad-Mail-Directory,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5025
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Bad-Mail-Directory
+adminDescription: ms-Exch-Smtp-Bad-Mail-Directory
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpBadMailDirectory
+name: ms-Exch-Smtp-Bad-Mail-Directory
+schemaIDGUID: 2b5904dc-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Connection-Rules-Priority	
+#
+dn: CN=ms-Exch-Smtp-Connection-Rules-Priority,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Rules-Priority
+distinguishedName: CN=ms-Exch-Smtp-Connection-Rules-Priority,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5064
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Rules-Priority
+adminDescription: ms-Exch-Smtp-Connection-Rules-Priority
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionRulesPriority
+name: ms-Exch-Smtp-Connection-Rules-Priority
+schemaIDGUID: 86c24f8c-259b-4f19-88b9-9c9445936121
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-Display	
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-Display,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-Display
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Display,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5065
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Display
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-Display
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionTurfListDisplay
+name: ms-Exch-Smtp-Connection-Turf-List-Display
+schemaIDGUID: 73fb04ac-b2d4-4a4d-8520-757dd3c9261a
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-DNS		
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-DNS,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-DNS
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-DNS,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5067
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-DNS
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-DNS
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionTurfListDNS
+name: ms-Exch-Smtp-Connection-Turf-List-DNS
+schemaIDGUID: 3fee7de6-d3e5-43cb-8459-f7a072ae3789
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-Mask	
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-Mask
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5069
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Mask
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-Mask
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionTurfListMask
+name: ms-Exch-Smtp-Connection-Turf-List-Mask
+schemaIDGUID: bc0241af-9d38-4c40-842e-51d802506de5
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-Options	
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-Options
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5066
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Options
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionTurfListOptions
+name: ms-Exch-Smtp-Connection-Turf-List-Options
+schemaIDGUID: 5ae62360-1105-4d8b-8a1e-a2c793b4d57d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Connection-Turf-List-Response	
+#
+dn: CN=ms-Exch-Smtp-Connection-Turf-List-Response,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Turf-List-Response
+distinguishedName: CN=ms-Exch-Smtp-Connection-Turf-List-Response,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5068
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Turf-List-Response
+adminDescription: ms-Exch-Smtp-Connection-Turf-List-Response
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionTurfListResponse
+name: ms-Exch-Smtp-Connection-Turf-List-Response
+schemaIDGUID: eeddd98f-da01-4ecb-a65e-5f016f1d8032
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Connection-Whitelist		
+#
+dn: CN=ms-Exch-Smtp-Connection-Whitelist,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Connection-Whitelist
+distinguishedName: CN=ms-Exch-Smtp-Connection-Whitelist,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5063
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Connection-Whitelist
+adminDescription: ms-Exch-Smtp-Connection-Whitelist
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpConnectionWhitelist
+name: ms-Exch-Smtp-Connection-Whitelist
+schemaIDGUID: 87cf463a-561e-45ce-a0ba-6d528f111d23
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Domain-String			
+# The drop directory of the domain or route domain.
+#
+dn: CN=ms-Exch-Smtp-Domain-String,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Domain-String
+distinguishedName: CN=ms-Exch-Smtp-Domain-String,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5033
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Domain-String
+adminDescription: ms-Exch-Smtp-Domain-String
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDomainString
+name: ms-Exch-Smtp-Domain-String
+schemaIDGUID: 2bd03a70-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Do-Masquerade	  
+# If set, use the Masquerade domain.
+#
+dn: CN=ms-Exch-Smtp-Do-Masquerade,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Do-Masquerade
+distinguishedName: CN=ms-Exch-Smtp-Do-Masquerade,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5022
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Do-Masquerade
+adminDescription: ms-Exch-Smtp-Do-Masquerade
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDoMasquerade
+name: ms-Exch-Smtp-Do-Masquerade
+schemaIDGUID: 2b949fa6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Drop-Directory	
+# The directory where mail messages are being dropped.
+#
+dn: CN=ms-Exch-Smtp-Drop-Directory,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Drop-Directory
+distinguishedName: CN=ms-Exch-Smtp-Drop-Directory,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5032
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Drop-Directory
+adminDescription: ms-Exch-Smtp-Drop-Directory
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDropDirectory
+name: ms-Exch-Smtp-Drop-Directory
+schemaIDGUID: 2c260f18-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ds-Data-Directory    
+# The data directory for DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ds-Data-Directory,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Data-Directory
+distinguishedName: CN=ms-Exch-Smtp-Ds-Data-Directory,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5036
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Data-Directory
+adminDescription: ms-Exch-Smtp-Ds-Data-Directory
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsDataDirectory
+name: ms-Exch-Smtp-Ds-Data-Directory
+schemaIDGUID: 2c6d95a4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ds-Default-Mail-Root	
+# The default mail root for DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ds-Default-Mail-Root,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Default-Mail-Root
+distinguishedName: CN=ms-Exch-Smtp-Ds-Default-Mail-Root,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5037
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Default-Mail-Root
+adminDescription: ms-Exch-Smtp-Ds-Default-Mail-Root
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsDefaultMailRoot
+name: ms-Exch-Smtp-Ds-Default-Mail-Root
+schemaIDGUID: 2cadf522-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Ds-Domain	
+# The default mail root for DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ds-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Domain
+distinguishedName: CN=ms-Exch-Smtp-Ds-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5038
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Domain
+adminDescription: ms-Exch-Smtp-Ds-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsDomain
+name: ms-Exch-Smtp-Ds-Domain
+schemaIDGUID: 2ce72d92-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ds-Flags	
+#
+dn: CN=ms-Exch-Smtp-Ds-Flags,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Flags
+distinguishedName: CN=ms-Exch-Smtp-Ds-Flags,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5049
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Flags
+adminDescription: ms-Exch-Smtp-Ds-Flags
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsFlags
+name: ms-Exch-Smtp-Ds-Flags
+schemaIDGUID: 2d206602-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ds-Host 
+# The host to connect in DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ds-Host,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Host
+distinguishedName: CN=ms-Exch-Smtp-Ds-Host,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5042
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Host
+adminDescription: ms-Exch-Smtp-Ds-Host
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsHost
+name: ms-Exch-Smtp-Ds-Host
+schemaIDGUID: 2d599e72-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ds-Port	
+# The port to use in DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ds-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ds-Port
+distinguishedName: CN=ms-Exch-Smtp-Ds-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5017
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ds-Port
+adminDescription: ms-Exch-Smtp-Ds-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpDsPort
+name: ms-Exch-Smtp-Ds-Port
+schemaIDGUID: 2d92d6e2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Enable-EXPN	
+#
+dn: CN=ms-Exch-Smtp-Enable-EXPN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Enable-EXPN
+distinguishedName: CN=ms-Exch-Smtp-Enable-EXPN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12537
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Enable-EXPN
+adminDescription: ms-Exch-Smtp-Enable-EXPN
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpEnableEXPN
+name: ms-Exch-Smtp-Enable-EXPN
+schemaIDGUID: e24d7a86-439d-11d3-aa72-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Enable-Ldap-Routing 
+# Configures the directory that this resource uses to route mail.
+#
+dn: CN=ms-Exch-Smtp-Enable-Ldap-Routing,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Enable-Ldap-Routing
+distinguishedName: CN=ms-Exch-Smtp-Enable-Ldap-Routing,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5019
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Enable-Ldap-Routing
+adminDescription: ms-Exch-Smtp-Enable-Ldap-Routing
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpEnableLdapRouting
+name: ms-Exch-Smtp-Enable-Ldap-Routing
+schemaIDGUID: 2dce71ac-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Enable-VRFY 
+#
+dn: CN=ms-Exch-Smtp-Enable-VRFY,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Enable-VRFY
+distinguishedName: CN=ms-Exch-Smtp-Enable-VRFY,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12536
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Enable-VRFY
+adminDescription: ms-Exch-Smtp-Enable-VRFY
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpEnableVRFY
+name: ms-Exch-Smtp-Enable-VRFY
+schemaIDGUID: e24d7a80-439d-11d3-aa72-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-External-DNS-Servers	
+# Contains the IP addresses of DNS servers that should be used by this
+# SMTP virtual server.
+#
+dn: CN=ms-Exch-Smtp-External-DNS-Servers,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-External-DNS-Servers
+distinguishedName: CN=ms-Exch-Smtp-External-DNS-Servers,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5056
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-External-DNS-Servers
+adminDescription: ms-Exch-Smtp-External-DNS-Servers
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpExternalDNSServers
+name: ms-Exch-Smtp-External-DNS-Servers
+schemaIDGUID: a1826432-f85e-42b6-b55d-1249ed2f78a3
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Fully-Qualified-Domain-Name   
+# The Fully Qualified Domain Name for this virtual server.
+#
+dn: CN=ms-Exch-Smtp-Fully-Qualified-Domain-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Fully-Qualified-Domain-Name
+distinguishedName: CN=ms-Exch-Smtp-Fully-Qualified-Domain-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5029
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Fully-Qualified-Domain-Name
+adminDescription: ms-Exch-Smtp-Fully-Qualified-Domain-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpFullyQualifiedDomainName
+name: ms-Exch-Smtp-Fully-Qualified-Domain-Name
+schemaIDGUID: 2e0547c2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SMTP-Global-IP-Accept-List	 
+#
+dn: CN=ms-Exch-SMTP-Global-IP-Accept-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMTP-Global-IP-Accept-List
+distinguishedName: CN=ms-Exch-SMTP-Global-IP-Accept-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5073
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMTP-Global-IP-Accept-List
+adminDescription: ms-Exch-SMTP-Global-IP-Accept-List
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchSMTPGlobalIPAcceptList
+name: ms-Exch-SMTP-Global-IP-Accept-List
+schemaIDGUID: 752cd028-a935-40aa-8f8b-14aeb4433c93
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SMTP-Global-IP-Deny-List	 
+#
+dn: CN=ms-Exch-SMTP-Global-IP-Deny-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SMTP-Global-IP-Deny-List
+distinguishedName: CN=ms-Exch-SMTP-Global-IP-Deny-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5074
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SMTP-Global-IP-Deny-List
+adminDescription: ms-Exch-SMTP-Global-IP-Deny-List
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchSMTPGlobalIPDenyList
+name: ms-Exch-SMTP-Global-IP-Deny-List
+schemaIDGUID: 61e731dc-484d-4566-8aac-c54747f13cc4
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Inbound-Command-Support-Options	  
+# The TLF encryption flag used for basic authentication.
+#
+dn: CN=ms-Exch-Smtp-Inbound-Command-Support-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Inbound-Command-Support-Options
+distinguishedName: CN=ms-Exch-Smtp-Inbound-Command-Support-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5018
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Inbound-Command-Support-Options
+adminDescription: ms-Exch-Smtp-Inbound-Command-Support-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpInboundCommandSupportOptions
+name: ms-Exch-Smtp-Inbound-Command-Support-Options
+schemaIDGUID: 2e40e28c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Ldap-Account    
+# The LDAP account to use in DSAccess.
+dn: CN=ms-Exch-Smtp-Ldap-Account,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ldap-Account
+distinguishedName: CN=ms-Exch-Smtp-Ldap-Account,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5044
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ldap-Account
+adminDescription: ms-Exch-Smtp-Ldap-Account
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLdapAccount
+name: ms-Exch-Smtp-Ldap-Account
+schemaIDGUID: 2e7c7d56-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ldap-Bind-Type	
+# The bind type to use in DSAccess.
+dn: CN=ms-Exch-Smtp-Ldap-Bind-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ldap-Bind-Type
+distinguishedName: CN=ms-Exch-Smtp-Ldap-Bind-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5040
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ldap-Bind-Type
+adminDescription: ms-Exch-Smtp-Ldap-Bind-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLdapBindType
+name: ms-Exch-Smtp-Ldap-Bind-Type
+schemaIDGUID: 2ebcdcd4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ldap-Naming-Context	
+# The naming context to use in DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ldap-Naming-Context,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ldap-Naming-Context
+distinguishedName: CN=ms-Exch-Smtp-Ldap-Naming-Context,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5043
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ldap-Naming-Context
+adminDescription: ms-Exch-Smtp-Ldap-Naming-Context
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLdapNamingContext
+name: ms-Exch-Smtp-Ldap-Naming-Context
+schemaIDGUID: 2ef61544-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Ldap-Password	
+# The LDAP password to use in DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Ldap-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ldap-Password
+distinguishedName: CN=ms-Exch-Smtp-Ldap-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5045
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ldap-Password
+adminDescription: ms-Exch-Smtp-Ldap-Password
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLdapPassword
+name: ms-Exch-Smtp-Ldap-Password
+schemaIDGUID: 2f2f4db4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Ldap-Schema-Type	
+# The schema type to use in DSAccess.
+dn: CN=ms-Exch-Smtp-Ldap-Schema-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Ldap-Schema-Type
+distinguishedName: CN=ms-Exch-Smtp-Ldap-Schema-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5041
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Ldap-Schema-Type
+adminDescription: ms-Exch-Smtp-Ldap-Schema-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLdapSchemaType
+name: ms-Exch-Smtp-Ldap-Schema-Type
+schemaIDGUID: 2f688624-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Local-Queue-Delay-Notification	
+# The time at which this resource should send a notification regarding
+# a local undelivered message.
+#
+dn: CN=ms-Exch-Smtp-Local-Queue-Delay-Notification,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Local-Queue-Delay-Notification
+distinguishedName: CN=ms-Exch-Smtp-Local-Queue-Delay-Notification,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5011
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Local-Queue-Delay-Notification
+adminDescription: ms-Exch-Smtp-Local-Queue-Delay-Notification
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLocalQueueDelayNotification
+name: ms-Exch-Smtp-Local-Queue-Delay-Notification
+schemaIDGUID: 2f9f5c3a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Local-Queue-Expiration-Timeout	   
+# The time at which this resource should expire a local undelivered message.
+#
+dn: CN=ms-Exch-Smtp-Local-Queue-Expiration-Timeout,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Local-Queue-Expiration-Timeout
+distinguishedName: CN=ms-Exch-Smtp-Local-Queue-Expiration-Timeout,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5010
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Local-Queue-Expiration-Timeout
+adminDescription: ms-Exch-Smtp-Local-Queue-Expiration-Timeout
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpLocalQueueExpirationTimeout
+name: ms-Exch-Smtp-Local-Queue-Expiration-Timeout
+schemaIDGUID: 40bd7e66-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Masquerade-Domain      
+# The domain that mail outbound from this resource is masqueraded as.
+#
+dn: CN=ms-Exch-Smtp-Masquerade-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Masquerade-Domain
+distinguishedName: CN=ms-Exch-Smtp-Masquerade-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5026
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Masquerade-Domain
+adminDescription: ms-Exch-Smtp-Masquerade-Domain
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMasqueradeDomain
+name: ms-Exch-Smtp-Masquerade-Domain
+schemaIDGUID: 40eacb14-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Max-Hop-Count	
+# The maximum number of hops that the message transported by this
+# resource can take.
+#
+dn: CN=ms-Exch-Smtp-Max-Hop-Count,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Hop-Count
+distinguishedName: CN=ms-Exch-Smtp-Max-Hop-Count,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Hop-Count
+adminDescription: ms-Exch-Smtp-Max-Hop-Count
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxHopCount
+name: ms-Exch-Smtp-Max-Hop-Count
+schemaIDGUID: 411817c2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Max-Message-Size	    
+# The maximum size that a message delivered by this resource can be.
+#
+dn: CN=ms-Exch-Smtp-Max-Message-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Message-Size
+distinguishedName: CN=ms-Exch-Smtp-Max-Message-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5007
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Message-Size
+adminDescription: ms-Exch-Smtp-Max-Message-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxMessageSize
+name: ms-Exch-Smtp-Max-Message-Size
+schemaIDGUID: 4147c6ca-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain	   
+# The maximum number of messages delivered for connections outgoing
+# from each domain of this resource.
+#
+dn: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain
+distinguishedName: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5015
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain
+adminDescription: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxOutboundMsgPerDomain
+name: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain
+schemaIDGUID: 417775d2-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag	 
+# The maximum number of outbound messages per domain.
+#
+dn: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag
+distinguishedName: CN=ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5023
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag
+adminDescription: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxOutboundMsgPerDomainFlag
+name: ms-Exch-Smtp-Max-Outbound-Msg-Per-Domain-Flag
+schemaIDGUID: 41a724da-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Max-Outgoing-Connections	
+# The maximum number of connections outgoing from this resource.
+#
+dn: CN=ms-Exch-Smtp-Max-Outgoing-Connections,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Outgoing-Connections
+distinguishedName: CN=ms-Exch-Smtp-Max-Outgoing-Connections,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5001
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Outgoing-Connections
+adminDescription: ms-Exch-Smtp-Max-Outgoing-Connections
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxOutgoingConnections
+name: ms-Exch-Smtp-Max-Outgoing-Connections
+schemaIDGUID: 41d9363c-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain	
+# The maximum length of time for connections outgoing from each domain
+# of this resource.
+#
+dn: CN=ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain
+distinguishedName: CN=ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain,CN=Sche
+attributeID: 1.2.840.113556.1.4.7000.102.5003
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain
+adminDescription: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxOutgoingConnectionsPerDomain
+name: ms-Exch-Smtp-Max-Outgoing-Connections-Per-Domain
+schemaIDGUID: 420b479e-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Max-Recipients	   
+# The maximum number of recipients allowed on a message transferred by
+# this resource.
+#
+dn: CN=ms-Exch-Smtp-Max-Recipients,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Recipients
+distinguishedName: CN=ms-Exch-Smtp-Max-Recipients,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5009
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Recipients
+adminDescription: ms-Exch-Smtp-Max-Recipients
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxRecipients
+name: ms-Exch-Smtp-Max-Recipients
+schemaIDGUID: 423af6a6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Max-Session-Size	 
+#
+dn: CN=ms-Exch-Smtp-Max-Session-Size,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Max-Session-Size
+distinguishedName: CN=ms-Exch-Smtp-Max-Session-Size,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5008
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Max-Session-Size
+adminDescription: ms-Exch-Smtp-Max-Session-Size
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpMaxSessionSize
+name: ms-Exch-Smtp-Max-Session-Size
+schemaIDGUID: 426aa5ae-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Outbound-Security-Flag	
+# Configures which authentication is used when connecting outbound
+# from this resource.
+#
+dn: CN=ms-Exch-Smtp-Outbound-Security-Flag,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outbound-Security-Flag
+distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-Flag,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outbound-Security-Flag
+adminDescription: ms-Exch-Smtp-Outbound-Security-Flag
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutboundSecurityFlag
+name: ms-Exch-Smtp-Outbound-Security-Flag
+schemaIDGUID: 429cb710-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Outbound-Security-Password	
+# The password for outbound security.
+#
+dn: CN=ms-Exch-Smtp-Outbound-Security-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outbound-Security-Password
+distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5035
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outbound-Security-Password
+adminDescription: ms-Exch-Smtp-Outbound-Security-Password
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutboundSecurityPassword
+name: ms-Exch-Smtp-Outbound-Security-Password
+schemaIDGUID: 42edc704-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Outbound-Security-User-Name	
+# User name for outbound security.
+#
+dn: CN=ms-Exch-Smtp-Outbound-Security-User-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outbound-Security-User-Name
+distinguishedName: CN=ms-Exch-Smtp-Outbound-Security-User-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5034
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outbound-Security-User-Name
+adminDescription: ms-Exch-Smtp-Outbound-Security-User-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutboundSecurityUserName
+name: ms-Exch-Smtp-Outbound-Security-User-Name
+schemaIDGUID: 43249d1a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Outgoing-Connection-Timeout	
+# The maximum length of time for connections outgoing from this resource.
+#
+dn: CN=ms-Exch-Smtp-Outgoing-Connection-Timeout,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outgoing-Connection-Timeout
+distinguishedName: CN=ms-Exch-Smtp-Outgoing-Connection-Timeout,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5002
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outgoing-Connection-Timeout
+adminDescription: ms-Exch-Smtp-Outgoing-Connection-Timeout
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutgoingConnectionTimeout
+name: ms-Exch-Smtp-Outgoing-Connection-Timeout
+schemaIDGUID: 436037e4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Outgoing-Port	   
+# The outbound connection port number.
+#
+dn: CN=ms-Exch-Smtp-Outgoing-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outgoing-Port
+distinguishedName: CN=ms-Exch-Smtp-Outgoing-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5004
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outgoing-Port
+adminDescription: ms-Exch-Smtp-Outgoing-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutgoingPort
+name: ms-Exch-Smtp-Outgoing-Port
+schemaIDGUID: 43b3aa32-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+
+#
+# ms-Exch-Smtp-Outgoing-Secure-Port	
+# The outbound connection SSL port number.
+#
+dn: CN=ms-Exch-Smtp-Outgoing-Secure-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Outgoing-Secure-Port
+distinguishedName: CN=ms-Exch-Smtp-Outgoing-Secure-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5005
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Outgoing-Secure-Port
+adminDescription: ms-Exch-Smtp-Outgoing-Secure-Port
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpOutgoingSecurePort
+name: ms-Exch-Smtp-Outgoing-Secure-Port
+schemaIDGUID: 43f1a756-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Perform-Reverse-Dns-Lookup	
+# Performs reverse DNS lookup for delivery.
+#
+dn: CN=ms-Exch-Smtp-Perform-Reverse-Dns-Lookup,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup
+distinguishedName: CN=ms-Exch-Smtp-Perform-Reverse-Dns-Lookup,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5021
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup
+adminDescription: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpPerformReverseDnsLookup
+name: ms-Exch-Smtp-Perform-Reverse-Dns-Lookup
+schemaIDGUID: 441ef404-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Pickup-Directory	
+# The directory from which mail messages are being picked up.
+#
+dn: CN=ms-Exch-Smtp-Pickup-Directory,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Pickup-Directory
+distinguishedName: CN=ms-Exch-Smtp-Pickup-Directory,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5030
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Pickup-Directory
+adminDescription: ms-Exch-Smtp-Pickup-Directory
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpPickupDirectory
+name: ms-Exch-Smtp-Pickup-Directory
+schemaIDGUID: 444054f0-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Queue-Directory 
+# The directory where mail messages are being queued.
+#
+dn: CN=ms-Exch-Smtp-Queue-Directory,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Queue-Directory
+distinguishedName: CN=ms-Exch-Smtp-Queue-Directory,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5031
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Queue-Directory
+adminDescription: ms-Exch-Smtp-Queue-Directory
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpQueueDirectory
+name: ms-Exch-Smtp-Queue-Directory
+schemaIDGUID: 4468dcea-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Relay-For-Auth 
+# Checks if the relay IP requires authentication.
+#
+dn: CN=ms-Exch-Smtp-Relay-For-Auth,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Relay-For-Auth
+distinguishedName: CN=ms-Exch-Smtp-Relay-For-Auth,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5020
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Relay-For-Auth
+adminDescription: ms-Exch-Smtp-Relay-For-Auth
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRelayForAuth
+name: ms-Exch-Smtp-Relay-For-Auth
+schemaIDGUID: 449164e4-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Relay-Ip-List	
+# List of Internet Protocols (IPs) for relay restriction.
+#
+dn: CN=ms-Exch-Smtp-Relay-Ip-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Relay-Ip-List
+distinguishedName: CN=ms-Exch-Smtp-Relay-Ip-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5048
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Relay-Ip-List
+adminDescription: ms-Exch-Smtp-Relay-Ip-List
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRelayIpList
+name: ms-Exch-Smtp-Relay-Ip-List
+schemaIDGUID: 44b5282a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Remote-Queue-Delay-Notification	
+# The time at which this resource should send a notification regarding
+# an undelivered outbound message.
+#
+dn: CN=ms-Exch-Smtp-Remote-Queue-Delay-Notification,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Remote-Queue-Delay-Notification
+distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Delay-Notification,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5013
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Remote-Queue-Delay-Notification
+adminDescription: ms-Exch-Smtp-Remote-Queue-Delay-Notification
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRemoteQueueDelayNotification
+name: ms-Exch-Smtp-Remote-Queue-Delay-Notification
+schemaIDGUID: 44ddb024-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Remote-Queue-Expiration-Timeout	   
+# The time at which this resource should expire an undelivered
+# outbound message.
+#
+dn: CN=ms-Exch-Smtp-Remote-Queue-Expiration-Timeout,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout
+distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Expiration-Timeout,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5012
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout
+adminDescription: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRemoteQueueExpirationTimeout
+name: ms-Exch-Smtp-Remote-Queue-Expiration-Timeout
+schemaIDGUID: 4501736a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Remote-Queue-Retries   
+# The first, second, third, and subsequent retries for remote mail
+# delivery.
+#
+dn: CN=ms-Exch-Smtp-Remote-Queue-Retries,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Remote-Queue-Retries
+distinguishedName: CN=ms-Exch-Smtp-Remote-Queue-Retries,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5046
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Remote-Queue-Retries
+adminDescription: ms-Exch-Smtp-Remote-Queue-Retries
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRemoteQueueRetries
+name: ms-Exch-Smtp-Remote-Queue-Retries
+schemaIDGUID: 4527990a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Routing-Table-Type	 
+# The routing table type for DSAccess.
+#
+dn: CN=ms-Exch-Smtp-Routing-Table-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Routing-Table-Type
+distinguishedName: CN=ms-Exch-Smtp-Routing-Table-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5039
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Routing-Table-Type
+adminDescription: ms-Exch-Smtp-Routing-Table-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpRoutingTableType
+name: ms-Exch-Smtp-Routing-Table-Type
+schemaIDGUID: 454dbeaa-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Smtp-Send-Badmail-To	
+# The address to send bad mail to.
+#
+dn: CN=ms-Exch-Smtp-Send-Badmail-To,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Send-Badmail-To
+distinguishedName: CN=ms-Exch-Smtp-Send-Badmail-To,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5028
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Send-Badmail-To
+adminDescription: ms-Exch-Smtp-Send-Badmail-To
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpSendBadmailTo
+name: ms-Exch-Smtp-Send-Badmail-To
+schemaIDGUID: 4586f71a-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Send-NDR-To	
+# The address to send a non-delivery report to.
+#
+dn: CN=ms-Exch-Smtp-Send-NDR-To,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Send-NDR-To
+distinguishedName: CN=ms-Exch-Smtp-Send-NDR-To,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5027
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Send-NDR-To
+adminDescription: ms-Exch-Smtp-Send-NDR-To
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpSendNDRTo
+name: ms-Exch-Smtp-Send-NDR-To
+schemaIDGUID: 45bb6ad6-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Smart-Host  
+# Sets a Smart Host route domain for mail outbound from this resource.
+#
+dn: CN=ms-Exch-Smtp-Smart-Host,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Smart-Host
+distinguishedName: CN=ms-Exch-Smtp-Smart-Host,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5024
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Smart-Host
+adminDescription: ms-Exch-Smtp-Smart-Host
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpSmartHost
+name: ms-Exch-Smtp-Smart-Host
+schemaIDGUID: 45e19076-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-Smart-Host-Type	
+# The Smart Host type.
+#
+dn: CN=ms-Exch-Smtp-Smart-Host-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-Smart-Host-Type
+distinguishedName: CN=ms-Exch-Smtp-Smart-Host-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5014
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-Smart-Host-Type
+adminDescription: ms-Exch-Smtp-Smart-Host-Type
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchSmtpSmartHostType
+name: ms-Exch-Smtp-Smart-Host-Type
+schemaIDGUID: 46008f08-b098-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Smtp-TRN-Smart-Host	
+# Contains an alternate Smart Host to which the server should issue
+# the TURN or ETRN command.
+#
+dn: CN=ms-Exch-Smtp-TRN-Smart-Host,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Smtp-TRN-Smart-Host
+distinguishedName: CN=ms-Exch-Smtp-TRN-Smart-Host,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12531
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Smtp-TRN-Smart-Host
+adminDescription: ms-Exch-Smtp-TRN-Smart-Host
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchSmtpTRNSmartHost
+name: ms-Exch-Smtp-TRN-Smart-Host
+schemaIDGUID: be41789c-2da8-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Source-BH-Address 
+#
+dn: CN=ms-Exch-Source-BH-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Source-BH-Address
+distinguishedName: CN=ms-Exch-Source-BH-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12509
+attributeSyntax: 2.5.5.4
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 255
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Source-BH-Address
+adminDescription: ms-Exch-Source-BH-Address
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchSourceBHAddress
+name: ms-Exch-Source-BH-Address
+schemaIDGUID: 203d2f32-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Source-Bridgehead-Servers-DN		  
+# Pointers to SMTP virtual servers of servers in bridgehead on the
+# local side of Exchange Connector.
+#
+dn: CN=ms-Exch-Source-Bridgehead-Servers-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Source-Bridgehead-Servers-DN
+distinguishedName: CN=ms-Exch-Source-Bridgehead-Servers-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12511
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1002
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Source-Bridgehead-Servers-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Source-Bridgehead-Servers-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchSourceBridgeheadServersDN
+name: ms-Exch-Source-Bridgehead-Servers-DN
+schemaIDGUID: 206f4094-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Space-Last-Computed	    
+# The time at which the site-proxy-space was last computed.
+#
+dn: CN=ms-Exch-Space-Last-Computed,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Space-Last-Computed
+distinguishedName: CN=ms-Exch-Space-Last-Computed,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.386
+attributeSyntax: 2.5.5.11
+isSingleValued: TRUE
+mAPIID: 33081
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Space-Last-Computed
+adminDescription: ms-Exch-Space-Last-Computed
+oMSyntax: 23
+searchFlags: 0
+lDAPDisplayName: spaceLastComputed
+name: ms-Exch-Space-Last-Computed
+schemaIDGUID: 9928d7bc-b093-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Submission-Cont-Length   
+# Contains the maximum size message allowed to be submitted, either
+# globally or by this user.
+#
+dn: CN=ms-Exch-Submission-Cont-Length,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Submission-Cont-Length
+distinguishedName: CN=ms-Exch-Submission-Cont-Length,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.280
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33084
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Submission-Cont-Length
+adminDescription: ms-Exch-Submission-Cont-Length
+oMSyntax: 2
+searchFlags: 16
+lDAPDisplayName: submissionContLength
+name: ms-Exch-Submission-Cont-Length
+schemaIDGUID: bf967a3e-0de6-11d0-a285-00aa003049e2
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-SubmitRelaySD	  
+#
+dn: CN=ms-Exch-SubmitRelaySD,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-SubmitRelaySD
+distinguishedName: CN=ms-Exch-SubmitRelaySD,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.5060
+attributeSyntax: 2.5.5.15
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-SubmitRelaySD
+adminDescription: ms-Exch-SubmitRelaySD
+oMSyntax: 66
+searchFlags: 0
+lDAPDisplayName: msExchSubmitRelaySD
+name: ms-Exch-SubmitRelaySD
+schemaIDGUID: e2cefbcc-dcc1-45a5-bab8-d5f4bd78884d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Supported-Algorithms	   
+#
+dn: CN=ms-Exch-Supported-Algorithms,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Supported-Algorithms
+distinguishedName: CN=ms-Exch-Supported-Algorithms,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.597
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32767
+mAPIID: 35925
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Supported-Algorithms
+adminDescription: ms-Exch-Supported-Algorithms
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: supportedAlgorithms
+name: ms-Exch-Supported-Algorithms
+schemaIDGUID: 1677588e-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Supporting-Stack	   
+#
+dn: CN=ms-Exch-Supporting-Stack,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Supporting-Stack
+distinguishedName: CN=ms-Exch-Supporting-Stack,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.28
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33086
+linkID: 132
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Supporting-Stack
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Supporting-Stack
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: supportingStack
+name: ms-Exch-Supporting-Stack
+schemaIDGUID: a8df7480-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Supporting-Stack-BL	   
+#
+dn: CN=ms-Exch-Supporting-Stack-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Supporting-Stack-BL
+distinguishedName: CN=ms-Exch-Supporting-Stack-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.357
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33087
+linkID: 133
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Supporting-Stack-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Supporting-Stack-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: supportingStackBL
+name: ms-Exch-Supporting-Stack-BL
+schemaIDGUID: 16775891-47f3-11d1-a9c3-0000f80367c1
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Support-SMIME-Signatures 
+#
+dn: CN=ms-Exch-Support-SMIME-Signatures,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Support-SMIME-Signatures
+distinguishedName: CN=ms-Exch-Support-SMIME-Signatures,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.590
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 35912
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Support-SMIME-Signatures
+adminDescription: ms-Exch-Support-SMIME-Signatures
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: supportSMIMESignatures
+name: ms-Exch-Support-SMIME-Signatures
+schemaIDGUID: a8df747f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Synchronization-Direction    
+# The direction in which the directories will be synchronized.
+#
+dn: CN=ms-Exch-Synchronization-Direction,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Synchronization-Direction
+distinguishedName: CN=ms-Exch-Synchronization-Direction,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.1
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 2
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Synchronization-Direction
+adminDescription: ms-Exch-Synchronization-Direction
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: msExchSynchronizationDirection
+name: ms-Exch-Synchronization-Direction
+schemaIDGUID: 20a151f6-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-S-Selector	       
+#
+dn: CN=ms-Exch-S-Selector,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-S-Selector
+distinguishedName: CN=ms-Exch-S-Selector,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.284
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 33067
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-S-Selector
+adminDescription: ms-Exch-S-Selector
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: sSelector
+name: ms-Exch-S-Selector
+schemaIDGUID: a8df746c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-S-Selector-Inbound   
+#
+dn: CN=ms-Exch-S-Selector-Inbound,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-S-Selector-Inbound
+distinguishedName: CN=ms-Exch-S-Selector-Inbound,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.46
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 16
+mAPIID: 33068
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-S-Selector-Inbound
+adminDescription: ms-Exch-S-Selector-Inbound
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: sSelectorInbound
+name: ms-Exch-S-Selector-Inbound
+schemaIDGUID: a8df746d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Target-Address       
+# Contains the destination address for this object.
+dn: CN=ms-Exch-Target-Address,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Target-Address
+distinguishedName: CN=ms-Exch-Target-Address,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.352
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1123
+mAPIID: 32785
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Target-Address
+adminDescription: ms-Exch-Target-Address
+oMSyntax: 64
+searchFlags: 1
+lDAPDisplayName: targetAddress
+name: ms-Exch-Target-Address
+schemaIDGUID: f0f8ff9f-1191-11d0-a060-00aa006c33ed
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Target-Bridgehead-Servers-DN	
+# Pointers to bridgehead SMTP virtual servers in the connector target
+# routing group (RG).
+#
+dn: CN=ms-Exch-Target-Bridgehead-Servers-DN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Target-Bridgehead-Servers-DN
+distinguishedName: CN=ms-Exch-Target-Bridgehead-Servers-DN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12514
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1004
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Target-Bridgehead-Servers-DN
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Target-Bridgehead-Servers-DN
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchTargetBridgeheadServersDN
+name: ms-Exch-Target-Bridgehead-Servers-DN
+schemaIDGUID: 20da8a66-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Target-MTAs	    
+# Used by Exchange Server 5.5 to indicate the message transfer agents
+# (MTAs) on the remote side of a connector.
+#
+dn: CN=ms-Exch-Target-MTAs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Target-MTAs
+distinguishedName: CN=ms-Exch-Target-MTAs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.259
+attributeSyntax: 2.5.5.4
+isSingleValued: FALSE
+rangeLower: 1
+rangeUpper: 36
+mAPIID: 33090
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Target-MTAs
+adminDescription: ms-Exch-Target-MTAs
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: targetMTAs
+name: ms-Exch-Target-MTAs
+schemaIDGUID: a8df7483-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Telephone-Assistant	
+# The telephone number of the assistant that corresponds to this user.
+#
+dn: CN=ms-Exch-Telephone-Assistant,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Telephone-Assistant
+distinguishedName: CN=ms-Exch-Telephone-Assistant,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.79
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 64
+mAPIID: 14894
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Telephone-Assistant
+adminDescription: ms-Exch-Telephone-Assistant
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: telephoneAssistant
+name: ms-Exch-Telephone-Assistant
+schemaIDGUID: a8df7484-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Telephone-Personal-Pager 
+#
+dn: CN=ms-Exch-Telephone-Personal-Pager,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Telephone-Personal-Pager
+distinguishedName: CN=ms-Exch-Telephone-Personal-Pager,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.612
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 35944
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Telephone-Personal-Pager
+adminDescription: ms-Exch-Telephone-Personal-Pager
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: personalPager
+name: ms-Exch-Telephone-Personal-Pager
+schemaIDGUID: a8df7487-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Template-RDNs	 
+# The Relative Distinguished Names (RDNs) to the child template
+# objects.
+#
+dn: CN=ms-Exch-Template-RDNs,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Template-RDNs
+distinguishedName: CN=ms-Exch-Template-RDNs,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.65
+attributeSyntax: 2.5.5.4
+isSingleValued: FALSE
+mAPIID: 65528
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Template-RDNs
+adminDescription: ms-Exch-Template-RDNs
+oMSyntax: 20
+searchFlags: 0
+lDAPDisplayName: msExchTemplateRDNs
+name: ms-Exch-Template-RDNs
+schemaIDGUID: 211fae98-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Temp-Assoc-Threshold	
+#
+dn: CN=ms-Exch-Temp-Assoc-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Temp-Assoc-Threshold
+distinguishedName: CN=ms-Exch-Temp-Assoc-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.329
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32767
+mAPIID: 33092
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Temp-Assoc-Threshold
+adminDescription: ms-Exch-Temp-Assoc-Threshold
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: tempAssocThreshold
+name: ms-Exch-Temp-Assoc-Threshold
+schemaIDGUID: a8df7488-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Tracking-Log-Path-Name    
+#
+dn: CN=ms-Exch-Tracking-Log-Path-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Tracking-Log-Path-Name
+distinguishedName: CN=ms-Exch-Tracking-Log-Path-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.347
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 256
+mAPIID: 33094
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Tracking-Log-Path-Name
+adminDescription: ms-Exch-Tracking-Log-Path-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: trackingLogPathName
+name: ms-Exch-Tracking-Log-Path-Name
+schemaIDGUID: bf967a57-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Track-Duplicates	    
+# The number of hours for which information about received messages
+# will be kept and duplicates will be eliminated.
+#
+dn: CN=ms-Exch-Track-Duplicates,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Track-Duplicates
+distinguishedName: CN=ms-Exch-Track-Duplicates,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.11006
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Track-Duplicates
+adminDescription: ms-Exch-Track-Duplicates
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchTrackDuplicates
+name: ms-Exch-Track-Duplicates
+schemaIDGUID: 2196e42c-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Transfer-Retry-Interval 
+#
+dn: CN=ms-Exch-Transfer-Retry-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Transfer-Retry-Interval
+distinguishedName: CN=ms-Exch-Transfer-Retry-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.133
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33097
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transfer-Retry-Interval
+adminDescription: ms-Exch-Transfer-Retry-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transferRetryInterval
+name: ms-Exch-Transfer-Retry-Interval
+schemaIDGUID: a8df748c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Transfer-Timeout-Non-Urgent 
+#
+dn: CN=ms-Exch-Transfer-Timeout-Non-Urgent,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Transfer-Timeout-Non-Urgent
+distinguishedName: CN=ms-Exch-Transfer-Timeout-Non-Urgent,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.136
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33098
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transfer-Timeout-Non-Urgent
+adminDescription: ms-Exch-Transfer-Timeout-Non-Urgent
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transferTimeoutNonUrgent
+name: ms-Exch-Transfer-Timeout-Non-Urgent
+schemaIDGUID: a8df748d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Transfer-Timeout-Normal     
+#
+dn: CN=ms-Exch-Transfer-Timeout-Normal,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Transfer-Timeout-Normal
+distinguishedName: CN=ms-Exch-Transfer-Timeout-Normal,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.137
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33099
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transfer-Timeout-Normal
+adminDescription: ms-Exch-Transfer-Timeout-Normal
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transferTimeoutNormal
+name: ms-Exch-Transfer-Timeout-Normal
+schemaIDGUID: a8df748e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Transfer-Timeout-Urgent     
+#
+dn: CN=ms-Exch-Transfer-Timeout-Urgent,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Transfer-Timeout-Urgent
+distinguishedName: CN=ms-Exch-Transfer-Timeout-Urgent,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.142
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33100
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transfer-Timeout-Urgent
+adminDescription: ms-Exch-Transfer-Timeout-Urgent
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transferTimeoutUrgent
+name: ms-Exch-Transfer-Timeout-Urgent
+schemaIDGUID: a8df748f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Translation-Table-Used      
+#
+dn: CN=ms-Exch-Translation-Table-Used,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Translation-Table-Used
+distinguishedName: CN=ms-Exch-Translation-Table-Used,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.396
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33101
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Translation-Table-Used
+adminDescription: ms-Exch-Translation-Table-Used
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: translationTableUsed
+name: ms-Exch-Translation-Table-Used
+schemaIDGUID: a8df7490-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Transport-Expedited-Data    
+#
+dn: CN=ms-Exch-Transport-Expedited-Data,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Transport-Expedited-Data
+distinguishedName: CN=ms-Exch-Transport-Expedited-Data,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.150
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33102
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Transport-Expedited-Data
+adminDescription: ms-Exch-Transport-Expedited-Data
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: transportExpeditedData
+name: ms-Exch-Transport-Expedited-Data
+schemaIDGUID: a8df7491-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Trans-Retry-Mins	      
+#
+dn: CN=ms-Exch-Trans-Retry-Mins,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Trans-Retry-Mins
+distinguishedName: CN=ms-Exch-Trans-Retry-Mins,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.219
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33095
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Trans-Retry-Mins
+adminDescription: ms-Exch-Trans-Retry-Mins
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transRetryMins
+name: ms-Exch-Trans-Retry-Mins
+schemaIDGUID: a8df748a-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Trans-Timeout-Mins	      
+#
+dn: CN=ms-Exch-Trans-Timeout-Mins,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Trans-Timeout-Mins
+distinguishedName: CN=ms-Exch-Trans-Timeout-Mins,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.220
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+mAPIID: 33096
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Trans-Timeout-Mins
+adminDescription: ms-Exch-Trans-Timeout-Mins
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: transTimeoutMins
+name: ms-Exch-Trans-Timeout-Mins
+schemaIDGUID: a8df748b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Trk-Log-Cleaning-Interval   
+# The number of days after which to remove a tracking log file.
+#
+dn: CN=ms-Exch-Trk-Log-Cleaning-Interval,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Trk-Log-Cleaning-Interval
+distinguishedName: CN=ms-Exch-Trk-Log-Cleaning-Interval,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.50016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Trk-Log-Cleaning-Interval
+adminDescription: ms-Exch-Trk-Log-Cleaning-Interval
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchTrkLogCleaningInterval
+name: ms-Exch-Trk-Log-Cleaning-Interval
+schemaIDGUID: 21d27ef6-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Trust-Level  
+#
+dn: CN=ms-Exch-Trust-Level,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Trust-Level
+distinguishedName: CN=ms-Exch-Trust-Level,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.70
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 100
+mAPIID: 33103
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Trust-Level
+adminDescription: ms-Exch-Trust-Level
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: trustLevel
+name: ms-Exch-Trust-Level
+schemaIDGUID: a8df7492-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-TUI-Password 
+# The user logon authentication password when accessed by phone.
+#
+dn: CN=ms-Exch-TUI-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-TUI-Password
+distinguishedName: CN=ms-Exch-TUI-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17025
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-TUI-Password
+adminDescription: ms-Exch-TUI-Password
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: msExchTUIPassword
+name: ms-Exch-TUI-Password
+schemaIDGUID: 567d521f-2f6a-11d3-aa6c-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-TUI-Speed   
+# The speed at which to play text to speech.
+#
+dn: CN=ms-Exch-TUI-Speed,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-TUI-Speed
+distinguishedName: CN=ms-Exch-TUI-Speed,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17027
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-TUI-Speed
+adminDescription: ms-Exch-TUI-Speed
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchTUISpeed
+name: ms-Exch-TUI-Speed
+schemaIDGUID: 567d522a-2f6a-11d3-aa6c-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-TUI-Volume	
+# The volume at which to play voice mail and text-to-speech mail via
+# Telephone User Interface (TUI).
+#
+dn: CN=ms-Exch-TUI-Volume,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-TUI-Volume
+distinguishedName: CN=ms-Exch-TUI-Volume,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17026
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-TUI-Volume
+adminDescription: ms-Exch-TUI-Volume
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchTUIVolume
+name: ms-Exch-TUI-Volume
+schemaIDGUID: 567d5225-2f6a-11d3-aa6c-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Turf-List 
+#
+dn: CN=ms-Exch-Turf-List,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Turf-List
+distinguishedName: CN=ms-Exch-Turf-List,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5051
+attributeSyntax: 2.5.5.5
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Turf-List
+adminDescription: ms-Exch-Turf-List
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: msExchTurfList
+name: ms-Exch-Turf-List
+schemaIDGUID: 8b60f7f8-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Turf-List-Action    
+#
+dn: CN=ms-Exch-Turf-List-Action,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Turf-List-Action
+distinguishedName: CN=ms-Exch-Turf-List-Action,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12535
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Turf-List-Action
+adminDescription: ms-Exch-Turf-List-Action
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchTurfListAction
+name: ms-Exch-Turf-List-Action
+schemaIDGUID: 0b836daa-3b20-11d3-aa6f-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Turf-List-Names     
+#
+dn: CN=ms-Exch-Turf-List-Names,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Turf-List-Names
+distinguishedName: CN=ms-Exch-Turf-List-Names,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12534
+attributeSyntax: 2.5.5.12
+isSingleValued: FALSE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Turf-List-Names
+adminDescription: ms-Exch-Turf-List-Names
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchTurfListNames
+name: ms-Exch-Turf-List-Names
+schemaIDGUID: 0b836da0-3b20-11d3-aa6f-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Turf-List-Options   
+#
+dn: CN=ms-Exch-Turf-List-Options,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Turf-List-Options
+distinguishedName: CN=ms-Exch-Turf-List-Options,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.5054
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Turf-List-Options
+adminDescription: ms-Exch-Turf-List-Options
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchTurfListOptions
+name: ms-Exch-Turf-List-Options
+schemaIDGUID: 01dbe64c-bfeb-47cd-9939-8911946bdd6d
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Turn-Request-Threshold  
+#
+dn: CN=ms-Exch-Turn-Request-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Turn-Request-Threshold
+distinguishedName: CN=ms-Exch-Turn-Request-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.38
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33104
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Turn-Request-Threshold
+adminDescription: ms-Exch-Turn-Request-Threshold
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: turnRequestThreshold
+name: ms-Exch-Turn-Request-Threshold
+schemaIDGUID: a8df7493-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Two-Way-Alternate-Facility  
+#
+dn: CN=ms-Exch-Two-Way-Alternate-Facility,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Two-Way-Alternate-Facility
+distinguishedName: CN=ms-Exch-Two-Way-Alternate-Facility,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.40
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33105
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Two-Way-Alternate-Facility
+adminDescription: ms-Exch-Two-Way-Alternate-Facility
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: twoWayAlternateFacility
+name: ms-Exch-Two-Way-Alternate-Facility
+schemaIDGUID: a8df7494-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Type		   
+#
+dn: CN=ms-Exch-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Type
+distinguishedName: CN=ms-Exch-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.573
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 35896
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Type
+adminDescription: ms-Exch-Type
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: type
+name: ms-Exch-Type
+schemaIDGUID: 167758aa-47f3-11d1-a9c3-0000f80367c1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-T-Selector	   
+#
+dn: CN=ms-Exch-T-Selector,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-T-Selector
+distinguishedName: CN=ms-Exch-T-Selector,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.283
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 32
+mAPIID: 33088
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-T-Selector
+adminDescription: ms-Exch-T-Selector
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: tSelector
+name: ms-Exch-T-Selector
+schemaIDGUID: a8df7481-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Uce-Block-Threshold  
+#
+dn: CN=ms-Exch-Uce-Block-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Uce-Block-Threshold
+distinguishedName: CN=ms-Exch-Uce-Block-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12601
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Uce-Block-Threshold
+adminDescription: ms-Exch-Uce-Block-Threshold
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchUceBlockThreshold
+name: ms-Exch-Uce-Block-Threshold
+schemaIDGUID: 9f297c14-d715-4631-a259-bf51dc52eac1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Uce-Enabled	       
+#
+dn: CN=ms-Exch-Uce-Enabled,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Uce-Enabled
+distinguishedName: CN=ms-Exch-Uce-Enabled,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12600
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Uce-Enabled
+adminDescription: ms-Exch-Uce-Enabled
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchUceEnabled
+name: ms-Exch-Uce-Enabled
+schemaIDGUID: 15e2db2e-7206-4109-9b94-830f4def1b05
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Uce-Store-Action-Threshold	
+#
+dn: CN=ms-Exch-Uce-Store-Action-Threshold,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Uce-Store-Action-Threshold
+distinguishedName: CN=ms-Exch-Uce-Store-Action-Threshold,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.12602
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Uce-Store-Action-Threshold
+adminDescription: ms-Exch-Uce-Store-Action-Threshold
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchUceStoreActionThreshold
+name: ms-Exch-Uce-Store-Action-Threshold
+schemaIDGUID: 44ccbd60-6ede-46f0-8f13-931a9bb5b8e8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Unauth-Orig	   
+# Contains objects that may not send to this recipient.
+#
+dn: CN=ms-Exch-Unauth-Orig,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Unauth-Orig
+distinguishedName: CN=ms-Exch-Unauth-Orig,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.221
+attributeSyntax: 2.5.5.7
+isSingleValued: FALSE
+linkID: 114
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Unauth-Orig
+oMObjectClass:: VgYBAgULHQ==
+adminDescription: ms-Exch-Unauth-Orig
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: unauthOrig
+name: ms-Exch-Unauth-Orig
+schemaIDGUID: a8df7495-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Unauth-Orig-BL   
+# A backlink to ms-Exch-Unauth-Orig.
+#
+dn: CN=ms-Exch-Unauth-Orig-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Unauth-Orig-BL
+distinguishedName: CN=ms-Exch-Unauth-Orig-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.292
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+mAPIID: 33106
+linkID: 115
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Unauth-Orig-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Unauth-Orig-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: unauthOrigBL
+name: ms-Exch-Unauth-Orig-BL
+schemaIDGUID: a8df7496-c5ea-11d1-bbcb-0080c76670c0
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+systemFlags: 1
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-UNC-Password	  
+# Specifies the encrypted password used to gain access to Universal
+# Naming Convention (UNC) virtual roots.
+#
+dn: CN=ms-Exch-UNC-Password,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-UNC-Password
+distinguishedName: CN=ms-Exch-UNC-Password,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15004
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-UNC-Password
+adminDescription: ms-Exch-UNC-Password
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchUNCPassword
+name: ms-Exch-UNC-Password
+schemaIDGUID: 8c07dc94-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-UNC-Username	 
+# Specifies the user name for UNC virtual roots.
+#
+dn: CN=ms-Exch-UNC-Username,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-UNC-Username
+distinguishedName: CN=ms-Exch-UNC-Username,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15003
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-UNC-Username
+adminDescription: ms-Exch-UNC-Username
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchUNCUsername
+name: ms-Exch-UNC-Username
+schemaIDGUID: 8be8de02-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Unmerged-Atts	
+# A set of DN syntax attribute values that were not set on the target
+# object because the object they pointed to was not found in the
+# target directory.
+#
+dn: CN=ms-Exch-Unmerged-Atts,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Unmerged-Atts
+distinguishedName: CN=ms-Exch-Unmerged-Atts,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.48
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Unmerged-Atts
+adminDescription: ms-Exch-Unmerged-Atts
+oMSyntax: 4
+searchFlags: 1
+lDAPDisplayName: unmergedAtts
+name: ms-Exch-Unmerged-Atts
+schemaIDGUID: 9947d64e-b093-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Unmerged-Atts-Pt  
+# Exchange-specific unmerged attributes.
+#
+dn: CN=ms-Exch-Unmerged-Atts-Pt,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Unmerged-Atts-Pt
+distinguishedName: CN=ms-Exch-Unmerged-Atts-Pt,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.90
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Unmerged-Atts-Pt
+adminDescription: ms-Exch-Unmerged-Atts-Pt
+oMSyntax: 4
+searchFlags: 1
+lDAPDisplayName: msExchUnmergedAttsPt
+name: ms-Exch-Unmerged-Atts-Pt
+schemaIDGUID: a5924ad4-c597-4db1-8f9d-1799909dc166
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Usenet-Site-Name	
+#
+dn: CN=ms-Exch-Usenet-Site-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Usenet-Site-Name
+distinguishedName: CN=ms-Exch-Usenet-Site-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.484
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33161
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Usenet-Site-Name
+adminDescription: ms-Exch-Usenet-Site-Name
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: usenetSiteName
+name: ms-Exch-Usenet-Site-Name
+schemaIDGUID: f0f8ffa8-1191-11d0-a060-00aa006c33ed
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-User-Account-Control	
+#
+dn: CN=ms-Exch-User-Account-Control,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-User-Account-Control
+distinguishedName: CN=ms-Exch-User-Account-Control,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.101
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-User-Account-Control
+adminDescription: ms-Exch-User-Account-Control
+oMSyntax: 2
+searchFlags: 25
+lDAPDisplayName: msExchUserAccountControl
+name: ms-Exch-User-Account-Control
+schemaIDGUID: 07c31f12-a3e8-4fa0-af8e-4932c75b2241
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Use-OAB    
+# The OAB that this mailbox store or this user uses.
+#
+dn: CN=ms-Exch-Use-OAB,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Use-OAB
+distinguishedName: CN=ms-Exch-Use-OAB,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.69
+attributeSyntax: 2.5.5.1
+isSingleValued: TRUE
+linkID: 1014
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Use-OAB
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Use-OAB
+oMSyntax: 127
+searchFlags: 16
+lDAPDisplayName: msExchUseOAB
+name: ms-Exch-Use-OAB
+schemaIDGUID: 2209550c-b099-11d2-aa06-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Use-OAB-BL	
+#
+dn: CN=ms-Exch-Use-OAB-BL,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Use-OAB-BL
+distinguishedName: CN=ms-Exch-Use-OAB-BL,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.70
+attributeSyntax: 2.5.5.1
+isSingleValued: FALSE
+linkID: 1015
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Use-OAB-BL
+oMObjectClass:: KwwCh3McAIVK
+adminDescription: ms-Exch-Use-OAB-BL
+oMSyntax: 127
+searchFlags: 0
+lDAPDisplayName: msExchUseOABBL
+name: ms-Exch-Use-OAB-BL
+schemaIDGUID: 22428d7c-b099-11d2-aa06-00c04f8eedd8
+systemFlags: 1
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Use-Site-Values   
+#
+dn: CN=ms-Exch-Use-Site-Values,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Use-Site-Values
+distinguishedName: CN=ms-Exch-Use-Site-Values,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.478
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33155
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Use-Site-Values
+adminDescription: ms-Exch-Use-Site-Values
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: useSiteValues
+name: ms-Exch-Use-Site-Values
+schemaIDGUID: a8df7497-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Visibility-Mask   
+# The data conference visibility mask.
+dn: CN=ms-Exch-Visibility-Mask,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Visibility-Mask
+distinguishedName: CN=ms-Exch-Visibility-Mask,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.9016
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Visibility-Mask
+adminDescription: ms-Exch-Visibility-Mask
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: msExchVisibilityMask
+name: ms-Exch-Visibility-Mask
+schemaIDGUID: 22770138-b099-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-Voice-Mailbox-ID	
+# The telephone extension of a user's mailbox ID when accessed by phone.
+#
+dn: CN=ms-Exch-Voice-Mailbox-ID,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Voice-Mailbox-ID
+distinguishedName: CN=ms-Exch-Voice-Mailbox-ID,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17019
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Voice-Mailbox-ID
+adminDescription: ms-Exch-Voice-Mailbox-ID
+oMSyntax: 64
+searchFlags: 1
+lDAPDisplayName: msExchVoiceMailboxID
+name: ms-Exch-Voice-Mailbox-ID
+schemaIDGUID: 567d5200-2f6a-11d3-aa6c-00c04f8eedd8
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: TRUE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-VPIM-Convert-Inbound	    
+# Convert inbound Voice Profile for Internet Mail (VPIM) messages via
+# SMTP to Multimedia Message format.
+#
+dn: CN=ms-Exch-VPIM-Convert-Inbound,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-VPIM-Convert-Inbound
+distinguishedName: CN=ms-Exch-VPIM-Convert-Inbound,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17008
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-VPIM-Convert-Inbound
+adminDescription: ms-Exch-VPIM-Convert-Inbound
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchVPIMConvertInbound
+name: ms-Exch-VPIM-Convert-Inbound
+schemaIDGUID: 2d0977eb-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-VPIM-Convert-Outbound	   
+# Convert outbound Multimedia Message format to Voice Profile for
+# Internet Mail (VPIM) based on address or non-delivery report (NDR).
+#
+dn: CN=ms-Exch-VPIM-Convert-Outbound,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-VPIM-Convert-Outbound
+distinguishedName: CN=ms-Exch-VPIM-Convert-Outbound,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.17009
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-VPIM-Convert-Outbound
+adminDescription: ms-Exch-VPIM-Convert-Outbound
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: msExchVPIMConvertOutbound
+name: ms-Exch-VPIM-Convert-Outbound
+schemaIDGUID: 2d0977f1-2b54-11d3-aa6b-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-Web-Access-Name   
+# The name through which users will access Exchange data via HTTP.
+#
+dn: CN=ms-Exch-Web-Access-Name,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-Web-Access-Name
+distinguishedName: CN=ms-Exch-Web-Access-Name,${SCHEMADN}
+attributeID: 1.2.840.113556.1.4.7000.102.15007
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-Web-Access-Name
+adminDescription: ms-Exch-Web-Access-Name
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: msExchWebAccessName
+name: ms-Exch-Web-Access-Name
+schemaIDGUID: 8df7c5b4-b09e-11d2-aa06-00c04f8eedd8
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-Call-User-Data-Incoming	  
+#
+dn: CN=ms-Exch-X25-Call-User-Data-Incoming,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Call-User-Data-Incoming
+distinguishedName: CN=ms-Exch-X25-Call-User-Data-Incoming,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.316
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33113
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Call-User-Data-Incoming
+adminDescription: ms-Exch-X25-Call-User-Data-Incoming
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x25CallUserDataIncoming
+name: ms-Exch-X25-Call-User-Data-Incoming
+schemaIDGUID: a8df749b-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X25-Call-User-Data-Outgoing	  
+#
+dn: CN=ms-Exch-X25-Call-User-Data-Outgoing,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Call-User-Data-Outgoing
+distinguishedName: CN=ms-Exch-X25-Call-User-Data-Outgoing,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.317
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 128
+mAPIID: 33114
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Call-User-Data-Outgoing
+adminDescription: ms-Exch-X25-Call-User-Data-Outgoing
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x25CallUserDataOutgoing
+name: ms-Exch-X25-Call-User-Data-Outgoing
+schemaIDGUID: a8df749c-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-Facilities-Data-Incoming	  
+#
+dn: CN=ms-Exch-X25-Facilities-Data-Incoming,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Facilities-Data-Incoming
+distinguishedName: CN=ms-Exch-X25-Facilities-Data-Incoming,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.318
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 109
+mAPIID: 33115
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Facilities-Data-Incoming
+adminDescription: ms-Exch-X25-Facilities-Data-Incoming
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x25FacilitiesDataIncoming
+name: ms-Exch-X25-Facilities-Data-Incoming
+schemaIDGUID: a8df749d-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-Facilities-Data-Outgoing	  
+#
+dn: CN=ms-Exch-X25-Facilities-Data-Outgoing,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Facilities-Data-Outgoing
+distinguishedName: CN=ms-Exch-X25-Facilities-Data-Outgoing,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.319
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 109
+mAPIID: 33116
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Facilities-Data-Outgoing
+adminDescription: ms-Exch-X25-Facilities-Data-Outgoing
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x25FacilitiesDataOutgoing
+name: ms-Exch-X25-Facilities-Data-Outgoing
+schemaIDGUID: a8df749e-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+#
+# ms-Exch-X25-Leased-Line-Port		  
+#
+dn: CN=ms-Exch-X25-Leased-Line-Port,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Leased-Line-Port
+distinguishedName: CN=ms-Exch-X25-Leased-Line-Port,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.321
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 3
+mAPIID: 33117
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Leased-Line-Port
+adminDescription: ms-Exch-X25-Leased-Line-Port
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x25LeasedLinePort
+name: ms-Exch-X25-Leased-Line-Port
+schemaIDGUID: a8df749f-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X25-Leased-Or-Switched	  
+#
+dn: CN=ms-Exch-X25-Leased-Or-Switched,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Leased-Or-Switched
+distinguishedName: CN=ms-Exch-X25-Leased-Or-Switched,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.372
+attributeSyntax: 2.5.5.8
+isSingleValued: TRUE
+mAPIID: 33118
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Leased-Or-Switched
+adminDescription: ms-Exch-X25-Leased-Or-Switched
+oMSyntax: 1
+searchFlags: 0
+lDAPDisplayName: x25LeasedOrSwitched
+name: ms-Exch-X25-Leased-Or-Switched
+schemaIDGUID: a8df74a0-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X25-Remote-MTA-Phone		  
+#
+dn: CN=ms-Exch-X25-Remote-MTA-Phone,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X25-Remote-MTA-Phone
+distinguishedName: CN=ms-Exch-X25-Remote-MTA-Phone,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.373
+attributeSyntax: 2.5.5.5
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 55
+mAPIID: 33119
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X25-Remote-MTA-Phone
+adminDescription: ms-Exch-X25-Remote-MTA-Phone
+oMSyntax: 19
+searchFlags: 0
+lDAPDisplayName: x25RemoteMTAPhone
+name: ms-Exch-X25-Remote-MTA-Phone
+schemaIDGUID: a8df74a1-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X400-Attachment-Type		  
+#
+dn: CN=ms-Exch-X400-Attachment-Type,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X400-Attachment-Type
+distinguishedName: CN=ms-Exch-X400-Attachment-Type,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.99
+attributeSyntax: 2.5.5.10
+isSingleValued: TRUE
+mAPIID: 33120
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X400-Attachment-Type
+adminDescription: ms-Exch-X400-Attachment-Type
+oMSyntax: 4
+searchFlags: 0
+lDAPDisplayName: x400AttachmentType
+name: ms-Exch-X400-Attachment-Type
+schemaIDGUID: a8df74a2-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X400-Selector-Syntax		  
+#
+dn: CN=ms-Exch-X400-Selector-Syntax,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X400-Selector-Syntax
+distinguishedName: CN=ms-Exch-X400-Selector-Syntax,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.443
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 1
+mAPIID: 33121
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X400-Selector-Syntax
+adminDescription: ms-Exch-X400-Selector-Syntax
+oMSyntax: 10
+searchFlags: 0
+lDAPDisplayName: x400SelectorSyntax
+name: ms-Exch-X400-Selector-Syntax
+schemaIDGUID: a8df74a3-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X500-NC    
+#
+dn: CN=ms-Exch-X500-NC,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X500-NC
+distinguishedName: CN=ms-Exch-X500-NC,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.509
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 1024
+mAPIID: 33186
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X500-NC
+adminDescription: ms-Exch-X500-NC
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: dnQualifier
+name: ms-Exch-X500-NC
+schemaIDGUID: 167758c6-47f3-11d1-a9c3-0000f80367c1
+attributeSecurityGUID: e48d0154-bcf8-11d1-8702-00c04fb96050
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-X500-RDN   
+#
+dn: CN=ms-Exch-X500-RDN,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-X500-RDN
+distinguishedName: CN=ms-Exch-X500-RDN,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.508
+attributeSyntax: 2.5.5.12
+isSingleValued: TRUE
+rangeLower: 1
+rangeUpper: 256
+mAPIID: 33185
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-X500-RDN
+adminDescription: ms-Exch-X500-RDN
+oMSyntax: 64
+searchFlags: 0
+lDAPDisplayName: x500RDN
+name: ms-Exch-X500-RDN
+schemaIDGUID: bf967a7d-0de6-11d0-a285-00aa003049e2
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-XMIT-Timeout-Non-Urgent	   
+#
+dn: CN=ms-Exch-XMIT-Timeout-Non-Urgent,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-XMIT-Timeout-Non-Urgent
+distinguishedName: CN=ms-Exch-XMIT-Timeout-Non-Urgent,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.84
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33123
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-XMIT-Timeout-Non-Urgent
+adminDescription: ms-Exch-XMIT-Timeout-Non-Urgent
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: xMITTimeoutNonUrgent
+name: ms-Exch-XMIT-Timeout-Non-Urgent
+schemaIDGUID: a8df74a4-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-XMIT-Timeout-Normal		   
+#
+dn: CN=ms-Exch-XMIT-Timeout-Normal,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-XMIT-Timeout-Normal
+distinguishedName: CN=ms-Exch-XMIT-Timeout-Normal,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.67
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33124
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-XMIT-Timeout-Normal
+adminDescription: ms-Exch-XMIT-Timeout-Normal
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: xMITTimeoutNormal
+name: ms-Exch-XMIT-Timeout-Normal
+schemaIDGUID: a8df74a5-c5ea-11d1-bbcb-0080c76670c0
+isMemberOfPartialAttributeSet: FALSE
+objectCategory: CN=Attribute-Schema,${SCHEMADN}
+
+
+
+
+#
+# ms-Exch-XMIT-Timeout-Urgent		   
+#
+dn: CN=ms-Exch-XMIT-Timeout-Urgent,${SCHEMADN}
+objectClass: top
+objectClass: attributeSchema
+cn: ms-Exch-XMIT-Timeout-Urgent
+distinguishedName: CN=ms-Exch-XMIT-Timeout-Urgent,${SCHEMADN}
+attributeID: 1.2.840.113556.1.2.53
+attributeSyntax: 2.5.5.9
+isSingleValued: TRUE
+rangeLower: 0
+rangeUpper: 32767
+mAPIID: 33125
+showInAdvancedViewOnly: TRUE
+adminDisplayName: ms-Exch-XMIT-Timeout-Urgent
+adminDescription: ms-Exch-XMIT-Timeout-Urgent
+oMSyntax: 2
+searchFlags: 0
+lDAPDisplayName: xMITTimeoutUrgent
+name: ms-Exch-XMIT-Timeout-Urgent
+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}

Added: trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif	                        (rev 0)
+++ trunk/openchange/setup/AD/oc_provision_schema_ADSC.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,249 @@
+#
+# 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}

Added: trunk/openchange/setup/AD/oc_provision_schema_modify.ldif
===================================================================
--- trunk/openchange/setup/AD/oc_provision_schema_modify.ldif	                        (rev 0)
+++ trunk/openchange/setup/AD/oc_provision_schema_modify.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,674 @@
+# 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-Configuraion-Container class: see oc_provision_schema.ldif
+#
+
+
+#
+# Computer class
+# Represents a computer account in the domain
+#
+dn: CN=Computer,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: msExchExchangeServerLink
+mayContain: logRolloverInterval
+mayContain: monitoredConfigurations
+mayContain: monitoredServices
+mayContain: monitoringAvailabilityStyle
+mayContain: monitoringAvailabilityWindow
+mayContain: monitoringCachedViaMail
+mayContain: monitoringCachedViaRPC
+mayContain: monitoringMailUpdateInterval
+mayContain: monitoringMailUpdateUnits
+mayContain: monitoringRPCUpdateInterval
+mayContain: monitoringRPCUpdateUnits
+mayContain: ms-Exch-Policy-List Attribute
+mayContain: ms-Exch-Policy-Option-List Attribute
+mayContain: promoExpiration
+mayContain: securityProtocol
+mayContain: trackingLogPathName
+mayContain: type
+
+
+
+#
+# Container Class
+# Used to hold other classes
+dn: CN=Container,${SCHEMADN}
+changetype: modify
+add: auxiliaryClass
+add: possSuperiors
+add: mayContain
+auxiliaryClass: msExchBaseClass
+possSuperiors: protocolCfgSharedServer
+mayContain: containerInfo
+mayContain: msExchPolicyList
+mayContain: msExchTemplateRDNs
+mayContain: x500RDN
+mayContain: msExchExportContainersBL
+
+
+
+#
+# Domain-DNS
+# Windows NT domain with DNS-based (DC=) naming. 
+#
+dn: CN=Domain-DNS,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: msExchPolicyList
+
+
+
+#
+# Group
+# Stores a list of user names. Used to apply security principals on
+# resources.
+#
+dn: CN=Group,${SCHEMADN}
+changetype: modify
+add: auxiliaryClass
+add: mayContain
+auxiliaryClass: msExchCustomAttributes
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchIMRecipient
+mayContain: hideDLMembership
+mayContain: oOFReplyToOriginator
+mayContain: reportToOriginator
+mayContain: reportToOwner
+mayContain: dLMemberRule
+mayContain: owner
+mayContain: msExchOriginatingForest
+
+
+
+#
+# Mail-Recipient
+# Stores e-mail configuration information.
+#
+dn: CN=Mail-Recipient,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: assistant
+mayContain: altRecipient
+mayContain: authOrig
+mayContain: autoReplyMessage
+mayContain: delivContLength
+mayContain: deliverAndRedirect
+mayContain: dLMemRejectPerms
+mayContain: dLMemSubmitPerms
+mayContain: enabledProtocols
+mayContain: msExchExpansionServerName
+mayContain: expirationTime
+mayContain: folderPathname
+mayContain: formData
+mayContain: forwardingAddress
+mayContain: homeMTA
+mayContain: internetEncoding
+mayContain: languageCode
+mayContain: language
+mayContain: mailNickname
+mayContain: mAPIRecipient
+mayContain: pOPCharacterSet
+mayContain: pOPContentFormat
+mayContain: protocolSettings
+mayContain: publicDelegates
+mayContain: replicationSensitivity
+mayContain: securityProtocol
+mayContain: submissionContLength
+mayContain: targetAddress
+mayContain: unauthOrig
+mayContain: dnQualifier
+mayContain: msExchMailboxSecurityDescriptor
+mayContain: msExchMasterAccountSid
+mayContain: importedFrom
+mayContain: versionNumber
+mayContain: msExchPreviousAccountSid
+mayContain: msExchCustomProxyAddresses
+mayContain: dLMemDefault
+mayContain: mail
+mayContain: deliveryMechanism
+mayContain: extensionData
+mayContain: delivExtContTypes
+mayContain: msExchFBURL
+mayContain: msExchRecipLimit
+mayContain: altRecipientBL
+mayContain: authOrigBL
+mayContain: dLMemRejectPermsBL
+mayContain: dLMemSubmitPermsBL
+mayContain: publicDelegatesBL
+mayContain: unauthOrigBL
+mayContain: msExchPoliciesExcluded
+mayContain: msExchPoliciesIncluded
+mayContain: msExchPolicyEnabled
+mayContain: msExchPolicyOptionList
+mayContain: msExchProxyCustomProxy 
+mayContain: msExchUserAccountControl 
+mayContain: msExchMailboxFolderSet 
+mayContain: msExchRequireAuthToSendTo 
+
+
+
+#
+# NTDS-DSA
+# Represents the Active Directory DSA process on the server.
+#
+dn: CN=NTDS-DSA,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: deliveryMechanism
+mayContain: diagnosticRegKey
+
+
+
+#
+# Organizational-Person
+# Contains organizational information about a user.
+#
+dn: CN=Organizational-Person,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: employeeType
+mayContain: businessRoles
+mayContain: telephoneAssistant
+mayContain: personalPager
+mayContain: employeeNumber
+
+
+
+
+#
+# Organizational-Unit
+# A container for storing users, computers, and other account objects.
+#
+dn: CN=Organizational-Unit,${SCHEMADN}
+changetype: modify
+add: auxiliaryClass
+add: mayContain
+auxiliaryClass: msExchBaseClass
+mayContain: msExchPolicyList
+
+
+
+#
+# Sam-Domain
+# Auxiliary class holding common properties for Windows NT domains.
+#
+dn: CN=Sam-Domain,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: msExchAddGroupsToToken
+
+
+
+#
+# Server
+# Represents a server computer within a site.
+#
+dn: CN=Server,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: activationSchedule
+mayContain: activationStyle
+mayContain: type
+mayContain: networkAddress
+
+
+#
+# Site
+# A container for storing server objects. Represents a physical
+# location containing computers. Used to manage replication.
+#
+dn: CN=Site,${SCHEMADN}
+changetype: modify
+add: mayContain
+mayContain: msExchConferenceZoneBL
+mayContain: msExchMCUHostsSitesBL
+
+
+#
+# User
+# Used to store information about an employee or contractor who works
+# for an organization. Can also be applied to long-term visitors.
+#
+dn: CN=User,${SCHEMADN}
+changetype: modify
+add: auxiliaryClass
+add: possSuperiors
+add: mayContain
+auxiliaryClass: msExchCustomAttributes
+auxiliaryClass: msExchMailStorage
+auxiliaryClass: msExchBaseClass
+auxiliaryClass: msExchMultiMediaUser
+auxiliaryClass: msExchCertificateInformation
+auxiliaryClass: msExchIMRecipient
+auxiliaryClass: msExchOmaUser
+possSuperiors: msExchSystemObjectsContainer
+mayContain: msExchQueryBaseDN
+mayContain: msExchControllingZone
+mayContain: msExchResourceGUID
+mayContain: msExchResourceProperties
+mayContain: msExchConferenceMailboxBL
+mayContain: kMServer
+mayContain: msExchIMAPOWAURLPrefixOverride
+mayContain: msExchOriginatingForest
+
+
+
+##################################################################
+# Attributes
+##################################################################
+
+
+#
+# Address
+# The user's address
+#
+dn: CN=Address,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+#
+# Admin-Display-Name
+# The name to be displayed on administrator screens.
+#
+dn: CN=Admin-Display-Name,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+#
+# Attribute-Syntax
+# The object identifier (OID) for the syntax for this attribute.
+#
+dn: CN=Attribute-Syntax,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Comment
+# The user's comments. Can be a null string.
+#
+dn: CN=Comment,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Company
+# The user's company name.
+#
+dn: CN=Company,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Department
+# Contains the name for the department in which the user works.
+#
+dn: CN=Department,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Display-Name-Printable
+# The name displayed in the address book for a particular
+# user. Usually the combination of the user's first name, middle
+# initial, and last name.
+#
+dn: CN=Display-Name-Printable,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# E-mail-Addresses
+# The list of e-mail addresses for a contact.
+#
+dn: CN=E-mail-Addresses,${SCHEMADN}
+changetype: modify
+replace: searchFlags
+searchFlags: 5
+
+
+
+#
+# Facsimile-Telephone-Number
+# Contains the telephone number of the user's business fax machine.
+#
+dn: CN=Facsimile-Telephone-Number,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Garbage-Coll-Period
+# Located on the CN=Directory Service,CN=Windows
+# NT,CN=Services,CN=Configuration,... object. Represents the period in
+# hours between Directory Service (DS) garbage collection runs.
+#
+dn: CN=Garbage-Coll-Period,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+replace: searchFlags
+isMemberOfPartialAttributeSet: TRUE
+searchFlags: 16
+
+
+
+#
+# Given-Name
+# Contains the given name (first name) of the user. 
+#
+#dn: CN=Given-Name,${SCHEMADN}
+#changetype: modify
+#add: isMemberOfPartialAttributeSet
+#isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Initials
+# Contains the initials for parts of the user's full name. May be used
+# as the middle initial in the Windows Address Book.
+#
+dn: CN=Initials,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Managed-By
+# The distinguished name of the user that is assigned to manage this
+# object.
+#
+dn: CN=Managed-By,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Network-Address
+# The TCP/IP address for a network segment. Also called the subnet
+# address.
+#
+dn: CN=Network-Address,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# NT-Mixed-Domain
+# Indicates that the domain is in native mode or mixed mode. Found in
+# the domainDNS (head) object for the domain.
+#
+dn: CN=NT-Mixed-Domain,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# OM-Syntax
+# A number representing the OM type for the attribute. 
+#
+dn: CN=OM-Syntax,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Fax-Other
+# A list of alternate facsimile numbers. 
+#
+dn: CN=Phone-Fax-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Home-Other
+# A list of alternate home phone numbers.
+#
+dn: CN=Phone-Home-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Mobile-Other
+# A list of alternate cell phone numbers.
+#
+dn: CN=Phone-Mobile-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Mobile-Primary
+# The primary cell phone number
+#
+dn: CN=Phone-Mobile-Primary,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Office-Other
+# A list of alternate office phone numbers
+#
+dn: CN=Phone-Office-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Pager-Other
+# A list of alternate pager numbers
+#
+dn: CN=Phone-Pager-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Phone-Pager-Primary
+# The primary pager number
+#
+dn: CN=Phone-Pager-Primary,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Physical-Delivery-Office-Name
+# Contains the office location of the user's place of business.
+#
+dn: CN=Physical-Delivery-Office-Name,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Postal-Code
+# The postal or zip code for mail delivery. 
+#
+dn: CN=Postal-Code,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Post-Office-Box
+# The post office box number for this object. 
+#
+dn: CN=Post-Office-Box,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Proxy-Addresses
+# Address by which a Microsoft Exchange Server recipient object is
+# recognized in a foreign mail system. Required not just for users,
+# but for all recipient objects such as custom recipients and
+# distribution lists.
+#
+dn: CN=Proxy-Addresses,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+replace: searchFlags
+isMemberOfPartialAttributeSet: TRUE
+searchFlags: 13
+
+
+
+#
+# Show-In-Address-Book
+# 
+dn: CN=Show-In-Address-Book,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Sub-Class-Of
+# The parent class of a class
+#
+dn: CN=Sub-Class-Of,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Text-Country
+# The country/region in which the user is located.
+#
+dn: CN=Text-Country,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# Text-Encoded-Or-Address
+#
+dn: CN=Text-Encoded-Or-Address,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+replace: searchFlags
+replace: attributeSecurityGuid
+isMemberOfPartialAttributeSet: TRUE
+searchFlags: 1
+attributeSecurityGuid: e48d0154-bcf8-11d1-8702-00c04fb96050
+
+
+
+#
+# Title
+# Contains the user's job title. Property commonly used to indicate
+# the formal job title, such as Senior Programmer, rather than
+# occupational class, such as programmer. Not typically used for
+# suffix titles such as Esq. or D.D.S.
+#
+dn: CN=Title,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+replace: searchFlags
+isMemberOfPartialAttributeSet: TRUE
+searchFlags: 16
+
+
+
+#
+# Version-Number
+# A general-purpose version number.
+#
+dn: CN=Version-Number,${SCHEMADN}
+changetype: modify
+replace: searchFlags
+searchFlags: 8
+
+
+
+#
+# WWW-Home-Page
+# The primary Web page
+#
+dn: CN=WWW-Home-Page,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+
+
+
+#
+# WWW-Page-Other
+# A list of alternate Web pages
+#
+dn: CN=WWW-Page-Other,${SCHEMADN}
+changetype: modify
+add: isMemberOfPartialAttributeSet
+isMemberOfPartialAttributeSet: TRUE
+

Added: trunk/openchange/setup/AD/prefixMap.txt
===================================================================
--- trunk/openchange/setup/AD/prefixMap.txt	                        (rev 0)
+++ trunk/openchange/setup/AD/prefixMap.txt	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,39 @@
+0:2.5.4
+1:2.5.6
+2:1.2.840.113556.1.2
+3:1.2.840.113556.1.3
+4:2.16.840.1.101.2.2.1
+5:2.16.840.1.101.2.2.3
+6:2.16.840.1.101.2.1.5
+7:2.16.840.1.101.2.1.4
+8:2.5.5
+9:1.2.840.113556.1.4
+10:1.2.840.113556.1.5
+19:0.9.2342.19200300.100
+20:2.16.840.1.113730.3
+21:0.9.2342.19200300.100.1
+22:2.16.840.1.113730.3.1
+23:1.2.840.113556.1.5.7000
+24:2.5.21
+25:2.5.18
+26:2.5.20
+11:1.2.840.113556.1.4.260
+12:1.2.840.113556.1.5.56
+13:1.2.840.113556.1.4.262
+14:1.2.840.113556.1.5.57
+15:1.2.840.113556.1.4.263
+16:1.2.840.113556.1.5.58
+17:1.2.840.113556.1.5.73
+18:1.2.840.113556.1.4.305
+27:1.3.6.1.4.1.1466.101.119
+28:2.16.840.1.113730.3.2
+29:1.3.6.1.4.1.250.1
+30:1.2.840.113549.1.9
+31:0.9.2342.19200300.100.4
+32:1.3.6.1.4.1.7165.4.1
+33:1.3.6.1.4.1.7165.4.2
+34:1.2.840.113556.1.5.7000.62
+35:1.2.840.113556.1.4.7000.102
+36:1.2.840.113556.1.6.20.1
+37:1.2.840.113556.1.6.20.2
+

Added: trunk/openchange/setup/AD/provision_schema_basedn_modify.ldif
===================================================================
--- trunk/openchange/setup/AD/provision_schema_basedn_modify.ldif	                        (rev 0)
+++ trunk/openchange/setup/AD/provision_schema_basedn_modify.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,14 @@
+###############################
+# Schema Naming Context
+###############################
+dn: ${SCHEMADN}
+changetype: modify
+replace: fSMORoleOwner
+fSMORoleOwner: CN=NTDS Settings,${SERVERDN}
+-
+replace: objectVersion
+objectVersion: 30
+-
+replace: prefixMap
+prefixMap:: ${PREFIXMAP_B64}
+

Added: trunk/openchange/setup/openchange_newuser
===================================================================
--- trunk/openchange/setup/openchange_newuser	                        (rev 0)
+++ trunk/openchange/setup/openchange_newuser	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,74 @@
+#!/usr/bin/python
+# OpenChange provision script
+#
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+import optparse
+import os,sys
+
+# To allow running from the source directory
+sys.path.append("python")
+
+from openchange import find_samba_python_path
+samba_path = find_samba_python_path()
+if samba_path is not None:
+	sys.path.append(samba_path)
+
+import samba
+import samba.getopt as options
+from samba.auth import system_session
+import openchange.provision as openchange
+
+parser = optparse.OptionParser("openchange_newuser [options] <username>")
+
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option("--enable", action="store_true", metavar="ENABLE",
+		  help="Enable access to OpenChange server")
+parser.add_option("--disable", action="store_true", metavar="DISABLE",
+		  help="Disable access to OpenChange server")
+parser.add_option("--create", action="store_true", metavar="CREATE",
+		  help="Create the OpenChange user account")
+parser.add_option("--mailbox", action="store_true", metavar="MAILBOX",
+		  help="Create the OpenChange user mailbox")
+
+opts, args = parser.parse_args()
+
+if len(args) == 0:
+	parser.print_usage()
+	sys.exit(1)
+
+lp = sambaopts.get_loadparm()
+creds = credopts.get_credentials(lp)
+
+def setup_path(*args):
+	return os.path.join(os.path.dirname(__file__), *args)
+
+if opts.enable == True:
+	openchange.accountcontrol(lp, creds, username=args[0], value=0)
+
+if opts.disable == True:
+	openchange.accountcontrol(lp, creds, username=args[0], value=2)
+
+if opts.create == True:
+	openchange.newuser(lp, creds, username=args[0])
+
+if opts.mailbox == True:
+	openchange.newmailbox(lp, username=args[0], firstorg=None, firstou=None)


Property changes on: trunk/openchange/setup/openchange_newuser
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/setup/openchange_provision
===================================================================
--- trunk/openchange/setup/openchange_provision	                        (rev 0)
+++ trunk/openchange/setup/openchange_provision	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+# OpenChange provision script
+#
+# Copyright (C) Jelmer Vernooij <jelmer at openchange.org> 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/>.
+#
+
+import optparse
+import os,sys
+
+# To allow running from the source directory
+sys.path.append("python")
+
+from openchange import find_samba_python_path
+samba_path = find_samba_python_path()
+if samba_path is not None:
+	sys.path.append(samba_path)
+
+import samba
+import samba.getopt as options
+from samba.auth import system_session
+import openchange.provision as openchange
+
+parser = optparse.OptionParser("openchange_provision [options]")
+
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option("--firstorg", type="string", metavar="FIRSTORG", 
+                  help="set OpenChange First Organization (otherwise First Organization)")
+parser.add_option("--firstou", type="string", metavar="FIRSTOU", 
+                  help="set OpenChange First Organization Unit (otherwise First Organization Unit)")
+parser.add_option("--openchangedb", action="store_true", help="Initialize OpenChange dispatcher database")
+
+opts,args = parser.parse_args()
+if len(args) != 0:
+    parser.print_usage()
+    sys.exit(1)
+    
+lp = sambaopts.get_loadparm()
+creds = credopts.get_credentials(lp)
+
+def setup_path(*args):
+    return os.path.join(os.path.dirname(__file__), *args)
+
+if not opts.openchangedb:
+	openchange.provision(setup_path, lp, creds, firstorg=opts.firstorg, firstou=opts.firstou)
+else:
+	openchange.openchangedb_provision(lp, firstorg=opts.firstorg, firstou=opts.firstou)


Property changes on: trunk/openchange/setup/openchange_provision
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/setup/openchangedb/oc_provision_openchange_init.ldif
===================================================================
--- trunk/openchange/setup/openchangedb/oc_provision_openchange_init.ldif	                        (rev 0)
+++ trunk/openchange/setup/openchangedb/oc_provision_openchange_init.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,9 @@
+dn: @OPTIONS
+checkBaseOnSearch: TRUE
+
+dn: @INDEXLIST
+ at IDXATTR: cn
+
+dn: @ATTRIBUTES
+cn: CASE_INSENSITIVE
+dn: CASE_INSENSITIVE
\ No newline at end of file

Added: trunk/openchange/setup/openchangedb/oc_provision_openchange_mailbox.ldif
===================================================================
--- trunk/openchange/setup/openchangedb/oc_provision_openchange_mailbox.ldif	                        (rev 0)
+++ trunk/openchange/setup/openchangedb/oc_provision_openchange_mailbox.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,4 @@
+dn: CN=${FOLDER_IDX},${USERDN}
+cn: ${FOLDER_IDX}
+fid: ${FOLDER_IDX}
+name: ${NAME}

Added: trunk/openchange/setup/profiles/oc_profiles_init.ldif
===================================================================
--- trunk/openchange/setup/profiles/oc_profiles_init.ldif	                        (rev 0)
+++ trunk/openchange/setup/profiles/oc_profiles_init.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,7 @@
+dn: @ATTRIBUTES
+dnsDomain: CASE_INSENSITIVE
+cn: CASE_INSENSITIVE
+dc: CASE_INSENSITIVE
+name: CASE_INSENSITIVE
+dn: CASE_INSENSITIVE
+objectClass: CASE_INSENSITIVE

Added: trunk/openchange/setup/profiles/oc_profiles_schema.ldif
===================================================================
--- trunk/openchange/setup/profiles/oc_profiles_schema.ldif	                        (rev 0)
+++ trunk/openchange/setup/profiles/oc_profiles_schema.ldif	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,219 @@
+#
+# Exchange organization
+#
+dn: CN=Organization
+objectClass: top
+objectClass: attributeSchema
+name: Organization
+CN: Organization
+description: Exchange Organization
+isSingleValued: TRUE
+
+#
+# Exchange organization unit
+#
+dn: CN=OrganizationUnit
+objectClass: top
+objectClass: attributeSchema
+name: OrganizationUnit
+CN: OrganizationUnit
+description: Exchange Organization Unit
+isSingleValued: TRUE
+
+#
+# User display name
+#
+dn: CN=DisplayName
+objectClass: top
+objectClass: attributeSchema
+name: DisplayName
+CN: DisplayName
+description: User display name
+isSingleValued: TRUE
+
+#
+# Office Telephone Number
+#
+dn: CN=OfficeTelephoneNumber
+objectClass: top
+objectClass: attributeSchema
+name: OfficeTelephoneNumber
+CN: OfficeTelephoneNumber
+description: Office Telephone Number
+isSingleValued: TRUE
+
+#
+# Office Location
+#
+dn: CN=OfficeLocation
+objectClass: top
+objectClass: attributeSchema
+name: OfficeLocation
+CN: OfficeLocation
+description: Office Location
+isSingleValued: TRUE
+
+#
+# User title
+#
+dn: CN=Title
+objectClass: top
+objectClass: attributeSchema
+name: Title
+CN: Title
+description: User Title
+isSingleValued: TRUE
+
+#
+# Company Name
+#
+dn: CN=CompanyName
+objectClass: top
+objectClass: attributeSchema
+name: CompanyName
+CN: CompanyName
+description: Company Name
+isSingleValued: TRUE
+
+#
+# User account name
+#
+dn: CN=AccountName
+objectClass: top
+objectClass: attributeSchema
+name: AccountName
+CN: AccountName
+description: User account name
+isSingleValued: TRUE
+
+#
+# User email address
+#
+dn: CN=EmailAddress
+objectClass: top
+objectClass: attributeSchema
+name: EmailAddress
+CN: EmailAddress
+description: User email address
+isSingleValued: TRUE
+
+#
+# Email Address type
+#
+dn: CN=AddrType
+objectClass: top
+objectClass: attributeSchema
+name: AddrType
+CN: AddrType
+description: User Email Address Type
+isSingleValued: TRUE
+
+#
+# Entry ID
+#
+dn: CN=EntryID
+objectClass: top
+objectClass: attributeSchema
+name: EntryID
+CN: ENtryID
+description: Unique identifier for the given object
+isSingleValued: TRUE
+
+#
+# Object Type
+#
+dn: CN=ObjectType
+objectClass: top
+objectClass: attributeSchema
+name: ObjectType
+CN: ObjectType
+description: Object Type
+isSingleValued: TRUE
+
+#
+# Home MDB
+#
+dn: CN=HomeMDB
+objectClass: top
+objectClass: attributeSchema
+name: HomeMDB
+CN: HomeMDB
+description: Path to the user Mailbox
+isSingleValued: TRUE
+
+#
+# User Proxy addresses for different connectors
+#
+dn: CN=ProxyAddress
+objectClass: top
+objectClass: attributeSchema
+name: ProxyAddress
+CN: ProxyAddress
+description: Proxy addresses for other connectors
+isSingleValued: FALSE
+
+#
+# PR_DEFAULT_PROFILE
+#
+dn: CN=PR_DEFAULT_PROFILE
+objectClass: top
+objectClass: attributeSchema
+name: PR_DEFAULT_PROFILE
+CN: PR_DEFAULT_PROFILE
+description: Indicates if the profile is the default one
+isSingleValued: TRUE
+
+########################################################
+# Attributes for Exchange Servers containers
+########################################################
+
+#
+# Exchange server binding strings
+#
+dn: CN=NetworkAddress
+objectClass: top
+objectClass: attributeSchema
+name: NetworkAddress
+CN: NetworkAddress
+description: binding string we can use to connect to the Exchange Server
+isSingleValued: FALSE
+
+#
+# Container flags
+#
+dn: CN=ContainerFlags
+objectClass: top
+objectClass: attributeSchema
+name: ContainerFlags
+CN: ContainerFlags
+isSingleValued: TRUE
+
+#
+# Depth
+#
+dn: CN=Depth
+objectClass: top
+objectClass: attributeSchema
+name: Depth
+CN: Depth
+isSingleValued: TRUE
+
+#
+# AB Container ID
+#
+dn: CN=ABContainerID
+objectClass: top
+objectClass: attributeSchema
+name: ABContainerID
+CN: ABContainerID
+isSingleValued: TRUE
+
+#
+# AB is Master
+#
+dn: CN=ABIsMaster
+objectClass: top
+objectClass: attributeSchema
+name: ABIsMaster
+CN: ABIsMaster
+isSingleValued: TRUE
\ No newline at end of file

Added: trunk/openchange/swig/perl/Makefile
===================================================================
--- trunk/openchange/swig/perl/Makefile	                        (rev 0)
+++ trunk/openchange/swig/perl/Makefile	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,63 @@
+#Makefile for libmapi Perl bindings
+#Writen by Julien Kerihuel <j.kerihuel at openchange.org>, 2007.
+
+include ../../config.mk
+
+top_builddir = ../..
+
+CFLAGS+=`perl -MExtUtils::Embed -e ccopts` -D_SAMBA_UTIL_H_
+
+# Portability hack...
+CFLAGS+=-Duint_t="unsigned int" 
+
+CFLAGS+=-I$(top_builddir)
+
+all::	swig_mapitags.h 		\
+	swig_mapicodes.h		\
+	mapi_wrap.c			\
+	mapi.$(SHLIBEXT)
+
+clean::
+	rm -f *.o
+	rm -f *.pm
+	rm -f mapi_wrap.c
+	rm -f swig_mapicodes.h swig_mapitags.h
+	rm -f mapi.$(SHLIBEXT)
+
+distclean:: clean
+	rm -f *.so
+
+install:: all
+	cp mapi.pm $(PERL5DIR)
+	cp mapi.so $(PERL5DIR)
+
+uninstall::
+	rm -f $(PERL5DIR)/mapi.pm
+	rm -f $(PERL5DIR)/mapi.so
+
+mapi_wrap.c: mapi.i
+	@echo "Swigify $<"
+	@$(SWIG) -Wall -Werror -perl5 $<
+
+swig_mapitags.h:
+	@echo "Generating Headers (swig_mapitags.h)"
+	@$(top_builddir)/libmapi/conf/mparse.pl --parser=swig_mapitags --outputdir=./ $(top_builddir)/libmapi/conf/mapi-properties
+
+swig_mapicodes.h:
+	@echo "Generating Headers (swig_mapicodes.h)"
+	@$(top_builddir)/libmapi/conf/mparse.pl --parser=swig_mapicodes --outputdir=./ $(top_builddir)/libmapi/conf/mapi-codes
+
+.SUFFIXES: .po
+
+.c.po:
+	@echo "Compiling $< with -fPIC"
+	@$(CC) $(CFLAGS) -DDEFAULT_LDIF=\"$(DESTDIR)$(datadir)/setup\" -fPIC -c $< -o $@
+
+mapi.$(SHLIBEXT): 	mapi_wrap.po				\
+			lwmapi.po				\
+			../../libmapi/utf8_convert.yy.po	\
+			../../libmapi/*.po			\
+			../../gen_ndr/*.po			\
+			../../*.po
+	@echo "Compiling $<"
+	@$(CC) -o $@ $(DSOOPT) $^ $(LIBS)

Added: trunk/openchange/swig/perl/lwmapi.c
===================================================================
--- trunk/openchange/swig/perl/lwmapi.c	                        (rev 0)
+++ trunk/openchange/swig/perl/lwmapi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,45 @@
+/*
+   OpenChange Perl bindings wrappers
+
+   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/>.
+ */
+
+#include <stdint.h>
+
+typedef uint64_t NTTIME;
+struct ipv4_addr;
+
+#include <libmapi/libmapi.h>
+
+/**
+ * Note: Most of these wrapper functions are useless and are just here
+ * cause we don't use swig properly.
+ */
+
+void lw_dumpdata(void)
+{
+	global_mapi_ctx->dumpdata = true;
+}
+
+const uint64_t *lw_getID(struct SRowSet *SRowSet, uint32_t ulPropTag, 
+			 uint32_t idx)
+{
+	struct SPropValue *lpProp;
+	uint64_t *id;
+
+	lpProp = get_SPropValue_SRow((&SRowSet->aRow[idx]), ulPropTag);
+	return get_SPropValue(lpProp, ulPropTag);
+}

Added: trunk/openchange/swig/perl/mapi.i
===================================================================
--- trunk/openchange/swig/perl/mapi.i	                        (rev 0)
+++ trunk/openchange/swig/perl/mapi.i	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,124 @@
+/*
+   OpenChange MAPI library bindings for Perl
+
+   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/>.
+*/
+
+%module mapi
+%{
+typedef uint64_t NTTIME;
+struct ipv4_addr;
+
+#include <libmapi/libmapi.h>
+#include <libmapi/proto.h>
+
+%}
+
+%include "typemaps.i"
+%include "cstring.i"
+%include "cpointer.i"
+%include "carrays.i"
+%import "stdint.i"
+
+%include "../../libmapi/mapidefs.h"
+%include "swig_mapitags.h"
+%include "swig_mapicodes.h"
+
+%nodefaultctor SPropTagArray;
+%nodefaultdtor SPropTagArray;
+
+%array_functions(uint32_t,aulPropTag);
+struct SPropTagArray {
+       uint32_t	*aulPropTag;
+       uint32_t	cValues;
+};
+
+%inline %{
+	struct SPropTagArray *new_SPropTagArray(int nb) 
+	{
+		struct SPropTagArray *result = 0;
+
+		result = (struct SPropTagArray *)(struct SPropTagArray *) calloc(1, sizeof(struct SPropTagArray));
+		result->cValues = nb;
+		result->aulPropTag = new_aulPropTag(nb);
+		      
+		return result;
+	}
+
+	void delete_SPropTagArray(struct SPropTagArray *s)
+	{
+		delete_aulPropTag(s->aulPropTag);
+		free((struct SPropTagArray *)s);     		
+	}
+%}
+
+
+%nodefaultctor mapi_object;
+%nodefaultdtor mapi_object;
+%inline %{
+	mapi_object_t *new_mapi_object()
+	{
+		mapi_object_t	*obj;
+
+		obj = malloc(sizeof(mapi_object_t));
+		mapi_object_init(obj);
+
+		return obj;
+	}
+
+	static void delete_mapi_object(mapi_object_t *obj)
+	{
+		mapi_object_release(obj);
+		free((mapi_object_t *)obj);
+	}	
+%}
+
+struct SRowSet {
+	uint32_t cRows;
+	struct SRow *aRow;
+};
+
+%pointer_functions(uint64_t, int64);
+%pointer_functions(uint32_t, int32);
+%pointer_functions(struct mapi_SPropValue_array, mapi_SPropValue_array);
+%pointer_functions(struct mapi_session *, mapi_session_t);
+
+extern void		lw_dumpdata(void);
+extern uint64_t		*lw_getID(struct SRowSet *SRowSet, uint32_t tag, uint32_t idx);
+
+extern uint32_t		MAPIInitialize(const char *profile);
+extern void		MAPIUninitialize(void);
+extern uint32_t		MapiLogonEx(struct mapi_session **session, char *profile, char *password);
+extern uint32_t		GetLastError(void);
+extern void		mapi_errstr(const char *function, uint32_t mapi_code);
+
+%cstring_output_allocate(char **s, $1);
+extern uint32_t		GetDefaultProfile(const char **s);
+
+extern uint32_t		GetDefaultFolder(mapi_object_t *obj, uint64_t *folder, const uint32_t folder_id);
+extern uint32_t		OpenFolder(mapi_object_t *obj, uint64_t folder, mapi_object_t *obj2);
+extern uint32_t		GetFolderItemsCount(mapi_object_t *obj, uint32_t *unread, uint32_t *total);
+extern uint32_t		GetContentsTable(mapi_object_t *obj, mapi_object_t *obj2, uint8_t TableFlags, uint32_t *RowCount);
+extern uint32_t		SetColumns(mapi_object_t *obj, struct SPropTagArray *lpProps);
+extern uint32_t		QueryRows(mapi_object_t *obj, uint32_t nb, uint32_t flg, struct SRowSet *SRowSet);
+extern uint32_t		QueryPosition(mapi_object_t *obj, uint32_t *Numerator, uint32_t *Denominator);
+extern uint32_t		OpenMsgStore(struct mapi_session *session, mapi_object_t *obj);
+extern uint32_t		OpenMessage(mapi_object_t *obj, uint64_t fid, uint64_t mid, mapi_object_t *obj_msg, uint8_t flag);
+extern uint32_t		GetPropsAll(mapi_object_t *obj, struct mapi_SPropValue_array *mlpProps);
+
+extern void		mapidump_SPropTagArray(struct SPropTagArray *lpProps);
+extern void		mapidump_SRowSet(struct SRowSet *SRowSet, const char *sep);
+extern void		mapidump_message(struct mapi_SPropValue_array *mlpProps, char *);

Added: trunk/openchange/swig/perl/tests/fetchmail.pl
===================================================================
--- trunk/openchange/swig/perl/tests/fetchmail.pl	                        (rev 0)
+++ trunk/openchange/swig/perl/tests/fetchmail.pl	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,132 @@
+#!/usr/bin/perl -w
+
+##############################################
+# Perl bindings test suite:
+#
+# o Fetch emails from Exchange Server
+#
+# Copyright Julien Kerihuel 2007.
+# <j.kerihuel at openchange.org>
+#
+# released under GNU GPL
+
+
+use strict;
+use mapi;
+
+package mapi;
+
+my $retval;
+
+sub mapi_init()
+{
+    my $profdb;
+    my $profname;
+    my $password = ();
+    my $flag = 0;
+    my $session = new_mapi_session_t();
+
+    print "Initializing MAPI\n";
+    $profdb = sprintf("%s/.openchange/profiles.ldb", $ENV{HOME});
+
+    # Initialize MAPI library
+    $retval = MAPIInitialize($profdb);
+    mapi_errstr("MAPIInitialize", GetLastError());
+
+    # Activate MAPI decoding
+    #lw_dumpdata();
+
+    # Retrieve default profile name
+    ($retval, $profname) = GetDefaultProfile();
+    mapi_errstr("GetDefaultProfile", GetLastError());
+
+    $retval = MapiLogonEx($session, $profname, $password);
+    mapi_errstr("MapiLogonEx", $retval);
+
+    return $session;
+}
+
+sub mapi_finalize()
+{
+    MAPIUninitialize();
+}
+
+sub mapi_fetchmail($)
+{
+    my $session = shift;
+    my $inbox_id = new_int64();
+    my $cRows;
+    my $count = new_int32();
+    my $unread = new_int32();
+    my $total = new_int32();
+    my $SRowSet = new mapi::SRowSet();
+
+    ## Open Message Store
+    my $obj_store = new_mapi_object();
+    $retval = OpenMsgStore(mapi_session_t_value($session), $obj_store);
+    mapi_errstr("OpenMsgStore", GetLastError());
+
+    ## Open Inbox
+    my $obj_inbox = new_mapi_object();
+    $retval = GetDefaultFolder($obj_store, $inbox_id, $mapi::olFolderInbox);
+    mapi_errstr("GetDefaultFolder", GetLastError());
+
+    $retval = OpenFolder($obj_store, int64_value($inbox_id), $obj_inbox);
+    mapi_errstr("OpenFolder", GetLastError());
+
+    ## Count messages
+    $retval = GetFolderItemsCount($obj_inbox, $unread, $total);
+    mapi_errstr("GetFolderItemsCount", GetLastError());
+
+    print "Mailbox:\n";
+    print "\t => Unread(" . int32_value($unread) . ")\n";
+    print "\t => Total(" . int32_value($total) . ")\n";
+
+    ## GetContentsTable
+    my $obj_table = new_mapi_object();
+    $retval = GetContentsTable($obj_inbox, $obj_table, 0, $count);
+    mapi_errstr("GetContentsTable", GetLastError());
+
+    ## Prepare MAPI table creation
+    my $SPropTagArray = new_SPropTagArray(5);
+    aulPropTag_setitem($SPropTagArray->{aulPropTag}, 0, $mapi::PR_FID);
+    aulPropTag_setitem($SPropTagArray->{aulPropTag}, 1, $mapi::PR_MID);
+    aulPropTag_setitem($SPropTagArray->{aulPropTag}, 2, $mapi::PR_INST_ID);
+    aulPropTag_setitem($SPropTagArray->{aulPropTag}, 3, $mapi::PR_INSTANCE_NUM);
+    aulPropTag_setitem($SPropTagArray->{aulPropTag}, 4, $mapi::PR_SUBJECT);
+
+    $retval = SetColumns($obj_table, $SPropTagArray);
+    delete_SPropTagArray($SPropTagArray);
+    mapi_errstr("SetColumns", GetLastError());
+
+    ## Get table rows
+    while (($retval = QueryRows($obj_table, int32_value($count), 0, $SRowSet)) != $mapi::MAPI_E_NOT_FOUND 
+	   && $SRowSet->{cRows})
+    {
+
+	for (my $i = 0; $i != $SRowSet->{cRows}; $i++) {
+
+	    my $fid = int64_value(lw_getID($SRowSet, $mapi::PR_FID, $i));
+	    my $mid = int64_value(lw_getID($SRowSet, $mapi::PR_MID, $i));
+	    
+	    my $obj_message = new_mapi_object();
+	    $retval = OpenMessage($obj_store, $fid, $mid, $obj_message, $mapi::MAPI_CREATE|$mapi::MAPI_MODIFY);
+	    
+	    if (GetLastError() != $mapi::MAPI_E_NOT_FOUND) {
+		my $props = new_mapi_SPropValue_array();
+		
+		$retval = GetPropsAll($obj_message, $props);
+		mapidump_message($props, "");
+		delete_mapi_object($obj_message);
+	    }
+	}
+    }
+
+    delete_mapi_object($obj_table);
+    delete_mapi_object($obj_inbox);
+    delete_mapi_object($obj_store);
+}
+
+my $session = &mapi_init();
+&mapi_fetchmail($session);
+&mapi_finalize();


Property changes on: trunk/openchange/swig/perl/tests/fetchmail.pl
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/testprogs/blackbox/subunit.sh
===================================================================
--- trunk/openchange/testprogs/blackbox/subunit.sh	                        (rev 0)
+++ trunk/openchange/testprogs/blackbox/subunit.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,67 @@
+#
+#  subunit.sh: shell functions to report test status via the subunit protocol.
+#  Copyright (C) 2006  Robert Collins <robertc at robertcollins.net>
+#  Copyright (C) 2008  Jelmer Vernooij <jelmer at samba.org>
+#
+#  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 2 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, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+
+subunit_start_test () {
+  # emit the current protocol start-marker for test $1
+  echo "test: $1"
+}
+
+
+subunit_pass_test () {
+  # emit the current protocol test passed marker for test $1
+  echo "success: $1"
+}
+
+
+subunit_fail_test () {
+  # emit the current protocol fail-marker for test $1, and emit stdin as
+  # the error text.
+  # we use stdin because the failure message can be arbitrarily long, and this
+  # makes it convenient to write in scripts (using <<END syntax.
+  echo "failure: $1 ["
+  cat -
+  echo "]"
+}
+
+
+subunit_error_test () {
+  # emit the current protocol error-marker for test $1, and emit stdin as
+  # the error text.
+  # we use stdin because the failure message can be arbitrarily long, and this
+  # makes it convenient to write in scripts (using <<END syntax.
+  echo "error: $1 ["
+  cat -
+  echo "]"
+}
+
+testit () {
+	name="$1"
+	shift
+	cmdline="$*"
+	subunit_start_test "$name"
+	output=`$cmdline 2>&1`
+	status=$?
+	if [ x$status = x0 ]; then
+		subunit_pass_test "$name"
+	else
+		echo "$output" | subunit_fail_test "$name"
+	fi
+	return $status
+}


Property changes on: trunk/openchange/testprogs/blackbox/subunit.sh
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/testprogs/blackbox/test_mapiprofile.sh
===================================================================
--- trunk/openchange/testprogs/blackbox/test_mapiprofile.sh	                        (rev 0)
+++ trunk/openchange/testprogs/blackbox/test_mapiprofile.sh	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Black tests for mapiprofile
+# Copyright (C) 2009 Julien Kerihuel <j.kerihuel at openchange.org>
+
+if [ $# -lt 4 ]; then
+cat <<EOF
+Usage: mapiprofile.sh SERVER USERNAME PASSWORD DOMAIN
+EOF
+exit 1;
+fi
+
+SERVER=$1
+USERNAME=$2
+PASSWORD=$3
+DOMAIN=$4
+shift 4
+failed=0
+
+ocbindir=`dirname $0`/../../bin
+mapiprofile=$ocbindir/mapiprofile
+profdb=`dirname $0`/profiles.ldb
+
+. `dirname $0`/subunit.sh
+
+testit "create new database" $VALGRIND $mapiprofile --newdb --database=$profdb || failed=`expr $failed + 1`
+
+testit "create new profile" $VALGRIND $mapiprofile --database=$profdb -P mapiprofile --create --username=$USERNAME --password=$PASSWORD -I $SERVER -D $DOMAIN || failed=`expr $failed + 1`
+
+testit "list profiles" $VALGRIND $mapiprofile --database=$profdb --list || failed=`expr $failed + 1`
+
+testit "set it as default" $VALGRIND $mapiprofile --database=$profdb -P mapiprofile -S || failed=`expr $failed + 1`
+
+# Check if the default profile has the proper name
+list_test=`mapiprofile --list --database=$profdb | grep default | cut -d= -f2 | sed 's/\[default\]//' | sed 's/\s*//' | sed 's/ //'`
+if [ "$list_test" != "mapiprofile" ]; then
+    subunit_fail_test "\"$list_test\" is not the default profile"
+    failed=`expr $failed + 1`
+fi
+
+testit "rename profile" $VALGRIND $mapiprofile --database=$profdb -P mapiprofile --rename=mapiprofile_rename || failed=`expr $failed + 1`
+
+# Check if the new profile has the proper name
+rename=`mapiprofile --list --database=$profdb | grep default | cut -d= -f2 | sed 's/\[default\]//' | sed 's/\s*//' | sed 's/ //'`
+if [ "$rename" != "mapiprofile_rename" ]; then
+    subunit_fail_test "mapiprofile was not renamed to mapiprofile_rename"
+    failed=`expr $failed + 1`
+fi
+
+testit "get FQDN" $VALGRIND $mapiprofile --database=$profdb -P mapiprofile_rename --getfqdn || failed=`expr $failed + 1`
+
+testit "delete profile" $VALGRIND $mapiprofile --database=$profdb -P mapiprofile_rename --delete || failed=`expr $failed + 1`
+
+rm -f profiles.ldb
\ No newline at end of file


Property changes on: trunk/openchange/testprogs/blackbox/test_mapiprofile.sh
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/torture/exchange_createuser.c
===================================================================
--- trunk/openchange/torture/exchange_createuser.c	                        (rev 0)
+++ trunk/openchange/torture/exchange_createuser.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,523 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Create an Exchange user
+
+   Copyright (C) Julien Kerihuel 2006 - 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/>.
+ */
+
+/*
+   Several functions are forked from Samba4 trunk for convenient
+   purposes:
+		- DeleteUser_byname
+		- torture_join_user_sid
+		- torture_create_testuser
+		- torture_leave_domain
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+#include <ldb.h>
+#include <ldb_errors.h>
+#include <ldb_wrap.h>
+#include <ldap_ndr.h>
+#include <util_ldb.h>
+#include <gen_ndr/ndr_samr.h>
+#include <gen_ndr/ndr_samr_c.h>
+#include <time.h>
+#include <core/error.h>
+#include <tevent.h>
+
+struct tce_async_context {
+	int found;
+};
+
+static int tce_search_callback(struct ldb_request *req, struct ldb_reply *ares)
+{
+        struct tce_async_context *actx = talloc_get_type(req->context, struct tce_async_context);
+	int ret;
+
+        switch (ares->type) {
+
+        case LDB_REPLY_ENTRY:
+		if (ldb_msg_find_element(ares->message, "msExchMailboxGuid") != NULL) {
+			actx->found = 1;
+		}
+                break;
+
+        case LDB_REPLY_DONE:
+                ret = 0;
+                break;
+
+        default:
+                fprintf(stderr, "unknown Reply Type ignore it\n");
+                return LDB_ERR_OTHER;
+        }
+
+        if (talloc_free(ares) == -1) {
+                fprintf(stderr, "talloc_free failed\n");
+                return LDB_ERR_OPERATIONS_ERROR;
+        }
+
+        return LDB_SUCCESS;
+}
+
+NTSTATUS torture_exchange_createuser(TALLOC_CTX *mem_ctx, const char *username,
+				     const struct dom_sid *dom_sid)
+{
+	enum MAPISTATUS		retval;
+	struct tevent_context	*ev = NULL;
+	struct mapi_profile	*profile;
+	struct ldb_context	*remote_ldb;
+	struct ldb_request	*req;
+	struct ldb_message	*msg;
+	struct ldb_message	**res;
+	struct tce_async_context *tce_ctx;
+	char			*remote_ldb_url;
+	const char * const	dom_attrs[] = { "objectSid", NULL };
+	int			ret;
+	uint32_t		count;
+	char			**values;
+
+	profile = global_mapi_ctx->session->profile;
+
+	ev = tevent_context_init(talloc_autofree_context());
+
+	/* 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);
+	if (!remote_ldb) return NT_STATUS_UNSUCCESSFUL;
+
+	/* search the user's record using the user dom_sid */
+	ret = gendb_search(remote_ldb, mem_ctx, NULL, &res,
+			   dom_attrs, "(objectSid=%s)",
+			   ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
+	if (ret == -1) {
+		return NT_STATUS_INTERNAL_DB_CORRUPTION;
+	}
+	if (ret == 0) {
+		return NT_STATUS_NO_SUCH_USER;
+	}
+
+	/* Prepare a new message for modify */
+	msg = ldb_msg_new(mem_ctx);
+	if (!msg) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	msg->dn = res[0]->dn;
+
+	{
+		int rtn;
+		const char *exch_attrs[7];
+
+		exch_attrs[0] = talloc_strdup(mem_ctx, username);
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "givenName", exch_attrs[0]);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		exch_attrs[1] = talloc_asprintf(mem_ctx, "513");
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "userAccountControl", exch_attrs[1]);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		{
+			int	i;
+			char	*realm = NULL;
+			
+			retval = GetProfileAttr(profile, "ProxyAddress", &count, &values);
+			if (retval != MAPI_E_SUCCESS) return NT_STATUS_UNSUCCESSFUL;
+			for (i = 0; i < count; i++) {
+				if (values[i] && !strncasecmp("smtp", values[i], 4)) {
+					realm = strchr(values[i], '@');
+					realm += 1;
+				}
+			}
+			if (!realm) return NT_STATUS_UNSUCCESSFUL;
+
+			exch_attrs[2] = talloc_asprintf(mem_ctx, "%s@%s", username, realm);
+			rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mail", exch_attrs[2]);
+			if (rtn == -1) return NT_STATUS_NO_MEMORY;
+		}
+
+		exch_attrs[3] = talloc_strdup(mem_ctx, username);
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mailNickname", exch_attrs[3]);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		exch_attrs[4] = talloc_asprintf(mem_ctx, "TRUE");
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mDBUseDefaults", exch_attrs[4]);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		{
+			char	*org;
+			
+			org =  talloc_strndup(mem_ctx, profile->mailbox, 
+					      strlen(profile->mailbox) - strlen(profile->username));			
+			exch_attrs[5] = talloc_asprintf(mem_ctx, "%s%s", org, username);
+			talloc_free(org);
+			rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "legacyExchangeDN", exch_attrs[5]);
+			if (rtn == -1) return NT_STATUS_NO_MEMORY;
+		}
+
+		exch_attrs[6] = talloc_strdup(mem_ctx, profile->homemdb);
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "msExchHomeServerName", exch_attrs[6]);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		/* Prior we call ldb_modify, set up async ldb request on
+		 * msExchMailboxGuid
+		 */
+
+		req = talloc_zero(mem_ctx, struct ldb_request);
+		req->operation = LDB_SEARCH;
+		req->op.search.base = res[0]->dn;
+		req->op.search.scope = LDB_SCOPE_BASE;
+		req->op.search.tree = ldb_parse_tree(remote_ldb, "(objectclass=*)");
+		req->op.search.attrs = NULL;
+		ldb_request_add_control(req, LDB_CONTROL_NOTIFICATION_OID, false, NULL);
+
+		tce_ctx = talloc_zero(mem_ctx, struct tce_async_context);
+		req->context = tce_ctx;
+		req->callback = tce_search_callback;
+		ldb_set_timeout(mem_ctx, req, 60);
+
+		rtn = ldb_request(remote_ldb, req);
+		if (rtn != LDB_SUCCESS) {
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+		DEBUG(0, ("async ldb request on msExchMailboxGuid sent\n"));
+
+		/* We modify the user record with Exchange attributes */
+		rtn = ldb_modify(remote_ldb, msg);
+		if (rtn != 0) return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		DEBUG(0, ("Extending AD user record with Exchange attributes\n"));
+	}
+	{
+		int rtn;
+
+		DEBUG(0, ("Waiting for Exchange mailbox creation\n"));
+		rtn = ldb_wait(req->handle, LDB_WAIT_NONE);
+		if (rtn != LDB_SUCCESS) {
+			printf("rtn = %d (loop - unsuccessful)\n", rtn);
+			return NT_STATUS_UNSUCCESSFUL;
+		}
+		if (!tce_ctx->found) { /* timeout */
+			printf("Timeout\n");
+			return NT_STATUS_UNSUCCESSFUL; 
+		}
+		DEBUG(0, ("User mailbox generated\n"));
+	}
+	
+	/* replace UserAccountControl attr in the user record */
+	talloc_free(msg);
+	msg = ldb_msg_new(mem_ctx);
+	if (!msg) return NT_STATUS_NO_MEMORY;
+	msg->dn = res[0]->dn;
+
+	{
+		const char *UserAccountControl;
+		int rtn;
+
+		UserAccountControl = talloc_asprintf(mem_ctx, "66048");
+		rtn = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "UserAccountControl", UserAccountControl);
+		if (rtn == -1) return NT_STATUS_NO_MEMORY;
+
+		rtn = samdb_replace(remote_ldb, mem_ctx, msg);
+		if (rtn != 0) return NT_STATUS_INTERNAL_DB_CORRUPTION;
+		DEBUG(0, ("ACB flags reset: password never expires\n"));
+	}
+
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+				  struct policy_handle *handle, const char *name)
+{
+	NTSTATUS status;
+	struct samr_DeleteUser d;
+	struct policy_handle user_handle;
+	uint32_t rid;
+	struct samr_LookupNames n;
+	struct lsa_String sname;
+	struct samr_OpenUser r;
+
+	sname.string = name;
+
+	n.in.domain_handle = handle;
+	n.in.num_names = 1;
+	n.in.names = &sname;
+
+	status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
+	if (NT_STATUS_IS_OK(status)) {
+		rid = n.out.rids->ids[0];
+	} else {
+		return status;
+	}
+
+	r.in.domain_handle = handle;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.in.rid = rid;
+	r.out.user_handle = &user_handle;
+
+	status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("OpenUser(%s) failed - %s\n", name, nt_errstr(status));
+		return status;
+	}
+
+	d.in.user_handle = &user_handle;
+	d.out.user_handle = &user_handle;
+	status = dcerpc_samr_DeleteUser(p, mem_ctx, &d);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+const struct dom_sid *torture_join_user_sid(struct test_join *join)
+{
+	return join->user_sid;
+}
+
+struct test_join *torture_create_testuser(struct torture_context *torture,
+					  const char *username, 
+					  const char *domain,
+					  uint16_t acct_type,
+					  const char **random_password)
+{
+	NTSTATUS status;
+	struct samr_Connect c;
+	struct samr_CreateUser2 r;
+	struct samr_OpenDomain o;
+	struct samr_LookupDomain l;
+	struct samr_GetUserPwInfo pwp;
+	struct samr_SetUserInfo s;
+	union samr_UserInfo u;
+	struct policy_handle handle;
+	struct policy_handle domain_handle;
+	uint32_t access_granted;
+	uint32_t rid;
+	DATA_BLOB session_key;
+	struct lsa_String name;
+	
+	int policy_min_pw_len = 0;
+	struct test_join *join;
+	char *random_pw;
+	const char *dc_binding = lp_parm_string(torture->lp_ctx,
+											NULL, "torture", "dc_binding");
+
+	join = talloc(NULL, struct test_join);
+	if (join == NULL) {
+		return NULL;
+	}
+
+	ZERO_STRUCTP(join);
+
+	printf("Connecting to SAMR\n");
+	
+	if (dc_binding) {
+		status = dcerpc_pipe_connect(join,
+					     &join->p,
+					     dc_binding,
+					     &ndr_table_samr,
+					     cmdline_credentials, 
+					     NULL, torture->lp_ctx);
+					     
+	} else {
+		status = torture_rpc_connection(torture, 
+						&join->p, 
+						&ndr_table_samr);
+	}
+	if (!NT_STATUS_IS_OK(status)) {
+		return NULL;
+	}
+
+	c.in.system_name = NULL;
+	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	c.out.connect_handle = &handle;
+
+	status = dcerpc_samr_Connect(join->p, join, &c);
+	if (!NT_STATUS_IS_OK(status)) {
+		const char *errstr = nt_errstr(status);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+			errstr = dcerpc_errstr(join, join->p->last_fault_code);
+		}
+		printf("samr_Connect failed - %s\n", errstr);
+		return NULL;
+	}
+
+	printf("Opening domain %s\n", domain);
+
+	name.string = domain;
+	l.in.connect_handle = &handle;
+	l.in.domain_name = &name;
+
+	status = dcerpc_samr_LookupDomain(join->p, join, &l);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("LookupDomain failed - %s\n", nt_errstr(status));
+		goto failed;
+	}
+
+	talloc_steal(join, l.out.sid);
+	join->dom_sid = *l.out.sid;
+	join->dom_netbios_name = talloc_strdup(join, domain);
+	if (!join->dom_netbios_name) goto failed;
+
+	o.in.connect_handle = &handle;
+	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	o.in.sid = *l.out.sid;
+	o.out.domain_handle = &domain_handle;
+
+	status = dcerpc_samr_OpenDomain(join->p, join, &o);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("OpenDomain failed - %s\n", nt_errstr(status));
+		goto failed;
+	}
+
+	printf("Creating account %s\n", username);
+
+again:
+	name.string = username;
+	r.in.domain_handle = &domain_handle;
+	r.in.account_name = &name;
+	r.in.acct_flags = acct_type;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.out.user_handle = &join->user_handle;
+	r.out.access_granted = &access_granted;
+	r.out.rid = &rid;
+
+	status = dcerpc_samr_CreateUser2(join->p, join, &r);
+
+	if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
+		status = DeleteUser_byname(join->p, join, &domain_handle, name.string);
+		if (NT_STATUS_IS_OK(status)) {
+			goto again;
+		}
+	}
+
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("CreateUser2 failed - %s\n", nt_errstr(status));
+		goto failed;
+	}
+
+	join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);
+
+	pwp.in.user_handle = &join->user_handle;
+
+	status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
+	if (NT_STATUS_IS_OK(status)) {
+		policy_min_pw_len = pwp.out.info->min_password_length;
+	}
+
+	
+	random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));
+
+	printf("Setting account password '%s'\n", random_pw);
+
+	ZERO_STRUCT(u);
+	s.in.user_handle = &join->user_handle;
+	s.in.info = &u;
+	s.in.level = 24;
+
+	encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
+	u.info24.password_expired = 0;
+
+	status = dcerpc_fetch_session_key(join->p, &session_key);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("SetUserInfo level %u - no session key - %s\n",
+		       s.in.level, nt_errstr(status));
+		torture_leave_domain(join);
+		goto failed;
+	}
+
+	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
+
+	status = dcerpc_samr_SetUserInfo(join->p, join, &s);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("SetUserInfo failed - %s\n", nt_errstr(status));
+		goto failed;
+	}
+
+	ZERO_STRUCT(u);
+	s.in.user_handle = &join->user_handle;
+	s.in.info = &u;
+	s.in.level = 21;
+
+	u.info21.acct_flags = acct_type | ACB_PWNOEXP;
+	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
+
+	u.info21.comment.string = talloc_asprintf(join, 
+						  "Tortured by Samba4: %s", 
+						  timestring(join, time(NULL)));
+	
+	u.info21.full_name.string = talloc_asprintf(join, 
+						    "Torture account for Samba4: %s", 
+						    timestring(join, time(NULL)));
+	
+	u.info21.description.string = talloc_asprintf(join, 
+					 "Samba4 torture account created by host %s: %s", 
+					 lp_netbios_name(torture->lp_ctx), 
+					 timestring(join, time(NULL)));
+
+	printf("Resetting ACB flags, force pw change time\n");
+
+	status = dcerpc_samr_SetUserInfo(join->p, join, &s);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("SetUserInfo failed - %s\n", nt_errstr(status));
+		goto failed;
+	}
+
+	if (random_password) {
+		*random_password = random_pw;
+	}
+
+	return join;
+
+failed:
+	torture_leave_domain(join);
+	return NULL;
+}
+
+/*
+  leave the domain, deleting the machine acct
+*/
+
+_PUBLIC_ void torture_leave_domain(struct test_join *join)
+{
+	struct samr_DeleteUser d;
+	NTSTATUS status;
+
+	if (!join) {
+		return;
+	}
+	d.in.user_handle = &join->user_handle;
+	d.out.user_handle = &join->user_handle;
+					
+	/* Delete machine account */
+
+	status = dcerpc_samr_DeleteUser(join->p, join, &d);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("Delete of machine account failed\n");
+	} else {
+		printf("Delete of machine account was successful.\n");
+	}
+
+	talloc_free(join);
+}

Added: trunk/openchange/torture/mapi_bookmark.c
===================================================================
--- trunk/openchange/torture/mapi_bookmark.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_bookmark.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,145 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Bookmark related operations torture
+
+   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 <libmapi/libmapi.h>
+#include <libmapi/defs_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+bool torture_rpc_mapi_bookmark(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		id_folder;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	struct mapi_session	*session;
+	uint32_t		bookmark;
+	const char		*subject = NULL;
+	uint64_t		mid = 0;
+	uint32_t		row;
+	uint32_t		count;
+	uint32_t		i = 0;
+	uint32_t		halfcount;
+
+	/* init torture test */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_bookmark");
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* Open Message Store */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve Inbox folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox folder */
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the Contents Table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Customize the table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_MID, PR_SUBJECT);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	halfcount = count / 2;
+
+	/* Position the cursor at the desired position */
+	retval = SeekRow(&obj_ctable, BOOKMARK_BEGINNING, halfcount, &row);
+	mapi_errstr("SeekRow: BOOKMARK_BEGINNING + offset", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch the associated row */
+	retval = QueryRows(&obj_ctable, 1, TBL_NOADVANCE, &SRowSet);
+	mapi_errstr("QueryRows", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Create the Bookmark */
+	mid = SRowSet.aRow[i].lpProps[0].value.d;
+	subject = SRowSet.aRow[i].lpProps[1].value.lpszA;
+
+	retval = CreateBookmark(&obj_ctable, &bookmark);
+	mapi_errstr("CreateBookmark", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Position the cursor at the beginning of the table */
+	retval = SeekRow(&obj_ctable, BOOKMARK_BEGINNING, 0, &row);
+	mapi_errstr("SeekRow: BOOKMARK_BEGINNING", GetLastError());
+
+	/* SeekRowBookmark */
+	retval = SeekRowBookmark(&obj_ctable, bookmark, 0, &row);
+	mapi_errstr("SeekRowBookmark", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	/* QueryRows a single column */
+	retval = QueryRows(&obj_ctable, 1, TBL_NOADVANCE, &SRowSet);
+	mapi_errstr("QueryRows", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	if (SRowSet.cRows == 0) {
+		DEBUG(0, ("QueryRows returned no rows\n"));
+		return false;
+	}
+	
+	DEBUG(0, ("[1] mid: %"PRIx64", subject = %s\n", mid, subject));
+	DEBUG(0, ("[2] mid: %"PRIx64", subject = %s\n", SRowSet.aRow[0].lpProps[0].value.d,
+		  SRowSet.aRow[0].lpProps[1].value.lpszA));
+
+	if (mid == SRowSet.aRow[0].lpProps[0].value.d) {
+		DEBUG(0, ("[SUCCESS] Message ID are the same\n"));
+	} else {
+		DEBUG(0, ("[FAILURE] Message ID are different\n"));
+		return false;
+	}
+
+	/* Free the bookmark */
+	retval = FreeBookmark(&obj_ctable, bookmark);
+	mapi_errstr("FreeBookmark", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+	return true;
+}

Added: trunk/openchange/torture/mapi_common.c
===================================================================
--- trunk/openchange/torture/mapi_common.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_common.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,377 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Common MAPI and torture related operations
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <torture/mapi_torture.h>
+#include <param.h>
+
+const char *get_filename(const char *filename)
+{
+	const char *substr;
+
+	substr = rindex(filename, '/');
+	if (substr) return substr;
+
+	return filename;
+}
+
+const char **get_cmdline_recipients(TALLOC_CTX *mem_ctx, const char *type)
+{
+	const char	**usernames;
+	const char	*recipients;
+	char		*tmp = NULL;
+	uint32_t	j = 0;
+
+	if (!type) {
+		return 0;
+	}
+
+	recipients = lp_parm_string(global_mapi_ctx->lp_ctx, NULL, "mapi", type);
+
+	/* no recipients */
+	if (recipients == 0) {
+		printf("no recipients specified for %s\n", type);
+		return 0;
+	}
+
+	if ((tmp = strtok((char *)recipients, ",")) == NULL) {
+		DEBUG(2, ("Invalid mapi:%s string format\n", type));
+		return NULL;
+	}
+	
+	usernames = talloc_array(mem_ctx, const char *, 2);
+	usernames[0] = strdup(tmp);
+	
+	for (j = 1; (tmp = strtok(NULL, ",")) != NULL; j++) {
+		usernames = talloc_realloc(mem_ctx, usernames, const char *, j+2);
+		usernames[j] = strdup(tmp);
+	}
+	usernames[j] = 0;
+
+	return usernames;
+}
+
+const char **collapse_recipients(TALLOC_CTX *mem_ctx, const char **to, const char **cc, const char **bcc)
+{
+	uint32_t	count;
+	uint32_t       	i;
+	const char	**usernames;
+
+	if (!to && !cc && !bcc) return NULL;
+
+	count = 0;
+	for (i = 0; to && to[i]; i++,  count++);
+	for (i = 0; cc && cc[i]; i++,  count++);
+	for (i = 0; bcc && bcc[i]; i++, count++);
+
+	usernames = talloc_array(mem_ctx, const char *, count + 1);
+	count = 0;
+
+	for (i = 0; to && to[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, to[i]);
+	}
+
+	for (i = 0; cc && cc[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, cc[i]);
+	}
+
+	for (i = 0; bcc && bcc[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, bcc[i]);
+	}
+
+	usernames[count++] = 0;
+
+	return usernames;
+}
+
+static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, const char *username, enum ulRecipClass RecipClass)
+{
+	uint32_t		last;
+	struct SPropValue	SPropValue;
+
+	SRowSet->aRow = talloc_realloc(mem_ctx, SRowSet->aRow, struct SRow, SRowSet->cRows + 2);
+	last = SRowSet->cRows;
+	SRowSet->aRow[last].cValues = 0;
+	SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue);
+	
+	/* PR_OBJECT_TYPE */
+	SPropValue.ulPropTag = PR_OBJECT_TYPE;
+	SPropValue.value.l = MAPI_MAILUSER;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_TYPE */
+	SPropValue.ulPropTag = PR_DISPLAY_TYPE;
+	SPropValue.value.l = 0;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_GIVEN_NAME */
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_7BIT_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_SMTP_ADDRESS */
+	SPropValue.ulPropTag = PR_SMTP_ADDRESS;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_ADDRTYPE */
+	SPropValue.ulPropTag = PR_ADDRTYPE;
+	SPropValue.value.lpszA = "SMTP";
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	SetRecipientType(&(SRowSet->aRow[last]), RecipClass);
+
+	SRowSet->cRows += 1;
+	return true;
+}
+
+bool set_usernames_RecipientType(TALLOC_CTX *mem_ctx, uint32_t *index, struct SRowSet *rowset, 
+					const char **usernames, struct SPropTagArray *flaglist,
+					enum ulRecipClass RecipClass)
+{
+	uint32_t	i;
+	uint32_t	count = *index;
+	static uint32_t	counter = 0;
+
+	if (count == 0) counter = 0;
+	if (!usernames) return false;
+
+	for (i = 0; usernames[i]; i++) {
+		if (flaglist->aulPropTag[count] == MAPI_UNRESOLVED) {
+			set_external_recipients(mem_ctx, rowset, usernames[i], RecipClass);
+		}
+		if (flaglist->aulPropTag[count] == MAPI_RESOLVED) {
+			SetRecipientType(&(rowset->aRow[counter]), RecipClass);
+			counter++;
+		}
+		count++;
+	}
+	
+	*index = count;
+	
+	return true;
+}
+
+/**
+ * Initialize MAPI and Load Profile
+ *
+ */
+enum MAPISTATUS torture_load_profile(TALLOC_CTX *mem_ctx, 
+				     struct loadparm_context *lp_ctx,
+				     struct mapi_session **s)
+{
+	enum MAPISTATUS		retval;
+	const char		*profdb;
+	char			*profname;
+	struct mapi_session	*session = NULL;
+
+	profdb = lp_parm_string(lp_ctx, NULL, "mapi", "profile_store");
+	if (!profdb) {
+		profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME"));
+		if (!profdb) {
+			DEBUG(0, ("Specify a valid MAPI profile store\n"));
+			return MAPI_E_NOT_FOUND;
+		}
+	}
+
+	retval = MAPIInitialize(profdb);
+	mapi_errstr("MAPIInitialize", GetLastError());
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	profname = talloc_strdup(mem_ctx, lp_parm_string(lp_ctx, NULL, "mapi", "profile"));
+	if (!profname) {
+		retval = GetDefaultProfile(&profname);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+	}
+
+	/* MapiLogonProvider returns MAPI_E_NO_SUPPORT: reset errno */
+	retval = MapiLogonProvider(&session, profname, NULL, PROVIDER_ID_NSPI);
+	talloc_free(profname);
+	errno = 0;
+
+	retval = LoadProfile(session->profile);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	*s = session;
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Initialize MAPI and logs on the EMSMDB pipe with the default
+ * profile
+ */
+
+struct mapi_session *torture_init_mapi(TALLOC_CTX *mem_ctx, 
+				       struct loadparm_context *lp_ctx)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session;
+	const char		*profdb;
+	char			*profname;
+	const char		*password;
+
+	profdb = lp_parm_string(lp_ctx, NULL, "mapi", "profile_store");
+	if (!profdb) {
+		profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME"));
+		if (!profdb) {
+			DEBUG(0, ("Specify a valid MAPI profile store\n"));
+			return NULL;
+		}
+	}
+
+	retval = MAPIInitialize(profdb);
+	mapi_errstr("MAPIInitialize", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return NULL;
+
+
+	profname = talloc_strdup(mem_ctx, lp_parm_string(lp_ctx, NULL, "mapi", "profile"));
+	if (!profname) {
+		retval = GetDefaultProfile(&profname);
+		if (retval != MAPI_E_SUCCESS) {
+			DEBUG(0, ("Please specify a valid profile\n"));
+			return NULL;
+		}
+	}
+
+	password = lp_parm_string(lp_ctx, NULL, "mapi", "password");
+	retval = MapiLogonEx(&session, profname, password);
+	talloc_free(profname);
+	mapi_errstr("MapiLogonEx", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return NULL;
+
+	return session;
+}
+
+enum MAPISTATUS torture_simplemail_fromme(struct loadparm_context *lp_ctx,
+					  mapi_object_t *obj_parent, 
+					  const char *subject, const char *body,
+					  uint32_t flags)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_message;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct SPropValue	props[3];
+	struct mapi_session	*session = NULL;
+	const char	       	**usernames;
+	uint32_t		index = 0;
+
+	mem_ctx = talloc_named(NULL, 0, "torture_simplemail");
+
+	session = mapi_object_get_session(obj_parent);
+	MAPI_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(obj_parent, &obj_message);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	SPropTagArray  = set_SPropTagArray(mem_ctx, 0x6,
+					   PR_OBJECT_TYPE,
+					   PR_DISPLAY_TYPE,
+					   PR_7BIT_DISPLAY_NAME,
+					   PR_DISPLAY_NAME,
+					   PR_SMTP_ADDRESS,
+					   PR_GIVEN_NAME);
+
+	lp_set_cmdline(lp_ctx, "mapi:to", session->profile->username);
+	usernames = get_cmdline_recipients(mem_ctx, "to");
+
+	retval = ResolveNames(session, usernames, SPropTagArray, &SRowSet, &flaglist, 0);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	if (!SRowSet) {
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames, flaglist, MAPI_TO);
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, SRowSet, SPropValue);
+
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = MAPIFreeBuffer(SRowSet);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+	retval = MAPIFreeBuffer(flaglist);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	set_SPropValue_proptag(&props[0], PR_SUBJECT, (const void *)subject);
+	set_SPropValue_proptag(&props[1], PR_BODY, (const void *)body);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_FLAGS, (const void *)&flags);
+	retval = SetProps(&obj_message, props, 3);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	retval = SaveChangesMessage(obj_parent, &obj_message, KeepOpenReadOnly);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	mapi_object_release(&obj_message);
+
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+uint32_t get_permission_from_name(const char *role)
+{
+	if (!role) return -1;
+
+	if (!strncasecmp(role, "RightsNone", strlen(role))) return 0x0;
+	if (!strncasecmp(role, "RightsReadItems", strlen(role))) return 0x1;
+	if (!strncasecmp(role, "RightsCreateItems", strlen(role))) return 0x2;
+	if (!strncasecmp(role, "RightsEditOwn", strlen(role))) return 0x8;
+	if (!strncasecmp(role, "RightsDeleteOwn", strlen(role))) return 0x10;
+	if (!strncasecmp(role, "RightsEditAll", strlen(role))) return 0x20;
+	if (!strncasecmp(role, "RightsDeleteAll", strlen(role))) return 0x40;
+	if (!strncasecmp(role, "RightsCreateSubfolders", strlen(role))) return 0x80;
+	if (!strncasecmp(role, "RightsFolderOwner", strlen(role))) return 0x100;
+	if (!strncasecmp(role, "RightsFolderContact", strlen(role))) return 0x200;
+	if (!strncasecmp(role, "RoleNone", strlen(role))) return 0x400;
+	if (!strncasecmp(role, "RoleReviewer", strlen(role))) return 0x401;
+	if (!strncasecmp(role, "RoleContributor", strlen(role))) return 0x402;
+	if (!strncasecmp(role, "RoleNoneditingAuthor", strlen(role))) return 0x413;
+	if (!strncasecmp(role, "RoleAuthor", strlen(role))) return 0x41B;
+	if (!strncasecmp(role, "RoleEditor", strlen(role))) return 0x47B;
+	if (!strncasecmp(role, "RolePublishAuthor", strlen(role))) return 0x49B;
+	if (!strncasecmp(role, "RolePublishEditor", strlen(role))) return 0x4FB;
+	if (!strncasecmp(role, "RightsAll", strlen(role))) return 0x5FB;
+	if (!strncasecmp(role, "RoleOwner", strlen(role))) return 0x7FB;
+
+	return -1;
+}

Added: trunk/openchange/torture/mapi_copymail.c
===================================================================
--- trunk/openchange/torture/mapi_copymail.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_copymail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,130 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Copy message from a folder to another
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_copymail(struct torture_context *torture)
+{
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_dir_src;
+	mapi_object_t		obj_dir_dst;
+	mapi_object_t		obj_table;
+	mapi_id_t		id_src;
+	mapi_id_t		id_dst;
+	mapi_id_array_t		msg_id_array;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SRowSet		rowset;
+	int			i;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_copymail");
+	status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+	
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_dir_src);
+	mapi_object_init(&obj_dir_dst);
+	mapi_object_init(&obj_table);
+
+	/* OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Get Inbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_src, olFolderInbox);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = OpenFolder(&obj_store, id_src, &obj_dir_src);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Get Deleted Items folder */
+	retval = GetDefaultFolder(&obj_store, &id_dst, olFolderDrafts);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	retval = OpenFolder(&obj_store, id_dst, &obj_dir_dst);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+
+	retval = GetContentsTable(&obj_dir_src, &obj_table, 0, NULL);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_id_array_init(&msg_id_array);
+
+	while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		for (i = 0; i < rowset.cRows; i++) {
+			mapi_id_array_add_id(&msg_id_array, rowset.aRow[i].lpProps[1].value.d);
+		}
+		retval = MoveCopyMessages(&obj_dir_src, &obj_dir_dst, &msg_id_array, 1);
+		mapi_errstr("MoveCopyMessages", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* release mapi objects
+	 */
+	mapi_id_array_release(&msg_id_array);
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_dir_src);
+	mapi_object_release(&obj_dir_dst);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+
+	return true;
+}

Added: trunk/openchange/torture/mapi_createuser.c
===================================================================
--- trunk/openchange/torture/mapi_createuser.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_createuser.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,76 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Create an Exchange User
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+#include <gen_ndr/samr.h>
+
+bool torture_mapi_createuser(struct torture_context *torture)
+{
+	NTSTATUS		ntstatus;
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_profile	*profile;
+	struct test_join        *user_ctx = (struct test_join *) NULL;
+	const char		*username = lp_parm_string(torture->lp_ctx, NULL, "exchange", "username");
+	const char		*user_password = lp_parm_string(torture->lp_ctx, NULL, "exchange", "password");
+	struct mapi_session	*session;
+
+	/* sanity checks */
+	if (!username) {
+		printf("Specify the username to create with exchange:username\n");
+		return false;
+	}
+
+	/* init mapi */
+	mem_ctx = talloc_named(NULL, 0, "torture_mapi_createuser");
+	retval = torture_load_profile(mem_ctx, torture->lp_ctx, &session);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	profile = session->profile;
+
+	/* Create the user in the AD */
+	user_ctx = torture_create_testuser(torture, username, 
+					   profile->domain, 
+					   ACB_NORMAL,
+					   (const char **)&user_password);
+
+	if (!user_ctx) {
+		printf("Failed to create the user\n");
+		return false;
+	}
+
+       /* We extend the user with Exchange attributes */
+	ntstatus = torture_exchange_createuser(mem_ctx, username, torture_join_user_sid(user_ctx));
+       if (!NT_STATUS_IS_OK(ntstatus)) {
+	       torture_leave_domain(user_ctx);
+	       talloc_free(mem_ctx);
+	       return false;
+       }
+
+       return true;
+}

Added: trunk/openchange/torture/mapi_criteria.c
===================================================================
--- trunk/openchange/torture/mapi_criteria.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_criteria.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,146 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Test Restrictions
+
+   Copyright (C) Julien Kerihuel 2007 - 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/libmapi.h>
+#include <libmapi/defs_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+/*
+  1. Create a search folder within Top Information Store
+  2. SetCriteria with RES_CONTENT PR_SUBJECT FL_SUBSTRING criteria
+  3. QueryRows and check if it worked ;-)
+ */
+
+bool torture_rpc_mapi_criteria(struct torture_context *torture)
+{
+	NTSTATUS			ntstatus;
+	enum MAPISTATUS			retval;
+	struct dcerpc_pipe		*p;
+	TALLOC_CTX			*mem_ctx;
+	struct mapi_session		*session;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_searchdir;
+	mapi_object_t			obj_search;
+	mapi_id_t			id_search;
+	mapi_id_t			id_tis;
+	mapi_id_array_t			id;
+	struct mapi_SRestriction	res;
+	struct SPropValue		lpProps[1];
+	uint32_t			ulSearchFlags;
+	uint16_t			count;
+	mapi_id_t			*fid;
+	uint32_t			i;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_criteria");
+	ntstatus = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(ntstatus)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+	
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* Open Message Store */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	/* Get Top Information Store ID */
+	retval = GetDefaultFolder(&obj_store, &id_tis, olFolderTopInformationStore);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Search folder */
+	retval = GetDefaultFolder(&obj_store, &id_search, olFolderFinder);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_search);
+	retval = OpenFolder(&obj_store, id_search, &obj_search);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Create the Search folder */
+	mapi_object_init(&obj_searchdir);
+	retval = CreateFolder(&obj_search, FOLDER_SEARCH, "torture_search", 
+			      "Torture Search Folder", OPEN_IF_EXISTS, 
+			      &obj_searchdir);
+	mapi_errstr("CreateFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set Props */
+	lpProps[0].ulPropTag = PR_CONTAINER_CLASS;
+	lpProps[0].value.lpszA = "IPF.Note";
+	retval = SetProps(&obj_searchdir, lpProps, 1);
+	mapi_errstr("SetProps", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set Search criteria on this folder */
+	mapi_id_array_init(&id);
+	mapi_id_array_add_id(&id, id_tis);
+
+	res.rt = RES_CONTENT;
+	res.res.resContent.fuzzy = FL_SUBSTRING;
+	res.res.resContent.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.value.lpszA = "criteria";
+
+	retval = SetSearchCriteria(&obj_searchdir, &res, 
+				   BACKGROUND_SEARCH|RECURSIVE_SEARCH,
+				   &id);
+	mapi_errstr("SetSearchCriteria", GetLastError());
+	mapi_id_array_release(&id);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Get Search criteria for this folder */
+	retval = GetSearchCriteria(&obj_searchdir, &res, &ulSearchFlags, &count, &fid);
+	mapi_errstr("GetSearchCriteria", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	printf("ulSearchFlags = 0x%x\n", ulSearchFlags);
+	printf("res.rt = %d\n", res.rt);
+	printf("count = %d\n", count);
+	for (i = 0; i < count; i++) {
+	  printf("lpContainerList[%d] = 0x%"PRIx64"\n", i, fid[i]);
+	}
+
+	/* Delete folder */
+	retval = DeleteFolder(&obj_search, mapi_object_get_id(&obj_searchdir),
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	mapi_errstr("DeleteFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_searchdir);
+	mapi_object_release(&obj_search);
+	mapi_object_release(&obj_store);
+	talloc_free(mem_ctx);
+
+	return true;
+}

Added: trunk/openchange/torture/mapi_deletemail.c
===================================================================
--- trunk/openchange/torture/mapi_deletemail.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_deletemail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,141 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Delete mail from an Exchange server
+
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <libmapi/defs_private.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+#define CN_ROWS 0x100
+
+
+bool torture_rpc_mapi_deletemail(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*s_subject = lp_parm_string(torture->lp_ctx, NULL, "mapi", "subject");
+	int			len_subject;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_table;
+	mapi_id_t		id_inbox;
+	mapi_id_t		*id_messages;
+	unsigned long		cn_messages;
+	struct SRowSet		rowset;
+	unsigned long		i_row;
+	unsigned long		cn_rows;
+	struct SPropTagArray	*SPropTagArray;
+
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_deletemail");
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objets */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_table);
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_object_debug(&obj_store);
+
+	/* id_inbox = store->GetReceiveFolder */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	mapi_errstr("GetReceiveFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* inbox = store->OpenFolder()
+	 */
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_object_debug(&obj_inbox);
+
+	/* table = inbox->GetContentsTable() */
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, NULL);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_object_debug(&obj_table);
+
+	/* rowset = table->QueryRows() */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	while ((retval = QueryRows(&obj_table, CN_ROWS, TBL_ADVANCE, &rowset)) == MAPI_E_SUCCESS) {
+		cn_rows = rowset.cRows;
+		if (!cn_rows) break;
+		id_messages = talloc_array(mem_ctx, uint64_t, cn_rows);
+		cn_messages = 0;
+		
+		if (s_subject == 0)
+			s_subject = "default_subject";
+		len_subject = strlen(s_subject);
+		
+		for (i_row = 0; i_row < cn_rows; ++i_row) {
+			if (strncmp(rowset.aRow[i_row].lpProps[4].value.lpszA, s_subject, len_subject) == 0) {
+				id_messages[cn_messages] = rowset.aRow[i_row].lpProps[1].value.d;
+				++cn_messages;
+				DEBUG(0, ("delete(%"PRIx64")\n", id_messages[cn_messages - 1]));
+			}
+		}
+
+		/* IMessage::DeleteMessages() */
+		if (cn_messages) {
+			retval = DeleteMessage(&obj_inbox, id_messages, cn_messages);
+			if (retval != MAPI_E_SUCCESS) {
+				mapi_errstr("DeleteMessages", GetLastError());
+			}
+		}
+	}
+
+	/* release objects
+	 */
+	mapi_object_release(&obj_store);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_table);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_fetchappointment.c
===================================================================
--- trunk/openchange/torture/mapi_fetchappointment.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_fetchappointment.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,129 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch appointments from an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_fetchappointment(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	uint64_t		id_calendar;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_calendar;
+	mapi_object_t		obj_cal_table;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchappointment");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+	
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_calendar);
+	mapi_object_init(&obj_cal_table);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the default calendar folder id */
+	retval = GetDefaultFolder(&obj_store, &id_calendar, olFolderCalendar);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the calendar folder */
+	retval = OpenFolder(&obj_store, id_calendar, &obj_calendar);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the calendar folder */
+	retval = GetContentsTable(&obj_calendar, &obj_cal_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_CLASS,
+					  PR_RULE_MSG_PROVIDER,
+					  PR_RULE_MSG_NAME);
+	retval = SetColumns(&obj_cal_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryRows(&obj_cal_table, 0x32, TBL_ADVANCE, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	{
+		int i;
+		mapi_object_t obj_message;
+		struct mapi_SPropValue_array properties_array;
+
+		printf("We have %d appointments in the table\n", SRowSet.cRows);
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_calendar, 
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     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) {
+				  mapidump_appointment(&properties_array, NULL);
+					mapi_object_release(&obj_message);
+				}
+			}
+		}
+	}
+
+	mapi_object_release(&obj_cal_table);
+	mapi_object_release(&obj_calendar);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_fetchattach.c
===================================================================
--- trunk/openchange/torture/mapi_fetchattach.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_fetchattach.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,230 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch attachments from an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+static enum MAPISTATUS read_attach_stream(TALLOC_CTX *ctx_mem,
+					  mapi_object_t *obj_attach,
+					  mapi_object_t *obj_stream,
+					  uint8_t** buf_data,
+					  uint32_t* sz_data)
+{
+  uint16_t		cn_read;
+  uint32_t		off_data;
+  enum MAPISTATUS	status;
+  int			done;
+  struct SPropTagArray	*proptags;
+  struct SPropValue	*vals;
+  uint32_t		cn_vals;
+
+  /* Reset 
+   */
+  *buf_data = 0;
+  *sz_data = 0;
+  off_data = 0;
+  done = 0;
+
+  /* Get Attachment size
+   */
+  proptags = set_SPropTagArray(ctx_mem, 0x1, PR_ATTACH_SIZE);
+  status = GetProps(obj_attach, proptags, &vals, &cn_vals);
+  mapi_errstr("GetProps", GetLastError());
+  if (status != MAPI_E_SUCCESS) return status;
+
+  /* Alloc buffer
+   */
+  *sz_data = (uint32_t)vals[0].value.b;
+  *buf_data = talloc_size(ctx_mem, *sz_data);
+  if (*buf_data == 0)
+    return -1;
+
+  /* Read attachment
+   */
+  while (done == 0) {
+	  status = ReadStream(obj_stream,
+			      (*buf_data) + off_data,
+			      (*sz_data) - off_data,
+			      &cn_read);
+	  mapi_errstr("ReadStream", GetLastError());
+	  if ((status != MAPI_E_SUCCESS) || (cn_read == 0)) {
+		  done = 1;
+	  }
+	  else {
+		  off_data += cn_read;
+		  if (off_data >= *sz_data)
+			  done = 1;
+	  }
+  }
+
+  *sz_data = off_data;
+
+  return status;
+}
+
+bool torture_rpc_mapi_fetchattach(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_tb_contents;
+	mapi_object_t		obj_tb_attach;
+	mapi_object_t		obj_attach;
+	mapi_object_t		obj_stream;
+	mapi_id_t		id_inbox;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_message;
+	struct SPropTagArray	*proptags;
+	struct SRowSet		rows_msgs;
+	struct SRowSet		rows_attach;
+	uint32_t		i_msg;
+	uint32_t		i_row_attach;
+	uint32_t		num_attach;
+	uint8_t			*buf_attach;
+	uint32_t		sz_attach;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchattach");
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_message);
+	mapi_object_init(&obj_tb_contents);
+	mapi_object_init(&obj_tb_attach);
+	mapi_object_init(&obj_attach);
+	mapi_object_init(&obj_stream);
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* id_inbox = store->GetReceiveFolder */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	mapi_errstr("GetReceiveFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* inbox = store->OpenFolder() */
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* table = inbox->GetContentsTable() */
+	retval = GetContentsTable(&obj_inbox, &obj_tb_contents, 0, NULL);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	proptags = set_SPropTagArray(mem_ctx, 0x5,
+				     PR_FID,
+				     PR_MID,
+				     PR_INST_ID,
+				     PR_INSTANCE_NUM,
+				     PR_SUBJECT);
+	retval = SetColumns(&obj_tb_contents, proptags);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryRows(&obj_tb_contents, 0xa, TBL_ADVANCE, &rows_msgs);
+	mapi_errstr("QueryRows", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* foreach message get attachment table
+	   foreach attachment, get PR_NUM
+	   foreach PR_NUM, open attachment
+	 */
+	
+	for (i_msg = 0; i_msg < rows_msgs.cRows; i_msg++) {
+
+		/* open message
+		 */
+		id_folder = rows_msgs.aRow[i_msg].lpProps[0].value.d;
+		id_message = rows_msgs.aRow[i_msg].lpProps[1].value.d;
+		retval = OpenMessage(&obj_store, 
+				     id_folder, 
+				     id_message, 
+				     &obj_message, 0);
+		mapi_errstr("OpenMessage", GetLastError());
+		if (retval == MAPI_E_SUCCESS) {
+
+			/* open attachment table */
+			retval = GetAttachmentTable(&obj_message, &obj_tb_attach);
+			mapi_errstr("GetAttachmentTable", GetLastError());
+
+			/* foreach attachment, open by PR_ATTACH_NUM */
+			if (retval == MAPI_E_SUCCESS) {
+				proptags = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
+				retval = SetColumns(&obj_tb_attach, proptags);
+				mapi_errstr("SetColumns", GetLastError());
+				if (retval != MAPI_E_SUCCESS) return false;
+
+				retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rows_attach);
+				mapi_errstr("QueryRows", GetLastError());
+				if (retval != MAPI_E_SUCCESS) return false;
+
+				/* get a stream on PR_ATTACH_DATA_BIN */
+				for (i_row_attach = 0; i_row_attach < rows_attach.cRows; i_row_attach++) {
+					num_attach = rows_attach.aRow[i_row_attach].lpProps[0].value.l;
+					retval = OpenAttach(&obj_message, num_attach, &obj_attach);
+					mapi_errstr("OpenAttach", GetLastError());
+					if (retval == MAPI_E_SUCCESS) {
+						retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+						mapi_errstr("OpenStream", GetLastError());
+
+						/* read stream content */
+						if (retval == MAPI_E_SUCCESS) {
+							read_attach_stream(mem_ctx,
+									   &obj_attach, &obj_stream, &buf_attach,
+									   &sz_attach);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	mapi_object_release(&obj_store);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_tb_contents);
+	mapi_object_release(&obj_tb_attach);
+	mapi_object_release(&obj_attach);
+	mapi_object_release(&obj_stream);
+
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_fetchcontacts.c
===================================================================
--- trunk/openchange/torture/mapi_fetchcontacts.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_fetchcontacts.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,126 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch contacts from an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_fetchcontacts(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	uint64_t		id_contacts;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_contacts;
+	mapi_object_t		obj_table;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchmail");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_contacts);
+	mapi_object_init(&obj_table);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the contacts Folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_contacts, olFolderContacts);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the contacts folder */
+	retval = OpenFolder(&obj_store, id_contacts, &obj_contacts);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the contacts folder */
+	retval = GetContentsTable(&obj_contacts, &obj_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_CLASS,
+					  PR_RULE_MSG_PROVIDER,
+					  PR_RULE_MSG_NAME);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryRows(&obj_table, 0x32, TBL_ADVANCE, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	{
+		int i;
+		mapi_object_t obj_message;
+		struct mapi_SPropValue_array properties_array;
+
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_contacts, 
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     SRowSet.aRow[i].lpProps[1].value.d,
+					     &obj_message, 0);
+			if (retval != MAPI_E_NOT_FOUND) {
+				retval = GetPropsAll(&obj_message, &properties_array);
+				mapidump_contact(&properties_array, NULL);
+				mapi_object_release(&obj_message);
+			}
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_contacts);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_fetchmail.c
===================================================================
--- trunk/openchange/torture/mapi_fetchmail.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_fetchmail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,139 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch emails from an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+bool torture_rpc_mapi_fetchmail(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_table;
+	uint64_t		id_inbox;
+	struct SPropTagArray	*SPropTagArray;
+	struct mapi_SPropValue_array	properties_array;
+	struct SRowSet		rowset;
+	uint32_t		i;
+	uint32_t		count;
+	uint32_t		unread;
+	uint32_t		total;
+
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchmail");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_message);
+	mapi_object_init(&obj_table);
+
+	/* session::OpenMsgStore()
+	 */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* id_inbox = store->GetReceiveFolder */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	mapi_errstr("GetReceiveFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox folder */
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve message count summary from the folder */
+	retval = GetFolderItemsCount(&obj_inbox, &unread, &total);
+	mapi_errstr("GetFolderItemsCount", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+		
+	/* table = inbox->GetContentsTable()
+	 */
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	talloc_free(SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	printf("Inbox: Total(%d) Unread(%d)\n", total, unread);
+
+	while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		for (i = 0; i < rowset.cRows; i++) {
+			retval = OpenMessage(&obj_store,
+					     rowset.aRow[i].lpProps[0].value.d,
+					     rowset.aRow[i].lpProps[1].value.d,
+					     &obj_message, 0);
+
+			if (GetLastError() != MAPI_E_NOT_FOUND) {
+			  retval = GetPropsAll(&obj_message, &properties_array);
+			  mapidump_message(&properties_array, NULL);
+			  mapi_object_release(&obj_message);
+			}
+		}
+	}
+
+	/* release mapi objects
+	 */
+	mapi_object_release(&obj_store);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_table);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_fetchtasks.c
===================================================================
--- trunk/openchange/torture/mapi_fetchtasks.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_fetchtasks.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,129 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch tasks from an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_fetchtasks(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	uint64_t		id_tasks;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_tasks;
+	mapi_object_t		obj_tasks_table;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchtasks");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_tasks);
+	mapi_object_init(&obj_tasks_table);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the tasks Folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_tasks, olFolderTasks);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the tasks folder */
+	retval = OpenFolder(&obj_store, id_tasks, &obj_tasks);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the tasks folder */
+	retval = GetContentsTable(&obj_tasks, &obj_tasks_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_CLASS,
+					  PR_RULE_MSG_PROVIDER,
+					  PR_RULE_MSG_NAME);
+	retval = SetColumns(&obj_tasks_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryRows(&obj_tasks_table, 0x32, TBL_ADVANCE, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	{
+		int i;
+		mapi_object_t obj_message;
+		struct mapi_SPropValue_array properties_array;
+
+		printf("We have %d tasks in the table\n", SRowSet.cRows);
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_tasks, 
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     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) {
+				  mapidump_task(&properties_array, NULL);
+					mapi_object_release(&obj_message);
+				}
+			}
+		}
+	}
+
+	mapi_object_release(&obj_tasks_table);
+	mapi_object_release(&obj_tasks);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_namedprops.c
===================================================================
--- trunk/openchange/torture/mapi_namedprops.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_namedprops.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,283 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Test Named properties and IMAPIProp associated functions
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#define	NAMEDPROP_NAME	"torture_namedprops"
+#define	NAMEDPROP_VALUE	"Can you see me?"
+
+bool torture_rpc_mapi_namedprops(struct torture_context *torture)
+{
+	NTSTATUS			status;
+	enum MAPISTATUS			retval;
+	struct dcerpc_pipe		*p;
+	TALLOC_CTX			*mem_ctx;
+	bool				ret = true;
+	struct mapi_session		*session;
+	mapi_id_t			id_folder;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_message;
+	struct SRowSet			SRowSet;
+	struct SPropTagArray		*SPropTagArray;
+	struct SPropValue		*propvals;
+	struct mapi_SPropValue_array	props_array;
+	uint32_t			i;
+	uint32_t			propID;
+	uint16_t			count;
+	struct MAPINAMEID		*nameid;
+	uint16_t			*propIDs;
+	uint32_t			cn_propvals;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_namedprops");
+	status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+	
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* OpenMsgStore */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the specified folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open the folder */
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the folder contents */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_folder, &obj_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_CLASS,
+					  PR_RULE_MSG_PROVIDER,
+					  PR_RULE_MSG_NAME);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryRows(&obj_table, 0x32, TBL_ADVANCE, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We just need to open the first message for this test */
+	if (SRowSet.cRows == 0) {
+		printf("No messages in Mailbox\n");
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	mapi_object_init(&obj_message);
+	retval = OpenMessage(&obj_folder,
+			     SRowSet.aRow[0].lpProps[0].value.d,
+			     SRowSet.aRow[0].lpProps[1].value.d,
+			     &obj_message, MAPI_MODIFY|MAPI_CREATE);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = GetPropsAll(&obj_message, &props_array);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* loop through properties, search for named properties
+	 * (0x8000-0xFFFE range) and call GetNamesFromIDs 
+	 */
+	printf("\n\n1. GetNamesFromIDs\n");
+	for (i = 0; i < props_array.cValues; i++) {
+		propID = props_array.lpProps[i].ulPropTag >> 16;
+		if (propID >= 0x8000 && propID <= 0xFFFE) {
+			propID = props_array.lpProps[i].ulPropTag;
+			propID = (propID & 0xFFFF0000) | PT_NULL;
+			nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
+			retval = GetNamesFromIDs(&obj_message, propID, &count, &nameid);
+			if (retval != MAPI_E_SUCCESS) return false;
+			switch (nameid->ulKind) {
+			case MNID_ID:
+				printf("\t0x%.8x mapped to 0x%.4x\n", 
+				       propID | (props_array.lpProps[i].ulPropTag & 0xFFFF), nameid->kind.lid);
+				break;
+			case MNID_STRING:
+				printf("\t0x%.8x mapped to %s\n",
+				       propID, nameid->kind.lpwstr.Name);
+				break;
+			}
+			talloc_free(nameid);
+		}
+	}
+
+	/*
+	 * Retrieve all the named properties for the current object
+	 * This function seems to be the only one accepting 0 for
+	 * input ulPropTag and returning the whole set of named properties
+	 */
+	printf("\n\n2. QueryNamedProperties\n");
+	nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
+	propIDs = talloc_zero(mem_ctx, uint16_t);
+	retval = QueryNamedProperties(&obj_message, 0, NULL, &count, &propIDs, &nameid);
+	mapi_errstr("QueryNamedProperties", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	for (i = 0; i < count; i++) {
+		char	*guid;
+
+		printf("0x%.4x:\n", propIDs[i]);
+
+		guid = GUID_string(mem_ctx, &nameid[i].lpguid);
+		printf("\tguid: %s\n", guid);
+		talloc_free(guid);
+
+		switch (nameid[i].ulKind) {
+		case MNID_ID:
+			printf("\tmapped to 0x%.4x\n", nameid[i].kind.lid);
+			break;
+		case MNID_STRING:
+			printf("\tmapped to %s\n", nameid[i].kind.lpwstr.Name);
+			break;
+		}		
+	}
+	talloc_free(propIDs);
+
+	/*
+	 * finally call GetIDsFromNames with the Names retrieved in
+	 * the previous call
+	 */
+	printf("\n\n3. GetIDsFromNames\n");
+	for (i = 0; i < count; i++) {
+		SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+		retval = GetIDsFromNames(&obj_folder, 1, &nameid[i], 0, &SPropTagArray);
+		switch (nameid[i].ulKind) {
+		case MNID_ID:
+			printf("0x%.4x mapped to ", nameid[i].kind.lid);
+			break;
+		case MNID_STRING:
+			printf("%s mapped to ", nameid[i].kind.lpwstr.Name);
+			break;
+		}	
+		mapidump_SPropTagArray(SPropTagArray);
+		talloc_free(SPropTagArray);
+	}
+
+	talloc_free(nameid);
+
+	/*
+	 * Try to create a named property
+	 */
+	{
+	  struct GUID guid;
+
+	  printf("\n\n4. GetIDsFromNames (Create named property)\n");
+	  GUID_from_string(PS_INTERNET_HEADERS, &guid);
+	  nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
+	  SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+
+	  nameid[0].lpguid = guid;
+	  nameid[0].ulKind = MNID_STRING;
+	  nameid[0].kind.lpwstr.Name = NAMEDPROP_NAME;
+	  nameid[0].kind.lpwstr.NameSize = strlen(NAMEDPROP_NAME) * 2 + 2;
+	  retval = GetIDsFromNames(&obj_folder, 1, &nameid[0], MAPI_CREATE, &SPropTagArray);
+	  if (retval != MAPI_E_SUCCESS) return false;
+	  mapi_errstr("GetIDsFromNames", GetLastError());
+
+	  printf("%s mapped to 0x%.8x\n", NAMEDPROP_NAME, SPropTagArray->aulPropTag[0]);
+	  propID = SPropTagArray->aulPropTag[0] | PT_STRING8;
+
+	  talloc_free(nameid);
+	  talloc_free(SPropTagArray);
+	}
+
+	/*
+	 * Assign its value with SetProps and save changes
+	 */
+	{
+		struct SPropValue	props[1];
+		const char		*testval = NAMEDPROP_VALUE;
+
+		printf("\n\n5. Assigning %s to %s\n", NAMEDPROP_VALUE, NAMEDPROP_NAME);
+		
+		set_SPropValue_proptag(&props[0], propID, (const void *)testval);
+		retval = SetProps(&obj_message, props, 1);
+		if (retval != MAPI_E_SUCCESS) return false;
+		mapi_errstr("SetProps", GetLastError());
+		
+		retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+		mapi_errstr("SaveChangesMessage", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	printf("\n\n6. GetNamesFromIDs (Fetch torture_namedprops property)\n");
+	propID = (propID & 0xFFFF0000)| PT_NULL;
+	retval = GetNamesFromIDs(&obj_message, propID, &count, &nameid);
+	mapi_errstr("GetNamesFromIDs", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	switch (nameid->ulKind) {
+	case MNID_ID:
+		printf("\t0x%.8x mapped to 0x%.4x\n", 
+		       propID | (props_array.lpProps[i].ulPropTag & 0xFFFF), nameid->kind.lid);
+		break;
+	case MNID_STRING:
+		printf("\t0x%.8x mapped to %s\n",
+		       propID, nameid->kind.lpwstr.Name);
+		break;
+	}
+	talloc_free(nameid);
+
+	printf("\n\n7. GetProps (torture_namedprops property)\n");
+	propID = (propID & 0xFFFF0000) | PT_STRING8;
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, propID);
+	retval = GetProps(&obj_message, SPropTagArray, &propvals, &cn_propvals);
+	MAPIFreeBuffer(SPropTagArray);
+	mapi_errstr("GetProps", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapidump_SPropValue(propvals[0], "\t");
+	MAPIFreeBuffer(propvals);
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	/* Uninitialize MAPI */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+
+	return ret;
+}

Added: trunk/openchange/torture/mapi_newmail.c
===================================================================
--- trunk/openchange/torture/mapi_newmail.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_newmail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,122 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   New mail notifications
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+static int callback(uint32_t NotificationType, void *NotificationData, void *private_data)
+{
+	struct NewMailNotification	*newmail;
+
+	switch(NotificationType) {
+	case fnevNewMail:
+		printf("[+]New mail Received!!!!\n");
+		newmail = (struct NewMailNotification *) NotificationData;
+		mapidump_newmail(newmail, "\t");
+		break;
+	case fnevObjectCreated:
+		printf("[+]Object Created!!!\n");
+		break;
+	}
+
+	return 0;
+}
+
+bool torture_rpc_mapi_newmail(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	uint64_t		id_inbox;
+	uint32_t		ulEventMask;
+	uint32_t		ulConnection;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_newmail");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_inbox);
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Register notification */
+	retval = RegisterNotification(fnevTableModified);
+	mapi_errstr("RegisterNotification", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox */
+	retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* newmail and created|modified object notifications in inbox */
+	ulEventMask = fnevObjectCreated;
+	retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+	mapi_errstr("Subscribe", GetLastError());
+
+	ulEventMask = fnevNewMail;
+	retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+	mapi_errstr("Subscribe", GetLastError());
+
+
+	if (retval != MAPI_E_SUCCESS) return false;
+
+ 	/* wait for notifications */
+	MonitorNotification(mapi_object_get_session(&obj_inbox),(void *)&obj_store);
+
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_permissions.c
===================================================================
--- trunk/openchange/torture/mapi_permissions.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_permissions.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,133 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Test MAPI Permissions
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_permissions(struct torture_context *torture)
+{
+	NTSTATUS		ntstatus;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_table;
+	mapi_id_t		id_inbox;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*proptags;
+	uint32_t		i;
+	const char		*operation = lp_parm_string(torture->lp_ctx, NULL, "mapi", "operation");
+	const char		*role = lp_parm_string(torture->lp_ctx, NULL, "mapi", "role");
+	uint32_t		permission;
+	const char		*username = lp_parm_string(torture->lp_ctx, NULL, "mapi", "username");
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_permissions");
+	ntstatus = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(ntstatus)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the default inbox folder id */
+	retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_inbox);
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (!strncasecmp(operation, "add", strlen(operation))) {
+		permission = get_permission_from_name(role);
+		retval = AddUserPermission(&obj_inbox, username, permission);
+		mapi_errstr("AddUserPermission", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	if (!strncasecmp(operation, "modify", strlen(operation))) {
+		permission = get_permission_from_name(role);
+		retval = ModifyUserPermission(&obj_inbox, username, permission);
+		mapi_errstr("ModifyUserPermission", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	if (!strncasecmp(operation, "remove", strlen(operation))) {
+		retval = RemoveUserPermission(&obj_inbox, username);
+		mapi_errstr("RemoveUserPermission", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	if (!strncasecmp(operation, "list", strlen(operation))) {
+		mapi_object_init(&obj_table);
+		retval = GetTable(&obj_inbox, &obj_table);
+		mapi_errstr("GetTable", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		proptags = set_SPropTagArray(mem_ctx, 4,
+					     PR_MEMBER_ID,
+					     PR_MEMBER_NAME,
+					     PR_MEMBER_RIGHTS,
+					     PR_ENTRYID);
+		retval = SetColumns(&obj_table, proptags);
+		mapi_errstr("SetColumns", GetLastError());
+		MAPIFreeBuffer(proptags);
+		if (retval != MAPI_E_SUCCESS) return false;
+		
+		retval = QueryRows(&obj_table, 0x32, TBL_ADVANCE, &SRowSet);
+		mapi_errstr("QueryRows", GetLastError());
+		if (retval != MAPI_E_SUCCESS) return false;
+		
+		for (i = 0; i < SRowSet.cRows; i++) {
+			struct SPropValue *lpProp;
+			uint32_t *rights;
+
+			lpProp = get_SPropValue_SRow(&(SRowSet.aRow[i]), PR_MEMBER_NAME);
+			printf("    %-25s: %s\n", "Username", lpProp->value.lpszA ? lpProp->value.lpszA : "Default");
+			lpProp = get_SPropValue_SRow(&(SRowSet.aRow[i]), PR_MEMBER_RIGHTS);
+			rights = &(lpProp->value.l);
+			ndr_print_debug((ndr_print_fn_t)ndr_print_ACLRIGHTS, "Rights", (void *)rights);
+			printf("\n");
+		}
+		
+		mapi_object_release(&obj_table);
+	}
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	return true;
+}

Added: trunk/openchange/torture/mapi_recipient.c
===================================================================
--- trunk/openchange/torture/mapi_recipient.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_recipient.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,143 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Fetch emails recipients from an Exchange server Inbox
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+bool torture_rpc_mapi_recipient(struct torture_context *torture)
+{
+	NTSTATUS		ntstatus;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_table;
+	mapi_id_t		id_inbox;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	uint32_t		count = 0;
+	uint32_t		i;
+	uint32_t		j;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_recipient");
+	ntstatus = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(ntstatus)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* Open Message Store */
+	mapi_object_init(&obj_store);
+	retval  = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Get Receive Folder */
+	mapi_object_init(&obj_inbox);
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	mapi_errstr("GetReceiveFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Get Contents Table */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Customize table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+					  PR_FID,
+					  PR_MID,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	while (((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_store,
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     SRowSet.aRow[i].lpProps[1].value.d,
+					     &obj_message, 0);
+			if (GetLastError() != MAPI_E_NOT_FOUND) {
+				struct SRowSet		props;
+				struct SPropTagArray	proptags;
+
+				
+
+				retval = GetRecipientTable(&obj_message, &props, &proptags);
+				if (retval == MAPI_E_SUCCESS) {
+					if (SRowSet.aRow[i].lpProps[2].value.lpszA) {
+						printf("\n\nSubject: %s\n", SRowSet.aRow[i].lpProps[2].value.lpszA);
+						fflush(0);
+					}
+
+					printf("\nSPropTagArray:\n");
+					fflush(0);
+					mapidump_SPropTagArray(&proptags);
+
+					printf("\nSRowSet:\n");
+					fflush(0);
+
+					for (j = 0; j < props.cRows; j++) {
+						printf("===\n");
+						fflush(0);
+						mapidump_SRow(&props.aRow[j], "SRow: ");
+					}
+					
+					printf("\n\n");
+					fflush(0);
+				}
+				mapi_object_release(&obj_message);
+			}
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+
+	return true;
+}

Added: trunk/openchange/torture/mapi_restrictions.c
===================================================================
--- trunk/openchange/torture/mapi_restrictions.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_restrictions.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,374 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Test Restrictions
+
+   Copyright (C) Julien Kerihuel 2007 - 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/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#define	SAME_SUBJECT		"Same subject"
+#define	SAME_SUBJECT_BODY	"Same subject and body"
+#define	UNIQUE_BODY		"The secret word is OpenChange and is hidden"
+
+bool torture_create_environment(struct loadparm_context *lp_ctx,
+				TALLOC_CTX *mem_ctx, 
+				mapi_object_t *parent,
+				mapi_object_t *child)
+{
+	enum MAPISTATUS	retval;
+	char		*subject = NULL;
+	char		*body = NULL;
+	uint32_t	i;
+
+	/* Create the test directory */
+	mapi_object_init(child);
+	retval = CreateFolder(parent, FOLDER_GENERIC, 
+			      "torture_restrictions", 
+			      "MAPI restrictions torture test", 
+			      OPEN_IF_EXISTS, child);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("[+] torture restrictions directory created\n"));
+	
+	retval = EmptyFolder(child);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Send 5 mails with MSGFLAG_READ set */
+	for (i = 0; i < 5; i++) {
+		subject = talloc_asprintf(mem_ctx, "Subject: %s %d", 
+					  "MSGFLAG_READ: Sample mail", i);
+		retval = torture_simplemail_fromme(lp_ctx, child, subject, 
+						   "This is sample content", 
+						   MSGFLAG_READ|MSGFLAG_SUBMIT);
+		talloc_free(subject);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	DEBUG(0, ("[+] 5 mails created with MSGFLAG_READ set\n"));
+
+	/* Send 5 mails with MSGFLAG_UNREAD set */
+	for (i = 0; i < 5; i++) {
+		subject = talloc_asprintf(mem_ctx, "Subject: %s %d", 
+					  "Sample mail", i);
+		retval = torture_simplemail_fromme(lp_ctx, child, subject, 
+						   "This is sample content", 
+						   MSGFLAG_SUBMIT);
+		talloc_free(subject);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	DEBUG(0, ("[+] 5 unread mails created\n"));
+
+	/* Create 2 mails with the same subject */
+	for (i = 0; i < 2; i++) {
+		retval = torture_simplemail_fromme(lp_ctx, child, SAME_SUBJECT,
+						   "Different content",
+						   MSGFLAG_SUBMIT);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	DEBUG(0, ("[+] 2 mails unread with same subject but different body\n"));
+
+
+	/* Create 3 mails with the same subject and same body */
+	for (i = 0; i < 3; i++) {
+		retval = torture_simplemail_fromme(lp_ctx, child, SAME_SUBJECT_BODY,
+						   SAME_SUBJECT_BODY,
+						   MSGFLAG_SUBMIT);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	DEBUG(0, ("[+] 3 mails unread with same subject and body\n"));
+
+
+	/* Create 1 mail with a long body */
+	body = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+	retval = torture_simplemail_fromme(lp_ctx, child, "Long body", body, MSGFLAG_SUBMIT);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("[+] 1 mail with  body > 39 chars\n"));
+
+	/* Create 1 mail with a unique body content */
+	retval = torture_simplemail_fromme(lp_ctx, child, "Unique content", UNIQUE_BODY, MSGFLAG_SUBMIT);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("[+] 1 mail with  unique body: %s\n", UNIQUE_BODY));
+	
+
+	return true;
+}
+
+bool torture_rpc_mapi_restrictions(struct torture_context *torture)
+{
+	NTSTATUS			nt_status;
+	enum MAPISTATUS			retval;
+	struct dcerpc_pipe		*p;
+	TALLOC_CTX			*mem_ctx;
+	bool				ret = true;
+	struct mapi_session		*session;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_inbox;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_testdir;
+	mapi_id_t			id_inbox;
+	struct SPropTagArray		*SPropTagArray;
+	struct SRowSet			SRowSet;
+	struct SRowSet			SRowSet_row;
+	struct mapi_SRestriction	res;
+	uint32_t			total;
+	uint32_t			Numerator;
+	uint32_t			Denominator;
+	uint32_t			row_idx;
+	uint32_t			bookmark;
+
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_restrictions");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_table);
+
+	/* Open Message Store */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox folder */
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Create test environment */
+	if (torture_create_environment(torture->lp_ctx, mem_ctx, &obj_inbox, &obj_testdir) != true) {
+		return false;
+	}
+
+	/* Get Contents Table */
+	retval = GetContentsTable(&obj_testdir, &obj_table, 0, &total);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("Total number of mails = %d\n", total));
+
+	/* Filter contents table on subject */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_FLAGS);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\nStep 1. Test Restrict MAPI call\n"));
+	DEBUG(0, ("===============================\n"));
+
+	/* RES_PROPERTY test */
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RES_PROPERTY;
+	res.res.resProperty.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.value.lpszA = "Same subject";
+
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_PROPERTY\n"));
+	DEBUG(0, ("  -------------------------\n"));
+	DEBUG(0, ("\tFilter on PR_SUBJECT\n"));
+	DEBUG(0, (("\tCheck for subject eq \"%s\"\n"), SAME_SUBJECT));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+	/* RES_BITMASK test */
+	res.rt = RES_BITMASK;
+	res.res.resBitmask.relMBR = BMR_NEZ;
+	res.res.resBitmask.ulPropTag = PR_MESSAGE_FLAGS;
+	res.res.resBitmask.ulMask = MSGFLAG_READ;
+
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_BITMASK\n"));
+	DEBUG(0, ("  --------------------------\n"));
+	DEBUG(0, ("\tFilter on PR_MESSAGE_FLAG bitmask\n"));
+	DEBUG(0, ("\tCheck for all emails with MSGFLAG_READ set\n"));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+	/* RES_SIZE test */
+	res.rt = RES_SIZE;
+	res.res.resSize.relop = RELOP_GT;
+	res.res.resSize.ulPropTag = PR_BODY;
+	res.res.resSize.size = 30;
+
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_SIZE\n"));
+	DEBUG(0, ("  --------------------------\n"));
+	DEBUG(0, ("\tFilter on property size\n"));
+	DEBUG(0, ("\tCheck for all emails with PR_BODY size > 30 chars\n"));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+	/* RES_EXIST test */
+	res.rt = RES_EXIST;
+	res.res.resExist.ulPropTag = PR_HTML;
+
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_EXIST\n"));
+	DEBUG(0, ("  --------------------------\n"));
+	DEBUG(0, ("\tFilter on an existing property\n"));
+	DEBUG(0, ("\tCheck for all emails with PR_HTML\n"));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+
+	/* RES_COMPAREPROPS */
+	res.rt = RES_COMPAREPROPS;
+	res.res.resCompareProps.relop = RELOP_EQ;
+	res.res.resCompareProps.ulPropTag1 = PR_BODY;
+	res.res.resCompareProps.ulPropTag2 = PR_SUBJECT;
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_COMPAREPROPS\n"));
+	DEBUG(0, ("  --------------------------\n"));
+	DEBUG(0, ("\tFilter on properties comparison\n"));
+	DEBUG(0, ("\tCheck for all emails with PR_SUBJECT == PR_BODY\n"));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+	/* RES_CONTENT */
+	res.rt = RES_CONTENT;
+	res.res.resContent.fuzzy = FL_SUBSTRING|FL_LOOSE;
+	res.res.resContent.ulPropTag = PR_BODY;
+	res.res.resContent.lpProp.ulPropTag = PR_BODY;
+	res.res.resContent.lpProp.value.lpszA = "openchange";
+	retval = Restrict(&obj_table, &res, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = QueryPosition(&obj_table, &Numerator, &Denominator);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no Restriction: RES_CONTENT\n"));
+	DEBUG(0, ("  --------------------------\n"));
+	DEBUG(0, ("\tFilter on insensitive substring within content\n"));
+	DEBUG(0, ("\tCheck for all emails with PR_SUBJECT contained \"openchange\"\n"));
+	DEBUG(0, ("\tCursor is at %d / %d\n", Numerator, Denominator));
+
+	/* We now test the FindRow MAPI call */
+
+	DEBUG(0, ("\nStep 2. Test FindRow MAPI call\n"));
+	DEBUG(0, ("==============================\n"));
+
+	/* Approximatively position at half the contents table */
+	retval = SeekRowApprox(&obj_table, 1, 2);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Create a bookmark */
+	retval = CreateBookmark(&obj_table, &bookmark);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch row data */
+	retval = QueryRows(&obj_table, 1, TBL_NOADVANCE, &SRowSet_row);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Position table cursor to the beginning of the table */
+	retval = SeekRow(&obj_table, BOOKMARK_BEGINNING, 0, &row_idx);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	res.rt = RES_CONTENT;
+	res.res.resContent.fuzzy = FL_SUBSTRING|FL_LOOSE;
+	res.res.resContent.ulPropTag = PR_BODY;
+	res.res.resContent.lpProp.ulPropTag = PR_BODY;
+	res.res.resContent.lpProp.value.lpszA = "openchange";
+	retval = FindRow(&obj_table, &res, 0, 0, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	DEBUG(0, ("\no FindRow: RES_CONTENT\n"));
+	DEBUG(0, ("----------------------\n"));
+	mapidump_SRowSet(&SRowSet, "\t[+] ");
+	MAPIFreeBuffer(SRowSet.aRow);
+
+	DEBUG(0, ("\n"));
+	mapi_object_bookmark_debug(&obj_table);
+
+	retval = FindRow(&obj_table, &res, bookmark, 0, &SRowSet);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("\no FindRow: RES_CONTENT BOOKMARK_USER (%.2d)\n", bookmark));
+	DEBUG(0, ("--------------------------------------------\n"));
+	mapidump_SRowSet(&SRowSet, "\t[+] ");
+	DEBUG(0, ("=============\n"));
+	mapidump_SRowSet(&SRowSet_row, "\t[+] ");
+	
+	if (SRowSet.aRow[0].lpProps[1].value.d == SRowSet_row.aRow[0].lpProps[1].value.d) {
+		DEBUG(0, ("PR_MID matches\n"));
+	}
+	MAPIFreeBuffer(SRowSet.aRow);
+
+	/* Clean up test environment */
+	retval = EmptyFolder(&obj_testdir);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("\n[+] Removing messages from testdir\n"));
+
+	retval = DeleteFolder(&obj_inbox, mapi_object_get_id(&obj_testdir), 
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+	DEBUG(0, ("[+] Deleting testdir folder\n"));
+
+	/* release mapi objects */
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_sendappointment.c
===================================================================
--- trunk/openchange/torture/mapi_sendappointment.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendappointment.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,180 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Send appointments to an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#include <time.h>
+
+#define	DATE_FORMAT "%Y-%m-%d %H:%M:%S"
+
+#define CN_PROPS 14
+
+bool torture_rpc_mapi_sendappointment(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*appointment = lp_parm_string(torture->lp_ctx, NULL, "mapi", "appointment");
+	const char		*body = lp_parm_string(torture->lp_ctx, NULL, "mapi", "body");
+	const char		*location = lp_parm_string(torture->lp_ctx, NULL, "mapi", "location");
+	const char		*start = lp_parm_string(torture->lp_ctx, NULL, "mapi", "start");
+	const char		*end = lp_parm_string(torture->lp_ctx, NULL, "mapi", "end");
+	uint32_t		busy_status = lp_parm_int(torture->lp_ctx, NULL, "mapi", "busystatus", 0);
+	uint32_t		label = lp_parm_int(torture->lp_ctx, NULL, "mapi", "label", 0);
+	struct mapi_session	*session;
+	uint64_t		id_calendar;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_calendar;
+	mapi_object_t		obj_message;
+	struct SPropValue	props[CN_PROPS];
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray;
+	NTTIME			nt;
+	struct tm		tm;
+	struct FILETIME		*start_date;
+	struct FILETIME		*end_date;
+	uint32_t		flag;
+	uint8_t			flag2;
+
+	if (!appointment) return false;
+	if (busy_status > 3) return false;
+	if (!start || !end) return false;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sendappointment");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_calendar);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = GetDefaultFolder(&obj_store, &id_calendar, olFolderCalendar);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the calendar folder */
+	retval = OpenFolder(&obj_store, id_calendar, &obj_calendar);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the calendar folder */
+	retval = CreateMessage(&obj_calendar, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Build the list of named properties we want to set */
+	nameid = mapi_nameid_new(mem_ctx);
+	mapi_nameid_OOM_add(nameid, "Location", PSETID_Appointment);
+	mapi_nameid_OOM_add(nameid, "BusyStatus", PSETID_Appointment);
+	mapi_nameid_OOM_add(nameid, "ApptStateFlags", PSETID_Appointment);
+	mapi_nameid_OOM_add(nameid, "CommonStart", PSETID_Common);
+	mapi_nameid_OOM_add(nameid, "CommonEnd", PSETID_Common);
+	mapi_nameid_OOM_add(nameid, "Label", PSETID_Appointment);
+	mapi_nameid_OOM_add(nameid, "ReminderDelta", PSETID_Common);
+
+	/* GetIDsFromNames and map property types */
+	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = GetIDsFromNames(&obj_calendar, nameid->count,
+				 nameid->nameid, 0, &SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+
+	if (!strptime(start, DATE_FORMAT, &tm)) {
+		printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.: 2007-09-17 10:00:00)\n");
+		return false;
+	}
+	unix_to_nt_time(&nt, mktime(&tm));
+	start_date = talloc(mem_ctx, struct FILETIME);
+	start_date->dwLowDateTime = (nt << 32) >> 32;
+	start_date->dwHighDateTime = (nt >> 32);
+
+	if (!strptime(end, DATE_FORMAT, &tm)) {
+		printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.:2007-09-17 18:30:00)\n");
+		return false;
+	}
+	unix_to_nt_time(&nt, mktime(&tm));
+	end_date = talloc(mem_ctx, struct FILETIME);
+	end_date->dwLowDateTime = (nt << 32) >> 32;
+	end_date->dwHighDateTime = (nt >> 32);
+
+	set_SPropValue_proptag(&props[0], PR_CONVERSATION_TOPIC, 
+						   (const void *) appointment);
+	set_SPropValue_proptag(&props[1], PR_NORMALIZED_SUBJECT, 
+						   (const void *) appointment);
+	set_SPropValue_proptag(&props[2], PR_START_DATE, (const void *) start_date);
+	set_SPropValue_proptag(&props[3], PR_END_DATE, (const void *) end_date);
+	set_SPropValue_proptag(&props[4], PR_MESSAGE_CLASS, (const void *)"IPM.Appointment");
+	flag = 1;
+	set_SPropValue_proptag(&props[5], PR_MESSAGE_FLAGS, (const void *) &flag);
+	set_SPropValue_proptag(&props[6], SPropTagArray->aulPropTag[0], (const void *)(location?location:""));
+	set_SPropValue_proptag(&props[7], SPropTagArray->aulPropTag[1], (const void *) &busy_status);
+	flag= MEETING_STATUS_NONMEETING;
+	set_SPropValue_proptag(&props[8], SPropTagArray->aulPropTag[2], (const void *) &flag);
+	flag2 = true;
+	set_SPropValue_proptag(&props[9], SPropTagArray->aulPropTag[3], (const void *) start_date);
+	set_SPropValue_proptag(&props[10], SPropTagArray->aulPropTag[4], (const void *) end_date);
+	set_SPropValue_proptag(&props[11], SPropTagArray->aulPropTag[5], (const void *)&label);
+	flag = 30;
+	set_SPropValue_proptag(&props[12], SPropTagArray->aulPropTag[6], (const void *)&flag);
+	set_SPropValue_proptag(&props[13], PR_BODY, (const void *)(body?body:""));
+	retval = SetProps(&obj_message, props, CN_PROPS);
+	mapi_errstr("SetProps", GetLastError());
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+
+	retval = SaveChangesMessage(&obj_calendar, &obj_message, KeepOpenReadOnly);
+	mapi_errstr("SaveChangesMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+
+	mapi_object_release(&obj_calendar);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_sendattach.c
===================================================================
--- trunk/openchange/torture/mapi_sendattach.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendattach.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,236 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Send attach to an Exchange server
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+#define CN_MSG_PROPS 3
+
+bool torture_rpc_mapi_sendattach(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*subject = lp_parm_string(torture->lp_ctx, NULL, "mapi", "subject");
+	const char		*body = lp_parm_string(torture->lp_ctx, NULL, "mapi", "body");
+	const char		*filename = lp_parm_string(torture->lp_ctx, NULL, "mapi", "attachment");
+	const char		**usernames;
+	const char		**usernames_to;
+	const char		**usernames_cc;
+	const char		**usernames_bcc;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_outbox;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_attach;
+	mapi_object_t		obj_stream;
+	uint64_t		id_outbox;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	uint32_t		index = 0;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	SPropValue;
+	struct SPropValue	props_attach[3];
+	unsigned long		cn_props_attach;
+	struct SPropValue	props[CN_MSG_PROPS];
+	uint32_t		msgflag;
+	DATA_BLOB		blob;
+
+	/* get the attachment filename */
+	if (!filename) {
+		DEBUG(0, ("No filename specified with mapi:attachment\n"));
+		return false;
+	}
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sendmail");
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_outbox);
+	mapi_object_init(&obj_message);
+	mapi_object_init(&obj_attach);
+
+	/* default if null */
+	if (subject == 0) subject = "";
+	if (body == 0) body = "";
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* id_outbox = store->GeOutboxFolder() */
+	retval = GetOutboxFolder(&obj_store, &id_outbox);
+	mapi_errstr("GetOutboxFodler", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* outbox = store->OpenFolder(id_outbox) */
+	retval = OpenFolder(&obj_store, id_outbox, &obj_outbox);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* message = outbox->CreateMessage() */
+	retval = CreateMessage(&obj_outbox, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	usernames_to = get_cmdline_recipients(mem_ctx, "to");
+	usernames_cc = get_cmdline_recipients(mem_ctx, "cc");
+	usernames_bcc = get_cmdline_recipients(mem_ctx, "bcc");
+	usernames = collapse_recipients(mem_ctx, usernames_to, usernames_cc, usernames_bcc);
+
+	retval = ResolveNames(mapi_object_get_session(&obj_outbox), usernames, 
+			      SPropTagArray, &SRowSet, &flaglist, 0);
+	mapi_errstr("ResolveNames", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (!SRowSet) {
+	  SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_to, flaglist, MAPI_TO);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_cc, flaglist, MAPI_CC);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_bcc, flaglist, MAPI_BCC);
+
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, &SRowSet[0], SPropValue);
+
+	/* message->ModifyRecipients() */
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapi_errstr("ModifyRecipients", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	retval = MAPIFreeBuffer(SRowSet);
+	mapi_errstr("MAPIFreeBuffer: SRowSet", GetLastError());
+
+	retval = MAPIFreeBuffer(flaglist);
+	mapi_errstr("MAPIFreeBuffer: flaglist", GetLastError());
+
+	/* message->SetProps()
+	 */
+	msgflag = MSGFLAG_UNSENT;
+	set_SPropValue_proptag(&props[0], PR_SUBJECT, (const void *)subject);
+	set_SPropValue_proptag(&props[1], PR_BODY, (const void *)body);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_FLAGS, (const void *)&msgflag);
+	retval = SetProps(&obj_message, props, CN_MSG_PROPS);
+	mapi_errstr("SetProps", GetLastError());
+
+	/* CreateAttach */
+	retval = CreateAttach(&obj_message, &obj_attach);
+	mapi_errstr("CreateAttach", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* send by value */
+	props_attach[0].ulPropTag = PR_ATTACH_METHOD;
+	props_attach[0].value.l = ATTACH_BY_VALUE;
+	props_attach[1].ulPropTag = PR_RENDERING_POSITION;
+	props_attach[1].value.l = 0;
+	props_attach[2].ulPropTag = PR_ATTACH_FILENAME;
+	props_attach[2].value.lpszA = get_filename(filename);
+	cn_props_attach = 3;
+
+	/* SetProps */
+	retval = SetProps(&obj_attach, props_attach, cn_props_attach);
+	mapi_errstr("SetProps", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* OpenStream on CreateAttach handle */
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
+	mapi_errstr("OpenStream", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* WriteStream */
+	{
+		int		fd;
+		struct stat	sb;
+		uint32_t	read_size;
+		uint16_t	buf_readsize;
+		uint8_t		buf[0x7000];
+
+		if (stat(filename, &sb) != 0) return false;
+
+		if ((fd = open(filename, O_RDONLY)) == -1) {
+			DEBUG(0, ("Error while opening %s\n", filename));
+			return false;
+		}
+	
+		while ((read_size = read(fd, buf, 0x4000))) {
+			/* We reset errno due to read */
+			blob.length = read_size;
+			blob.data = talloc_size(mem_ctx, read_size);
+			memcpy(blob.data, buf, read_size);
+			
+			errno = 0;
+			retval = WriteStream(&obj_stream, &blob, &buf_readsize);
+			mapi_errstr("WriteStream", GetLastError());
+			talloc_free(blob.data);
+		}
+		close(fd);
+	}
+
+	/* message->SaveChangesAttachment() */
+	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+	mapi_errstr("SaveChangesAttachment", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* message->SubmitMessage() */
+	retval = SubmitMessage(&obj_message);
+	mapi_errstr("SubmitMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* objects->Release()
+	 */
+	mapi_object_release(&obj_attach);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_outbox);
+	mapi_object_release(&obj_store);
+	
+	/* session::Uninitialize()
+	 */
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+	return ret;
+}

Added: trunk/openchange/torture/mapi_sendcontacts.c
===================================================================
--- trunk/openchange/torture/mapi_sendcontacts.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendcontacts.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,127 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Send contacts to an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_sendcontacts(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*cardname = lp_parm_string(torture->lp_ctx, NULL, "mapi", "cardname");
+	const char		*fullname = lp_parm_string(torture->lp_ctx, NULL, "mapi", "fullname");
+	struct mapi_session	*session;
+	uint64_t		id_contacts;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_contacts;
+	mapi_object_t		obj_table;
+	mapi_object_t		obj_message;
+	struct SPropValue	props[5];
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray;
+
+	if (!cardname) return false;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchmail");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_contacts);
+	mapi_object_init(&obj_table);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the contacts Folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_contacts, olFolderContacts);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the contacts folder */
+	retval = OpenFolder(&obj_store, id_contacts, &obj_contacts);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the contacts folder */
+	retval = CreateMessage(&obj_contacts, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Build the list of named properties we want to set */
+	nameid = mapi_nameid_new(mem_ctx);
+	mapi_nameid_OOM_add(nameid, "FileUnder", PSETID_Address);
+	mapi_nameid_string_add(nameid, "urn:schemas:contacts:fileas", PS_PUBLIC_STRINGS);
+
+
+	/* GetIDsFromNames and map property types */
+	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = GetIDsFromNames(&obj_contacts, nameid->count,
+				 nameid->nameid, 0, &SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+
+	set_SPropValue_proptag(&props[0], SPropTagArray->aulPropTag[0], (const void *) cardname);
+	set_SPropValue_proptag(&props[1], PR_DISPLAY_NAME, (const void *) fullname);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_CLASS, (const void *)"IPM.Contact");
+	set_SPropValue_proptag(&props[3], PR_NORMALIZED_SUBJECT, (const void *) cardname);
+	set_SPropValue_proptag(&props[4], SPropTagArray->aulPropTag[1], (const void *) cardname);
+	retval = SetProps(&obj_message, props, 5);
+	mapi_errstr("SetProps", GetLastError());
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = SaveChangesMessage(&obj_contacts, &obj_message, KeepOpenReadOnly);
+	mapi_errstr("SaveChangesMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_contacts);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_sendmail.c
===================================================================
--- trunk/openchange/torture/mapi_sendmail.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendmail.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,165 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Send emails to an Exchange server
+
+   Copyright (C) Julien Kerihuel 2007.
+   Copyright (C) Fabien Le Mentec 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+
+#define CN_MSG_PROPS 3
+
+bool torture_rpc_mapi_sendmail(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*subject = lp_parm_string(torture->lp_ctx, NULL, "mapi", "subject");
+	const char		*body = lp_parm_string(torture->lp_ctx, NULL, "mapi", "body");
+	const char		**usernames;
+	const char		**usernames_to;
+	const char		**usernames_cc;
+	const char		**usernames_bcc;
+	uint32_t		index = 0;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_outbox;
+	mapi_id_t		id_outbox;
+	struct mapi_session	*session;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	SPropValue;
+	struct SPropValue	props[CN_MSG_PROPS];
+	uint32_t		msgflag;
+
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sendmail");
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* default if null */
+	if (subject == NULL) subject = "";
+	if (body == NULL) body = "";
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_outbox);
+	mapi_object_init(&obj_message);
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the outbox folder id */
+	retval = GetDefaultFolder(&obj_store, &id_outbox, olFolderTopInformationStore);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* outbox = store->OpenFolder(id_outbox) */
+	retval = OpenFolder(&obj_store, id_outbox, &obj_outbox);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* message = outbox->CreateMessage() */
+	retval = CreateMessage(&obj_outbox, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	usernames_to = get_cmdline_recipients(mem_ctx, "to");
+	usernames_cc = get_cmdline_recipients(mem_ctx, "cc");
+	usernames_bcc = get_cmdline_recipients(mem_ctx, "bcc");
+	usernames = collapse_recipients(mem_ctx, usernames_to, usernames_cc, usernames_bcc);
+
+	/* ResolveNames */
+	retval = ResolveNames(mapi_object_get_session(&obj_store), usernames, 
+			      SPropTagArray, &SRowSet, &flaglist, 0);
+	mapi_errstr("ResolveNames", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	if (!SRowSet) {
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+	
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_to, flaglist, MAPI_TO);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_cc, flaglist, MAPI_CC);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_bcc, flaglist, MAPI_BCC);
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, SRowSet, SPropValue);
+	
+	/* ModifyRecipients */
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapi_errstr("ModifyRecipients", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = MAPIFreeBuffer(SRowSet);
+	mapi_errstr("MAPIFreeBuffer: SRowSet", GetLastError());
+
+	retval = MAPIFreeBuffer(flaglist);
+	mapi_errstr("MAPIFreeBuffer: flaglist", GetLastError());
+
+	/* message->SetProps() */
+	msgflag = MSGFLAG_UNSENT;
+	set_SPropValue_proptag(&props[0], PR_SUBJECT, (const void *)subject);
+	set_SPropValue_proptag(&props[1], PR_BODY, (const void *)body);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_FLAGS, (const void *)&msgflag);
+
+	retval = SetProps(&obj_message, props, CN_MSG_PROPS);
+	mapi_errstr("SetProps", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* message->SubmitMessage()
+	 */
+	retval = SubmitMessage(&obj_message);
+	mapi_errstr("SubmitMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* objects->Release()
+	 */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_outbox);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+
+	return ret;
+}

Added: trunk/openchange/torture/mapi_sendmail_html.c
===================================================================
--- trunk/openchange/torture/mapi_sendmail_html.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendmail_html.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,183 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Send attachments to an Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+bool torture_rpc_mapi_sendmail_html(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*subject = lp_parm_string(torture->lp_ctx, NULL, "mapi", "subject");
+	const char		*body = lp_parm_string(torture->lp_ctx, NULL, "mapi", "body");
+	const char		*filename = lp_parm_string(torture->lp_ctx, NULL, "mapi", "html");
+	const char		**usernames;
+	const char		**usernames_to;
+	const char		**usernames_cc;
+	const char		**usernames_bcc;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_outbox;
+	mapi_object_t		obj_message;
+	uint64_t		id_outbox;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	uint32_t		index = 0;
+	struct SPropTagArray	*SPropTagArray;
+	struct SBinary_short	html;
+	struct SPropValue	SPropValue;
+	struct SPropValue	props[3];
+	uint32_t		msgflag;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sendmail");
+
+	/* get the attachment filename */
+	if (!filename) {
+		DEBUG(0, ("No filename specified with mapi:html\n"));
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_outbox);
+	mapi_object_init(&obj_message);
+
+	/* default if null */
+	if (subject == 0) subject = "";
+	if (body == 0) body = "";
+
+	/* session::OpenMsgStore() */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* id_outbox = store->GeOutboxFolder() */
+	retval = GetOutboxFolder(&obj_store, &id_outbox);
+	mapi_errstr("GetOutboxFodler", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* outbox = store->OpenFolder(id_outbox) */
+	retval = OpenFolder(&obj_store, id_outbox, &obj_outbox);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* message = outbox->CreateMessage() */
+	retval = CreateMessage(&obj_outbox, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME_UNICODE,
+					  PR_DISPLAY_NAME_UNICODE,
+					  PR_SMTP_ADDRESS_UNICODE,
+					  PR_GIVEN_NAME_UNICODE);
+
+	usernames_to = get_cmdline_recipients(mem_ctx, "to");
+	usernames_cc = get_cmdline_recipients(mem_ctx, "cc");
+	usernames_bcc = get_cmdline_recipients(mem_ctx, "bcc");
+	usernames = collapse_recipients(mem_ctx, usernames_to, usernames_cc, usernames_bcc);
+
+	retval = ResolveNames(mapi_object_get_session(&obj_store), (const char **)usernames, 
+			      SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
+	mapi_errstr("ResolveNames", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (!SRowSet) {
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_to, flaglist, MAPI_TO);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_cc, flaglist, MAPI_CC);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, usernames_bcc, flaglist, MAPI_BCC);
+
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, &SRowSet[0], SPropValue);
+
+	/* message->ModifyRecipients() */
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapi_errstr("ModifyRecipients", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	retval = MAPIFreeBuffer(SRowSet);
+	mapi_errstr("MAPIFreeBuffer: SRowSet", GetLastError());
+
+	retval = MAPIFreeBuffer(flaglist);
+	mapi_errstr("MAPIFreeBuffer: flaglist", GetLastError());
+
+	/* message->SetProps()
+	 */
+
+	{
+		struct stat	sb;
+		int		fd;
+
+		if (stat(filename, &sb) != 0) return false;
+		if ((fd = open(filename, O_RDONLY)) == -1) {
+			DEBUG(0, ("Error while opening %s\n", filename));
+			return false;
+		}
+		html.lpb = talloc_size(mem_ctx, sb.st_size);
+		html.cb = read(fd, html.lpb, sb.st_size);
+		close(fd);
+	}
+
+	msgflag = MSGFLAG_UNSENT;
+	set_SPropValue_proptag(&props[0], PR_SUBJECT, (const void *)subject);
+	set_SPropValue_proptag(&props[1], PR_HTML, (const void *)&html);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_FLAGS, (const void *)&msgflag);
+	retval = SetProps(&obj_message, props, 3);
+	mapi_errstr("SetProps", GetLastError());
+
+	/* message->SubmitMessage() */
+	retval = SubmitMessage(&obj_message);
+	mapi_errstr("SubmitMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* objects->Release()
+	 */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_outbox);
+	mapi_object_release(&obj_store);
+	
+	/* session::Uninitialize()
+	 */
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+	return ret;
+}

Added: trunk/openchange/torture/mapi_sendtasks.c
===================================================================
--- trunk/openchange/torture/mapi_sendtasks.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sendtasks.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,128 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Create a task on Exchange server
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+#define	CN_PROPS 5
+
+bool torture_rpc_mapi_sendtasks(struct torture_context *torture)
+{
+	NTSTATUS		nt_status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	bool			ret = true;
+	const char		*task = lp_parm_string(torture->lp_ctx, NULL, "mapi", "task");
+	uint32_t		priority = lp_parm_int(torture->lp_ctx, NULL, "mapi", "priority", 0);
+	uint32_t		status = lp_parm_int(torture->lp_ctx, NULL, "mapi", "status", 0);
+	struct mapi_session	*session;
+	uint64_t		id_task;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_task;
+	mapi_object_t		obj_table;
+	mapi_object_t		obj_message;
+	struct SPropValue	props[CN_PROPS];
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray;
+
+	if (!task) return false;
+
+	/* init torture */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_fetchmail");
+	nt_status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* init objects */
+	mapi_object_init(&obj_store);
+	mapi_object_init(&obj_task);
+	mapi_object_init(&obj_table);
+
+	/* session::OpenMsgStore */
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the task Folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_task, olFolderTasks);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* We now open the task folder */
+	retval = OpenFolder(&obj_store, id_task, &obj_task);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Operations on the task folder */
+	retval = CreateMessage(&obj_task, &obj_message);
+	mapi_errstr("CreateMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Build the list of named properties we want to set */
+	nameid = mapi_nameid_new(mem_ctx);
+	mapi_nameid_OOM_add(nameid, "TaskStatus", PSETID_Task);
+
+	/* GetIDsFromNames and map property types */
+	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = GetIDsFromNames(&obj_task, nameid->count,
+				 nameid->nameid, 0, &SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+
+	set_SPropValue_proptag(&props[0], PR_CONVERSATION_TOPIC, (const void *) task);
+	set_SPropValue_proptag(&props[1], PR_NORMALIZED_SUBJECT, (const void *) task);
+	set_SPropValue_proptag(&props[2], PR_MESSAGE_CLASS, (const void *)"IPM.Task");
+	set_SPropValue_proptag(&props[3], PR_PRIORITY, (const void *)&priority);
+	set_SPropValue_proptag(&props[4], SPropTagArray->aulPropTag[0], (const void *)&status);
+	retval = SetProps(&obj_message, props, CN_PROPS);
+	mapi_errstr("SetProps", GetLastError());
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = SaveChangesMessage(&obj_task, &obj_message, KeepOpenReadOnly);
+	mapi_errstr("SaveChangesMessage", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_task);
+	mapi_object_release(&obj_store);
+
+	/* uninitialize mapi
+	 */
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	
+	return (ret);
+}

Added: trunk/openchange/torture/mapi_sorttable.c
===================================================================
--- trunk/openchange/torture/mapi_sorttable.c	                        (rev 0)
+++ trunk/openchange/torture/mapi_sorttable.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,121 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Tables related operations torture
+
+   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 <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_mapi_sorttable(struct torture_context *torture)
+{
+	enum MAPISTATUS		retval;
+	TALLOC_CTX		*mem_ctx;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		id_folder;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	struct SSortOrderSet	criteria;
+	struct mapi_session	*session;
+	uint32_t		count;
+	uint32_t		i;
+
+	/* init torture test */
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_mapi_sorttable");
+	if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
+
+	/* Open Message Store*/
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	mapi_errstr("OpenMsgStore", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve Inbox folder ID */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapi_errstr("GetDefaultFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox Folder */
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapi_errstr("OpenFolder", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Retrieve the Contents Table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
+	mapi_errstr("GetContentsTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Customize the contents table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_SUBJECT, PR_LAST_MODIFICATION_TIME);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapi_errstr("SetColumns", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Browse and print table content */
+	printf("\nBefore SortTable ASCENDING:\n");
+	while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
+	       SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		
+		for (i = 0; i < SRowSet.cRows; i++) {
+			printf("\t[%d] %s\n", i, SRowSet.aRow[i].lpProps[0].value.lpszA);
+		}
+	}
+
+	/* SortTable */
+	memset(&criteria, 0x0, sizeof (struct SSortOrderSet));
+	criteria.cSorts = 1;
+	criteria.aSort = talloc_array(mem_ctx, struct SSortOrder, criteria.cSorts);
+	criteria.aSort[0].ulPropTag = PR_LAST_MODIFICATION_TIME;
+	criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND;
+	retval = SortTable(&obj_ctable, &criteria);
+	mapi_errstr("SortTable", GetLastError());
+
+	/* SeekRow at beginning */
+	retval = SeekRow(&obj_ctable, BOOKMARK_BEGINNING, 0, &count);
+	mapi_errstr("SeekRow", GetLastError());
+
+	/* Browse and print table content */
+	printf("\nAfter SortTable ASCENDING:\n");
+	while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
+	       SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		
+		for (i = 0; i < SRowSet.cRows; i++) {
+			printf("\t[%d] %s\n", i, SRowSet.aRow[i].lpProps[0].value.lpszA);
+		}
+	}
+
+
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}

Added: trunk/openchange/torture/mapi_torture.h
===================================================================
--- trunk/openchange/torture/mapi_torture.h	                        (rev 0)
+++ trunk/openchange/torture/mapi_torture.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,65 @@
+/*
+   OpenChange MAPI torture suite 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/>.
+ */
+
+#ifndef __MAPI_TORTURE_H__
+#define	__MAPI_TORTURE_H__
+
+#include <ldb.h>
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+#ifndef	MAX
+#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
+#endif
+
+__BEGIN_DECLS
+
+int samdb_msg_add_string(struct ldb_context *, TALLOC_CTX *, 
+			 struct ldb_message *, const char *, const char *);
+int samdb_replace(struct ldb_context *, TALLOC_CTX *, struct ldb_message *);
+struct dom_sid *dom_sid_add_rid(TALLOC_CTX *,  const struct dom_sid *, uint32_t);
+bool encode_pw_buffer(uint8_t buffer[516], const char *, int);
+void arcfour_crypt_blob(uint8_t *, int, const DATA_BLOB *);
+
+__END_DECLS
+
+#define	DEFAULT_PROFDB_PATH	"%s/.openchange/profiles.ldb"
+
+struct test_join {
+	struct dcerpc_pipe		*p;
+	struct policy_handle		user_handle;
+	struct libnet_JoinDomain	*libnet_r;
+	struct dom_sid			*dom_sid;
+	const char			*dom_netbios_name;
+	const char			*dom_dns_name;
+	struct dom_sid			*user_sid;
+	struct GUID			user_guid;
+	const char			*netbios_name;
+};
+
+
+#endif /* __MAPI_TORTURE_H__ */

Added: trunk/openchange/torture/nspi_profile.c
===================================================================
--- trunk/openchange/torture/nspi_profile.c	                        (rev 0)
+++ trunk/openchange/torture/nspi_profile.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,278 @@
+/*
+   OpenChange NSPI torture suite implementation.
+
+   Create a MAPI profile
+
+   Copyright (C) Julien Kerihuel 2005 - 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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool set_profile_attribute(const char *profname, struct SRowSet rowset, 
+			   uint32_t property, const char *attr)
+{
+	struct SPropValue	*lpProp;
+	enum MAPISTATUS		ret;
+
+	lpProp = get_SPropValue_SRowSet(&rowset, property);
+
+	if (!lpProp) {
+		DEBUG(0, ("MAPI Property %s not set\n", attr));
+		return true;
+	}
+
+	ret = mapi_profile_add_string_attr(profname, attr, lpProp->value.lpszA);
+
+	if (ret != MAPI_E_SUCCESS) {
+		DEBUG(0, ("Problem adding attribute %s in profile %s\n", attr, profname));
+		return false;
+	}
+	return true;
+}
+
+bool set_profile_mvstr_attribute(const char *profname, struct SRowSet rowset,
+				 uint32_t property, const char *attr)
+{
+	struct SPropValue	*lpProp;
+	enum MAPISTATUS		ret;
+	int			i;
+
+	lpProp = get_SPropValue_SRowSet(&rowset, property);
+
+	if (!lpProp) {
+		DEBUG(0, ("MAPI Property %s not set\n", attr));
+		return true;
+	}
+
+	for (i = 0; i < lpProp->value.MVszA.cValues; i++) {
+		ret = mapi_profile_add_string_attr(profname, attr, lpProp->value.MVszA.lppszA[i]);
+		if (ret != MAPI_E_SUCCESS) {
+			DEBUG(0, ("Problem adding attriute %s in profile %s\n", attr, profname));
+			return false;
+		}
+	}
+	return true;
+}
+
+bool torture_rpc_nspi_profile(struct torture_context *torture)
+{
+	NTSTATUS		status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe	*p;
+	TALLOC_CTX		*mem_ctx;
+	struct nspi_context	*nspi;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropTagArray	*MIds = NULL;
+	struct SPropTagArray	MIds2;
+	struct SPropTagArray	*MId_server = NULL;
+	struct StringsArray_r	pNames;
+	struct Restriction_r	Filter;
+	struct SRowSet		*rowset;
+	struct SPropValue	*lpProp;
+	const char		*profname = lp_parm_string(torture->lp_ctx, NULL, "mapi", "profile");
+	const char		*profdb = lp_parm_string(torture->lp_ctx, NULL, "mapi", "profile_store");
+	uint32_t		codepage = lp_parm_int(torture->lp_ctx, NULL, "mapi", "codepage", 0);
+	uint32_t		language = lp_parm_int(torture->lp_ctx, NULL, "mapi", "language", 0);
+	uint32_t		method = lp_parm_int(torture->lp_ctx, NULL, "mapi", "method", 0);
+	const char		*username = NULL;
+	uint32_t		instance_key = 0;
+
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_nspi_profile");
+	
+	status = torture_rpc_connection(torture, &p, &ndr_table_exchange_nsp);
+
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+
+		return false;
+	}
+
+	/* profiles */
+	retval = MAPIInitialize(profdb);
+	mapi_errstr("MAPIInitialize", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	nspi = nspi_bind(mem_ctx, p, cmdline_credentials, codepage, language, method);
+	if (!nspi) return false;
+	
+	if (profname) {
+		const char *username = cli_credentials_get_username(cmdline_credentials);
+		const char *password = cli_credentials_get_password(cmdline_credentials);
+		
+		retval = CreateProfile(profname, username, password, 0);
+		mapi_errstr("CreateProfile", GetLastError());
+		if (retval != MAPI_E_SUCCESS) {
+			DEBUG(0, ("Unable to create %s profile\n", profname));
+			return false;
+		}
+		{
+			const char *workstation = cli_credentials_get_workstation(cmdline_credentials);
+			const char *domain = cli_credentials_get_domain(cmdline_credentials);
+			const char *binding = lp_parm_string(torture->lp_ctx, 
+												 NULL, "torture", "binding");
+			struct dcerpc_binding *dcerpc_binding;
+			char *p_codepage = talloc_asprintf(mem_ctx, "0x%x", codepage);
+			char *p_language = talloc_asprintf(mem_ctx, "0x%x", language);
+			char *p_method = talloc_asprintf(mem_ctx, "0x%x", method);
+			
+			dcerpc_parse_binding(mem_ctx, binding, &dcerpc_binding);
+
+			retval = mapi_profile_add_string_attr(profname, "workstation", workstation);
+			retval = mapi_profile_add_string_attr(profname, "domain", domain);
+			retval = mapi_profile_add_string_attr(profname, "binding", dcerpc_binding->host);
+			retval = mapi_profile_add_string_attr(profname, "codepage", p_codepage);
+			retval = mapi_profile_add_string_attr(profname, "language", p_language);
+			retval = mapi_profile_add_string_attr(profname, "method", p_method);
+		}
+	}
+	
+	nspi->mem_ctx = mem_ctx;
+
+	retval = nspi_GetSpecialTable(nspi, 0, &rowset);
+	mapi_errstr("NspiGetSpecialTable", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0xc,
+					  PR_DISPLAY_NAME,
+					  PR_OFFICE_TELEPHONE_NUMBER,
+					  PR_OFFICE_LOCATION,
+					  PR_TITLE,
+					  PR_COMPANY_NAME,
+					  PR_ACCOUNT,
+					  PR_ADDRTYPE,
+					  PR_ENTRYID,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_INSTANCE_KEY,
+					  PR_EMAIL_ADDRESS
+					  );
+
+	/* Set the username to match */
+	username = cli_credentials_get_username(nspi->cred);
+	if (!username) return false;
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(nspi->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_ANR_UNICODE;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszW = username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	Filter.res.resProperty.ulPropTag = PR_ANR_UNICODE;
+	Filter.res.resProperty.lpProp = lpProp;
+
+	rowset = talloc_zero(nspi->mem_ctx, struct SRowSet);
+	MIds = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
+	retval = nspi_GetMatches(nspi, SPropTagArray, &Filter, &rowset, &MIds);
+	MAPIFreeBuffer(lpProp);
+	mapi_errstr("NspiGetMatches", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	lpProp = get_SPropValue_SRowSet(rowset, PR_EMAIL_ADDRESS);
+	if (lpProp) {
+		DEBUG(3, ("PR_EMAIL_ADDRESS: %s\n", lpProp->value.lpszA));
+		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);
+		MAPI_RETVAL_IF(!nspi->org_unit, MAPI_E_INVALID_PARAMETER, mem_ctx);
+		MAPI_RETVAL_IF(!nspi->org, MAPI_E_INVALID_PARAMETER, mem_ctx);
+	}
+
+	if (profname) {
+		set_profile_attribute(profname, *rowset, PR_EMAIL_ADDRESS, "EmailAddress");
+		set_profile_attribute(profname, *rowset, PR_DISPLAY_NAME, "DisplayName");
+		set_profile_attribute(profname, *rowset, PR_ACCOUNT, "Account");
+		set_profile_attribute(profname, *rowset, PR_ADDRTYPE, "AddrType");
+		retval = mapi_profile_add_string_attr(profname, "Organization", nspi->org);
+		retval = mapi_profile_add_string_attr(profname, "OrganizationUnit", nspi->org_unit);
+	}
+
+	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x7,
+					  PR_DISPLAY_NAME,
+					  PR_EMAIL_ADDRESS,
+					  PR_DISPLAY_TYPE,
+					  PR_EMS_AB_HOME_MDB,
+					  PR_ATTACH_NUM,
+					  PR_PROFILE_HOME_SERVER_ADDRS,
+					  PR_EMS_AB_PROXY_ADDRESSES
+					  );
+
+	nspi->pStat->CurrentRec = 0x0;
+	nspi->pStat->Delta = 0x0;
+	nspi->pStat->NumPos = 0x0;
+	nspi->pStat->TotalRecs = 0x1;
+
+	instance_key = MIds->aulPropTag[0];
+	MIds2.cValues = 0x1;
+	MIds2.aulPropTag = &instance_key;
+
+	retval = nspi_QueryRows(nspi, SPropTagArray, &MIds2, 1, &rowset);
+	mapi_errstr("NspiQueryRows", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	lpProp = get_SPropValue_SRowSet(rowset, PR_EMS_AB_HOME_MDB);
+	if (lpProp) {
+		nspi->servername = x500_get_servername(lpProp->value.lpszA);
+		if (profname) {
+			mapi_profile_add_string_attr(profname, "ServerName", nspi->servername);
+			set_profile_attribute(profname, *rowset, PR_EMS_AB_HOME_MDB, "HomeMDB");
+			set_profile_mvstr_attribute(profname, *rowset, PR_EMS_AB_PROXY_ADDRESSES, "ProxyAddress");
+		}
+	} else {
+		printf("Unable to find the server name\n");
+		return -1;
+	}
+
+
+	MId_server = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
+	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, 
+							   nspi->org, nspi->org_unit, 
+							   nspi->servername);
+	retval = nspi_DNToMId(nspi, &pNames, &MId_server);
+	mapi_errstr("NspiDNToMId", GetLastError());
+	MAPIFreeBuffer((char *)pNames.Strings[0]);
+	MAPIFreeBuffer((char **)pNames.Strings);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x2,
+					  PR_EMS_AB_NETWORK_ADDRESS);
+	retval = nspi_GetProps(nspi, SPropTagArray, MId_server, &rowset);
+	mapi_errstr("NspiGetProps", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (profname) {
+		set_profile_mvstr_attribute(profname, *rowset, PR_EMS_AB_NETWORK_ADDRESS, "NetworkAddress");
+	}
+
+	retval = nspi_unbind(nspi);
+	mapi_errstr("NspiUnbind", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+
+	return true;
+}

Added: trunk/openchange/torture/nspi_resolvenames.c
===================================================================
--- trunk/openchange/torture/nspi_resolvenames.c	                        (rev 0)
+++ trunk/openchange/torture/nspi_resolvenames.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,139 @@
+/*
+   OpenChange MAPI torture suite implementation.
+
+   Query the WAB and attempts to resolve the given names
+
+   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/>.
+ */
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <samba/popt.h>
+
+bool torture_rpc_nspi_resolvenames(struct torture_context *torture)
+{
+	NTSTATUS                status;
+	enum MAPISTATUS		retval;
+	struct dcerpc_pipe      *p;
+	TALLOC_CTX              *mem_ctx;
+	struct mapi_session	*session;
+	bool                    ret = true;
+	struct SPropTagArray    *SPropTagArray;
+	struct SRowSet		*rowset = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	const char		*profdb;
+	char			*profname;
+	const char		*username = lp_parm_string(torture->lp_ctx, NULL, "exchange", "resolvename");
+	const char		*password = lp_parm_string(torture->lp_ctx, NULL, "mapi", "password");
+	uint32_t		unicode = lp_parm_int(torture->lp_ctx, NULL, "mapi", "unicode", 0);
+	char *tmp;
+	char **usernames;
+	int j;
+
+	mem_ctx = talloc_named(NULL, 0, "torture_rpc_nspi_resolvenames");
+
+	if (!username) {
+		DEBUG(0,("Specify the usernames to resolve with exchange:resolvename\n"));
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	status = torture_rpc_connection(torture, &p, &ndr_table_exchange_nsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(mem_ctx);
+		return false;
+	}
+
+	/* init mapi */
+	profdb = lp_parm_string(torture->lp_ctx, NULL, "mapi", "profile_store");
+	if (!profdb) {
+		profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB_PATH, getenv("HOME"));
+		if (!profdb) {
+			DEBUG(0, ("Specify a valie MAPI profile store\n"));
+			return false;
+		}
+	}
+	retval = MAPIInitialize(profdb);
+	mapi_errstr("MAPIInitialize", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* profile name */
+	profname = talloc_strdup(mem_ctx, lp_parm_string(torture->lp_ctx, NULL, "mapi", "profile"));
+	if (!profname) {
+		retval = GetDefaultProfile(&profname);
+		if (retval != MAPI_E_SUCCESS) {
+			DEBUG(0, ("Please specify a valid profile name\n"));
+			return false;
+		}
+	}
+	
+	retval = MapiLogonProvider(&session, profname, password, PROVIDER_ID_NSPI);
+	talloc_free(profname);
+	mapi_errstr("MapiLogonProvider", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0xd,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME,
+					  PR_ADDRTYPE,
+					  PR_GIVEN_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_EMAIL_ADDRESS,
+					  PR_SEND_INTERNET_ENCODING,
+					  PR_SEND_RICH_INFO,
+					  PR_SEARCH_KEY,
+					  PR_TRANSMITTABLE_DISPLAY_NAME,
+					  PR_7BIT_DISPLAY_NAME);
+
+	if ((tmp = strtok((char *)username, ",")) == NULL){
+		DEBUG(2, ("Invalid usernames string format\n"));
+		exit (1);
+	}
+
+	usernames = talloc_array(mem_ctx, char *, 2);
+	usernames[0] = strdup(tmp);
+
+	for (j = 1; (tmp = strtok(NULL, ",")) != NULL; j++) {
+		     usernames = talloc_realloc(mem_ctx, usernames, char *, j+2);
+		     usernames[j] = strdup(tmp);
+	}
+	usernames[j] = 0;
+
+	retval = ResolveNames(session, (const char **)usernames, SPropTagArray, &rowset, &flaglist, unicode?MAPI_UNICODE:0);
+	mapi_errstr("ResolveNames", GetLastError());
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapidump_Recipients((const char **)usernames, rowset, flaglist);
+
+	retval = MAPIFreeBuffer(rowset);
+	mapi_errstr("MAPIFreeBuffer: rowset", GetLastError());
+	
+	retval = MAPIFreeBuffer(flaglist);
+	mapi_errstr("MAPIFreeBuffer: flaglist", GetLastError());
+	
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+
+	return ret;
+}

Added: trunk/openchange/torture/openchange.c
===================================================================
--- trunk/openchange/torture/openchange.c	                        (rev 0)
+++ trunk/openchange/torture/openchange.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,127 @@
+/*
+   Unix EMSMDB implementation
+
+   Test suite for OpenChange
+
+   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 <samba/popt.h>
+#include <torture/mapi_torture.h>
+#include <torture.h>
+#include <torture/torture_proto.h>
+#include <smbtorture.h>
+
+NTSTATUS ndr_table_init(void);
+
+NTSTATUS samba_init_module(void)
+{
+	struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "OPENCHANGE");
+
+	ndr_table_init();
+
+	DEBUG(0, ("Loading openchange torture test\n"));
+
+	/* OpenChange torture tests */
+	/* Address Book name resolution */
+	torture_suite_add_simple_test(suite, "NSPI-PROFILE", torture_rpc_nspi_profile);
+	torture_suite_add_simple_test(suite, "NSPI-RESOLVENAMES", torture_rpc_nspi_resolvenames);
+	/* MAPI mail torture tests */
+	torture_suite_add_simple_test(suite, "MAPI-FETCHMAIL", torture_rpc_mapi_fetchmail);
+	torture_suite_add_simple_test(suite, "MAPI-FETCHATTACH", torture_rpc_mapi_fetchattach);
+	torture_suite_add_simple_test(suite, "MAPI-SENDMAIL", torture_rpc_mapi_sendmail);
+	torture_suite_add_simple_test(suite, "MAPI-SENDMAIL-HTML", torture_rpc_mapi_sendmail_html);
+	torture_suite_add_simple_test(suite, "MAPI-SENDATTACH", torture_rpc_mapi_sendattach);
+        torture_suite_add_simple_test(suite, "MAPI-DELETEMAIL", torture_rpc_mapi_deletemail);
+        torture_suite_add_simple_test(suite, "MAPI-NEWMAIL", torture_rpc_mapi_newmail);
+	torture_suite_add_simple_test(suite, "MAPI-COPYMAIL", torture_rpc_mapi_copymail);
+	/* MAPI calendar torture tests */
+	torture_suite_add_simple_test(suite, "MAPI-FETCHAPPOINTMENT", torture_rpc_mapi_fetchappointment);
+	torture_suite_add_simple_test(suite, "MAPI-SENDAPPOINTMENT", torture_rpc_mapi_sendappointment);
+	torture_suite_add_simple_test(suite, "MAPI-FETCHCONTACTS", torture_rpc_mapi_fetchcontacts);
+	torture_suite_add_simple_test(suite, "MAPI-SENDCONTACTS", torture_rpc_mapi_sendcontacts);
+	torture_suite_add_simple_test(suite, "MAPI-FETCHTASKS", torture_rpc_mapi_fetchtasks);
+	torture_suite_add_simple_test(suite, "MAPI-SENDTASKS", torture_rpc_mapi_sendtasks);
+	/* MAPI object torture tests */
+	torture_suite_add_simple_test(suite, "MAPI-ACLS", torture_rpc_mapi_permissions);
+	torture_suite_add_simple_test(suite, "MAPI-RESTRICTIONS", torture_rpc_mapi_restrictions);
+	torture_suite_add_simple_test(suite, "MAPI-CRITERIA", torture_rpc_mapi_criteria);
+	torture_suite_add_simple_test(suite, "MAPI-SORTTABLE", torture_rpc_mapi_sorttable);
+	torture_suite_add_simple_test(suite, "MAPI-BOOKMARK", torture_rpc_mapi_bookmark);
+	torture_suite_add_simple_test(suite, "MAPI-RECIPIENT", torture_rpc_mapi_recipient);
+	torture_suite_add_simple_test(suite, "MAPI-NAMEDPROPS", torture_rpc_mapi_namedprops);
+	/* Exchange Administration torture tests */
+	torture_suite_add_simple_test(suite, "EXCHANGE-CREATEUSER", torture_mapi_createuser);
+
+	suite->description = talloc_strdup(suite, "Exchange protocols tests (NSPI and EMSMDB)");
+
+	torture_register_suite(suite);
+	return NT_STATUS_OK;
+}
+
+/**
+ * Obtain the DCE/RPC binding context associated with a torture context.
+ *
+ * @param tctx Torture context
+ * @param binding Pointer to store DCE/RPC binding
+ */
+NTSTATUS torture_rpc_binding(struct torture_context *tctx,
+			     struct dcerpc_binding **binding)
+{
+	NTSTATUS status;
+	const char *binding_string = torture_setting_string(tctx, "binding",
+							    NULL);
+
+	if (binding_string == NULL) {
+		torture_comment(tctx,
+				"You must specify a DCE/RPC binding string\n");
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	status = dcerpc_parse_binding(tctx, binding_string, binding);
+	if (NT_STATUS_IS_ERR(status)) {
+		DEBUG(0,("Failed to parse dcerpc binding '%s'\n",
+			 binding_string));
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/**
+ * open a rpc connection to the chosen binding string
+ */
+_PUBLIC_ NTSTATUS torture_rpc_connection(struct torture_context *tctx,
+				struct dcerpc_pipe **p,
+				const struct ndr_interface_table *table)
+{
+	NTSTATUS status;
+	struct dcerpc_binding *binding;
+
+	status = torture_rpc_binding(tctx, &binding);
+	if (NT_STATUS_IS_ERR(status))
+		return status;
+
+	status = dcerpc_pipe_connect_b(tctx,
+				     p, binding, table,
+				     cmdline_credentials, NULL, tctx->lp_ctx);
+ 
+	if (NT_STATUS_IS_ERR(status)) {
+		printf("Failed to connect to remote server: %s %s\n",
+			   dcerpc_binding_string(tctx, binding), nt_errstr(status));
+	}
+
+	return status;
+}

Added: trunk/openchange/utils/backup/openchangebackup.c
===================================================================
--- trunk/openchange/utils/backup/openchangebackup.c	                        (rev 0)
+++ trunk/openchange/utils/backup/openchangebackup.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,317 @@
+/*
+   MAPI Backup application suite
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#include "openchangebackup.h"
+#include <libmapi/defs_private.h>
+
+/**
+ * Initialize OCB (OpenChange Backup) subsystem
+ * and open a pointer on the LDB database
+ */
+struct ocb_context *ocb_init(TALLOC_CTX *mem_ctx, const char *dbpath)
+{
+	struct ocb_context	*ocb_ctx = NULL;
+	char			*url = NULL;
+	int			ret;
+	struct tevent_context	*ev;
+
+	/* sanity check */
+	OCB_RETVAL_IF_CODE(!mem_ctx, "invalid memory context", NULL, NULL);
+	OCB_RETVAL_IF_CODE(!dbpath, "dbpath not set", NULL, NULL);
+
+	ocb_ctx = talloc_zero(mem_ctx, struct ocb_context);
+
+	ev = tevent_context_init(ocb_ctx);
+	if (!ev) goto failed;
+
+	/* init ldb store */
+	ocb_ctx->ldb_ctx = ldb_init((TALLOC_CTX *)ocb_ctx, ev);
+	if (!ocb_ctx->ldb_ctx) goto failed;
+
+	url = talloc_asprintf(mem_ctx, "tdb://%s", dbpath);
+	ret = ldb_connect(ocb_ctx->ldb_ctx, url, 0, NULL);
+	talloc_free(url);
+	if (ret != LDB_SUCCESS) goto failed;
+
+	return ocb_ctx;
+failed:
+	ocb_release(ocb_ctx);
+	return NULL;
+}
+
+/**
+ * Release OCB subsystem
+ */
+uint32_t ocb_release(struct ocb_context *ocb_ctx)
+{
+	OCB_RETVAL_IF(!ocb_ctx, "subsystem not initialized\n", NULL);
+	talloc_free(ocb_ctx);
+
+	return 0;
+}
+
+/**
+ * init and prepare a record
+ */
+
+int ocb_record_init(struct ocb_context *ocb_ctx, const char *objclass, const char *dn, 
+		    const char *id, struct mapi_SPropValue_array *props)
+{
+	TALLOC_CTX		*mem_ctx;
+	struct ldb_context	*ldb_ctx;
+	struct ldb_result	*res;
+	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	struct ldb_dn		*basedn;
+	int		       	ret;
+	const char * const     	attrs[] = { "*", NULL };
+
+	/* sanity check */
+	OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL);
+	OCB_RETVAL_IF(!dn, "Not a valid DN", NULL);
+	OCB_RETVAL_IF(!id, "Not a valid ID", NULL);
+
+	mem_ctx = (TALLOC_CTX *)ocb_ctx;
+	ldb_ctx = ocb_ctx->ldb_ctx;
+
+	/* Check if the record already exists */
+	ret = ldb_search(ldb_ctx, mem_ctx, &res, ldb_get_default_basedn(ldb_ctx), scope, attrs, dn);
+	OCB_RETVAL_IF(res->msgs, "Record already exists", NULL);
+
+	/* Retrieve the record basedn */
+	basedn = ldb_dn_new(ldb_ctx, ldb_ctx, dn);
+	OCB_RETVAL_IF(!ldb_dn_validate(basedn), "Invalid DN", NULL);
+
+	ocb_ctx->msg = ldb_msg_new(mem_ctx);
+	ocb_ctx->msg->dn = ldb_dn_copy(mem_ctx, basedn);
+
+	/* add records for cn */
+	ldb_msg_add_string(ocb_ctx->msg, "cn", id);
+
+	/* add filters attributes */
+	ldb_msg_add_string(ocb_ctx->msg, "objectClass", objclass);
+
+	talloc_free(basedn);
+
+	return 0;
+}
+
+
+/**
+ * Commit the record with all its attributes: single transaction
+ */
+uint32_t ocb_record_commit(struct ocb_context *ocb_ctx)
+{
+	int		ret;
+
+	/* sanity checks */
+	OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL);
+	OCB_RETVAL_IF(!ocb_ctx->ldb_ctx, "LDB context not initialized", NULL);
+	OCB_RETVAL_IF(!ocb_ctx->msg, "Message not initialized", NULL);
+
+	ret = ldb_add(ocb_ctx->ldb_ctx, ocb_ctx->msg);
+	if (ret != LDB_SUCCESS) {
+		DEBUG(3, ("LDB operation failed: %s\n", ldb_errstring(ocb_ctx->ldb_ctx)));
+		return -1;
+	}
+
+	talloc_free(ocb_ctx->msg);
+
+	return 0;
+}
+
+
+/**
+ * Add a property (attr, value) couple to the current record
+ */
+uint32_t ocb_record_add_property(struct ocb_context *ocb_ctx, 
+				 struct mapi_SPropValue *lpProp)
+{
+	TALLOC_CTX     	*mem_ctx;
+	int    		i;
+	char	       	*attr;
+	char	       	*value = NULL;
+	const char	*tag;
+
+	/* sanity checks */
+	OCB_RETVAL_IF(!ocb_ctx, "Subsystem not initialized", NULL);
+	OCB_RETVAL_IF(!ocb_ctx->ldb_ctx, "LDB context not initialized", NULL);
+	OCB_RETVAL_IF(!ocb_ctx->msg, "Message not initialized", NULL);
+
+	mem_ctx = (TALLOC_CTX *)ocb_ctx->msg;
+
+	tag = get_proptag_name(lpProp->ulPropTag);
+	if (tag) {
+		attr = talloc_asprintf(mem_ctx, "%s", tag);
+	} else {
+		attr = talloc_asprintf(mem_ctx, "PR-x%.8x", lpProp->ulPropTag);
+	}
+
+	for (i = 0; attr[i]; i++) {
+		if (attr[i] == '_') attr[i] = '-';
+	}
+	
+	switch (lpProp->ulPropTag & 0xFFFF) {
+	case PT_SHORT:
+		ldb_msg_add_fmt(ocb_ctx->msg, attr, "%hd", lpProp->value.i);
+		break;
+	case PT_STRING8:
+		ldb_msg_add_string(ocb_ctx->msg, attr, lpProp->value.lpszA);
+		break;
+	case PT_UNICODE:
+		ldb_msg_add_string(ocb_ctx->msg, attr, lpProp->value.lpszW);
+		break;
+	case PT_ERROR: /* We shouldn't need to backup error properties */
+		return 0;
+	case PT_LONG:
+		ldb_msg_add_fmt(ocb_ctx->msg, attr, "%d", lpProp->value.l);
+		break;
+	case PT_BOOLEAN:
+		ldb_msg_add_fmt(ocb_ctx->msg, attr, "%s", 
+				((lpProp->value.b == true) ? "true" : "false"));
+		break;
+	case PT_I8:
+		ldb_msg_add_fmt(ocb_ctx->msg, attr, "%16"PRIx64, lpProp->value.d);
+		break;
+	case PT_SYSTIME:
+		value = ocb_ldb_timestring(mem_ctx, &lpProp->value.ft);
+		ldb_msg_add_string(ocb_ctx->msg, attr, value);
+		break;
+	case 0xFB:
+	case PT_BINARY:
+		if (lpProp->value.bin.cb) {
+			value = ldb_base64_encode(mem_ctx, (char *)lpProp->value.bin.lpb,
+						  lpProp->value.bin.cb);
+			ldb_msg_add_string(ocb_ctx->msg, attr, value);
+		}
+		break;
+	case PT_MV_LONG:
+		for (i = 0; i < lpProp->value.MVl.cValues; i++) {
+			ldb_msg_add_fmt(ocb_ctx->msg, attr, "%d", 
+					lpProp->value.MVl.lpl[i]);
+		}
+		break;
+	case PT_MV_BINARY:
+		for (i = 0; i < lpProp->value.MVbin.cValues; i++) {
+			struct SBinary_short bin;
+
+			bin = lpProp->value.MVbin.bin[i];
+			if (bin.cb) {
+				value = ldb_base64_encode(mem_ctx, (char *)bin.lpb, bin.cb);
+				ldb_msg_add_string(ocb_ctx->msg, attr, value);
+			}
+		}
+		break;
+	case PT_MV_STRING8:
+		for (i = 0; i < lpProp->value.MVszA.cValues; i++) {
+			ldb_msg_add_string(ocb_ctx->msg, attr, 
+					   lpProp->value.MVszA.strings[i].lppszA);
+		}
+		break;
+	default:
+		printf("%s case %d not supported\n", attr, lpProp->ulPropTag & 0xFFFF);
+		break;
+	}
+
+	talloc_free(attr);
+	return 0;
+}
+
+/**
+ * Retrieve UUID from Sbinary_short struct
+ * Generally used to map PR_STORE_KEY to a string
+ * Used for attachments
+ */
+char *get_record_uuid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin)
+{
+	uint32_t	i;
+	char		*lpb;
+
+	OCB_RETVAL_IF_CODE(!bin, "Invalid PR_RECORD_KEY val", NULL, NULL);
+	lpb = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[0]);
+	for (i = 1; i < bin->cb; i++) {
+		lpb = talloc_asprintf_append(lpb, "%.2X", bin->lpb[i]);
+	}
+	
+	return lpb;
+}
+
+
+/**
+ * Extract MAPI object unique ID from PR_SOURCE_KEY Sbinary_short data:
+ * PR_SOURCE_KEY = 22 bytes field
+ * - 16 first bytes = MAPI Store GUID
+ * - 6 last bytes = MAPI object unique ID
+ */
+char *get_MAPI_uuid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin)
+{
+	uint32_t       	i;
+	char		*ab;
+
+	OCB_RETVAL_IF_CODE(!bin || bin->cb != 22, "Invalid SBinary", NULL, NULL);
+
+	ab = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[16]);
+	for (i = 17; i < bin->cb; i++) {
+		ab = talloc_asprintf_append(ab, "%.2X", bin->lpb[i]);
+	}
+
+	return ab;
+}
+
+
+/**
+ * Retrieve the store GUID from a given record.
+ * This GUID should be unique for each store and identical for all
+ * objects belonging to this store
+ */
+char *get_MAPI_store_guid(TALLOC_CTX *mem_ctx, const struct SBinary_short *bin)
+{
+	int		i;
+	char		*ab;
+
+	OCB_RETVAL_IF_CODE(!bin || bin->cb != 22, "Invalid SBinary", NULL, NULL);
+
+	ab = talloc_asprintf(mem_ctx, "%.2X", bin->lpb[0]);
+	for (i = 1; i < 16; i++) {
+		ab = talloc_asprintf_append(ab, "%.2X", bin->lpb[i]);
+	}
+	
+	return ab;
+}
+
+
+/**
+ * Convert date from MAPI property to ldb format
+ * Easier to manipulate
+ */
+char *ocb_ldb_timestring(TALLOC_CTX *mem_ctx, struct FILETIME *ft)
+{
+	NTTIME		time;
+	time_t		t;
+
+	OCB_RETVAL_IF_CODE(!ft, "Invalid FILTIME", NULL, NULL);
+
+	time = ft->dwHighDateTime;
+	time = time << 32;
+	time |= ft->dwLowDateTime;
+
+	t = nt_time_to_unix(time);
+	return ldb_timestring(mem_ctx, t);
+}

Added: trunk/openchange/utils/backup/openchangebackup.h
===================================================================
--- trunk/openchange/utils/backup/openchangebackup.h	                        (rev 0)
+++ trunk/openchange/utils/backup/openchangebackup.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,97 @@
+/*
+   MAPI Backup application suite
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#ifndef __OPENCHANGEBACKUP_H__
+#define	__OPENCHANGEBACKUP_H__
+
+#include <libmapi/libmapi.h>
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/* Samba4 includes */
+#include <util.h>
+#include <talloc.h>
+#include <ldb_errors.h>
+#include <ldb.h>
+
+/* Data structures */
+
+struct ocb_context {
+	struct ldb_context	*ldb_ctx;	/* ldb database context */
+	struct ldb_message	*msg;		/* pointer on record msg */
+};
+
+/* Prototypes */
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+__BEGIN_DECLS
+struct ocb_context	*ocb_init(TALLOC_CTX *, const char *);
+uint32_t		ocb_release(struct ocb_context *);
+
+int			ocb_record_init(struct ocb_context *, const char *, 
+					const char *, const char *, struct mapi_SPropValue_array *);
+uint32_t		ocb_record_commit(struct ocb_context *);
+uint32_t		ocb_record_add_property(struct ocb_context *, struct mapi_SPropValue *);
+
+char			*get_record_uuid(TALLOC_CTX *, const struct SBinary_short *);
+char			*get_MAPI_uuid(TALLOC_CTX *, const struct SBinary_short *);
+char			*get_MAPI_store_guid(TALLOC_CTX *, const struct SBinary_short *);
+char			*ocb_ldb_timestring(TALLOC_CTX *, struct FILETIME *);
+__END_DECLS
+
+#define	OCB_RETVAL_IF_CODE(x, m, c, r)	       	\
+do {						\
+	if (x) {				\
+		DEBUG(3, ("[OCB] %s\n", m));	\
+		if (c) {			\
+			talloc_free(c);		\
+		}				\
+		return r;			\
+	}					\
+} while (0);
+
+#define	OCB_RETVAL_IF(x, m, c) OCB_RETVAL_IF_CODE(x, m, c, -1)
+
+
+#define	DEFAULT_PROFDB		"%s/.openchange/profiles.ldb"
+#define	DEFAULT_OCBCONF		"%s/.openchange/openchangebackup.conf"
+#define	DEFAULT_OCBDB		"%s/.openchange/openchangebackup_%s.ldb"
+
+/* objectClass */
+#define	OCB_OBJCLASS_CONTAINER	"container"
+#define	OCB_OBJCLASS_MESSAGE	"message"
+#define	OCB_OBJCLASS_ATTACHMENT	"attachment"
+
+#endif /* __OPENCHANGEBACKUP_H__ */

Added: trunk/openchange/utils/backup/openchangemapidump.c
===================================================================
--- trunk/openchange/utils/backup/openchangemapidump.c	                        (rev 0)
+++ trunk/openchange/utils/backup/openchangemapidump.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,474 @@
+/*
+   MAPI Backup application suite
+   Dump a Mailbox store in a database
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include <samba/popt.h>
+#include <param.h>
+
+#include "openchangebackup.h"
+#include <utils/openchange-tools.h>
+
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <time.h>
+
+/**
+ * write attachment to the database
+ */
+static enum MAPISTATUS mapidump_write_attachment(struct ocb_context *ocb_ctx,
+						 struct mapi_SPropValue_array *props,
+						 const char *contentdn,
+						 const char *uuid)
+{
+	int			ret;
+	uint32_t		i;
+
+	ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_ATTACHMENT, contentdn, uuid, props);
+	if (ret == -1) return MAPI_E_SUCCESS;
+	for (i = 0; i < props->cValues; i++) {
+		ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]);
+	}
+	ret = ocb_record_commit(ocb_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * write message to the database (email, appointment, contact, task, note etc.)
+ */
+static enum MAPISTATUS mapidump_write_message(struct ocb_context *ocb_ctx,
+					      struct mapi_SPropValue_array *props,
+					      const char *contentdn,
+					      const char *uuid)
+{
+	int			ret;
+	uint32_t		i;
+
+	ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_MESSAGE, contentdn, uuid, props);
+	if (ret == -1) return MAPI_E_SUCCESS;
+	for (i = 0; i < props->cValues; i++) {
+		ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]);
+	}
+	ret = ocb_record_commit(ocb_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * write containers to the database (folders)
+ */
+static enum MAPISTATUS mapidump_write_container(struct ocb_context *ocb_ctx,
+						struct mapi_SPropValue_array *props,
+						const char *containerdn,
+						const char *uuid)
+{
+	int			ret;
+	uint32_t		i;
+
+	ret = ocb_record_init(ocb_ctx, OCB_OBJCLASS_CONTAINER, containerdn, uuid, props);
+	if (ret == -1) return MAPI_E_SUCCESS;
+	for (i = 0; i < props->cValues; i++) {
+		ret = ocb_record_add_property(ocb_ctx, &props->lpProps[i]);
+	}
+	ret = ocb_record_commit(ocb_ctx);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Retrieve all the attachments for a given message
+ */
+static enum MAPISTATUS mapidump_walk_attachment(TALLOC_CTX *mem_ctx,
+						struct ocb_context *ocb_ctx,
+						mapi_object_t *obj_message,
+						const char *messagedn)
+{
+	enum MAPISTATUS			retval;
+	struct SPropTagArray		*SPropTagArray;
+	struct SRowSet			rowset;
+	struct mapi_SPropValue_array	props;
+	mapi_object_t			obj_atable;
+	mapi_object_t			obj_attach;
+	uint32_t			Numerator = 0;
+	uint32_t			Denominator = 0;
+	uint32_t			i;
+	const uint32_t			*attach_num;
+	const struct SBinary_short	*sbin;
+	char				*uuid;
+	char				*contentdn;
+
+	/* Get attachment table */
+	mapi_object_init(&obj_atable);
+	retval = GetAttachmentTable(obj_message, &obj_atable);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	/* Customize the table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_ATTACH_NUM);
+	retval = SetColumns(&obj_atable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	/* Walk through the table */
+	retval = QueryPosition(&obj_atable, &Numerator, &Denominator);
+
+	while ((retval = QueryRows(&obj_atable, Denominator, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		for (i = 0; i < rowset.cRows; i++) {
+			attach_num = (const uint32_t *)find_SPropValue_data(&(rowset.aRow[i]), PR_ATTACH_NUM);
+			/* Open attachment */
+			mapi_object_init(&obj_attach);
+			retval = OpenAttach(obj_message, *attach_num, &obj_attach);
+			if (retval == MAPI_E_SUCCESS) {
+				retval = GetPropsAll(&obj_attach, &props);
+				if (retval == MAPI_E_SUCCESS) {
+					/* extract unique identifier from PR_RECORD_KEY */
+					sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_RECORD_KEY);
+					uuid = get_record_uuid(mem_ctx, sbin);
+					contentdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, messagedn);
+					mapidump_write_attachment(ocb_ctx, &props, contentdn, uuid);
+
+					/* free allocated strings */
+					talloc_free(uuid);
+					talloc_free(contentdn);
+				}
+			}
+			mapi_object_release(&obj_attach);
+		}
+	}
+
+	mapi_object_release(&obj_atable);
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Retrieve all the content within a folder
+ */
+static enum MAPISTATUS mapidump_walk_content(TALLOC_CTX *mem_ctx,
+					     struct ocb_context *ocb_ctx,
+					     mapi_object_t *obj_folder,
+					     const char *containerdn)
+{
+	enum MAPISTATUS			retval;
+	struct SPropTagArray		*SPropTagArray;
+	struct mapi_SPropValue_array	props;
+	struct SRowSet			rowset;
+	mapi_object_t			obj_ctable;
+	mapi_object_t			obj_message;
+	uint32_t			count = 0;
+	uint32_t			i;
+	const mapi_id_t			*fid;
+	const mapi_id_t			*mid;
+	char				*uuid;
+	const struct SBinary_short     	*sbin;
+	const uint8_t			*has_attach;
+	char				*contentdn;
+
+	/* Get Contents Table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(obj_folder, &obj_ctable, 0, &count);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	/* Customize the table view */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	while ((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		for (i = 0; i < rowset.cRows; i++) {
+			mapi_object_init(&obj_message);
+			fid = (const uint64_t *) get_SPropValue_SRow_data(&rowset.aRow[i], PR_FID);
+			mid = (const uint64_t *) get_SPropValue_SRow_data(&rowset.aRow[i], PR_MID);
+			/* Open Message */
+			retval = OpenMessage(obj_folder, *fid, *mid, &obj_message, 0);
+			if (GetLastError() == MAPI_E_SUCCESS) {
+				retval = GetPropsAll(&obj_message, &props);
+				if (GetLastError() == MAPI_E_SUCCESS) {
+					/* extract unique identifier from PR_SOURCE_KEY */
+					sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_SOURCE_KEY);
+					uuid = get_MAPI_uuid(mem_ctx, sbin);
+					contentdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, containerdn);
+					mapidump_write_message(ocb_ctx, &props, contentdn, uuid);
+
+					/* If Message has attachments then process them */
+					has_attach = (const uint8_t *)find_mapi_SPropValue_data(&props, PR_HASATTACH);
+					if (has_attach && *has_attach) {
+						mapidump_walk_attachment(mem_ctx, ocb_ctx, &obj_message, contentdn);
+					}
+
+					/* free allocated strings */
+					talloc_free(uuid);
+					talloc_free(contentdn);
+				}
+			}
+			mapi_object_release(&obj_message);
+		}
+	}
+
+	mapi_object_release(&obj_ctable);
+	
+	return MAPI_E_SUCCESS;
+}
+
+
+/**
+ * Recursively retrieve folders
+ */
+static enum MAPISTATUS mapidump_walk_container(TALLOC_CTX *mem_ctx,
+					       struct ocb_context *ocb_ctx,
+					       mapi_object_t *obj_parent,
+					       mapi_id_t folder_id,
+					       char *parentdn,
+					       int count)
+{
+	enum MAPISTATUS			retval;
+	struct SPropTagArray		*SPropTagArray;
+	struct SRowSet			rowset;
+	struct mapi_SPropValue_array	props;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_htable;
+	const uint32_t			*child_content;
+	const uint32_t			*child_folder;
+	char				*containerdn;
+	char				*uuid;
+	const mapi_id_t			*fid;
+	uint32_t			rcount;
+	uint32_t			i;
+	const struct SBinary_short	*sbin;
+
+	/* Open folder */
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(obj_parent, folder_id, &obj_folder);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	/* Retrieve all its properties */
+	retval = GetPropsAll(&obj_folder, &props);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+	child_content = (const uint32_t *)find_mapi_SPropValue_data(&props, PR_CONTENT_COUNT);
+	child_folder = (const uint32_t *)find_mapi_SPropValue_data(&props, PR_FOLDER_CHILD_COUNT);
+
+	/* extract unique identifier from PR_SOURCE_KEY */
+	sbin = (const struct SBinary_short *)find_mapi_SPropValue_data(&props, PR_SOURCE_KEY);
+	uuid = get_MAPI_uuid(mem_ctx, sbin);
+
+	if (parentdn == NULL && count == 0) {
+		parentdn = talloc_asprintf(mem_ctx, "cn=%s", 
+					   get_MAPI_store_guid(mem_ctx, sbin));
+	}
+
+	containerdn = talloc_asprintf(mem_ctx, "cn=%s,%s", uuid, parentdn);
+
+	/* Write entry for container */
+	mapidump_write_container(ocb_ctx, &props, containerdn, uuid);
+	talloc_free(uuid);
+
+	/* Get Contents Table if PR_CONTENT_COUNT >= 1 */
+	if (child_content && *child_content >= 1) {
+		retval = mapidump_walk_content(mem_ctx, ocb_ctx, &obj_folder, containerdn);
+	}
+
+	/* Get Container Table if PR_FOLDER_CHILD_COUNT >= 1 */
+
+	if (child_folder && *child_folder >= 1) {
+		mapi_object_init(&obj_htable);
+		retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, &rcount);
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+						  PR_FID,
+						  PR_CONTENT_COUNT,
+						  PR_FOLDER_CHILD_COUNT);
+		retval = SetColumns(&obj_htable, SPropTagArray);
+		MAPIFreeBuffer(SPropTagArray);
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+		while ((retval = QueryRows(&obj_htable, rcount, TBL_ADVANCE, &rowset) != MAPI_E_NOT_FOUND) && rowset.cRows) {
+			for (i = 0; i < rowset.cRows; i++) {
+				fid = (const uint64_t *)find_SPropValue_data(&rowset.aRow[i], PR_FID);
+				retval = mapidump_walk_container(mem_ctx, ocb_ctx, &obj_folder, *fid, containerdn, count + 1);
+			}
+		}
+	} 
+
+	talloc_free(containerdn);
+	mapi_object_release(&obj_folder);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Walk through known mapi folders
+ */
+
+static enum MAPISTATUS mapidump_walk(TALLOC_CTX *mem_ctx,
+					       struct ocb_context *ocb_ctx,
+					       mapi_object_t *obj_store)
+{
+	enum MAPISTATUS			retval;
+	mapi_id_t			id_mailbox;
+
+	retval = GetDefaultFolder(obj_store, &id_mailbox, 
+				  olFolderTopInformationStore);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	return mapidump_walk_container(mem_ctx, ocb_ctx, obj_store, id_mailbox, NULL, 0);
+}
+
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	struct ocb_context		*ocb_ctx = NULL;
+	struct mapi_session		*session = NULL;
+	mapi_object_t			obj_store;
+	poptContext			pc;
+	int				opt;
+	/* command line options */
+	const char			*opt_profdb = NULL;
+	char				*opt_profname = NULL;
+	const char			*opt_password = NULL;
+	const char			*opt_config = NULL;
+	const char			*opt_backupdb = NULL;
+	const char			*opt_debug = NULL;
+	bool				opt_dumpdata = false;
+
+	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, 
+	      OPT_MAILBOX, OPT_CONFIG, OPT_BACKUPDB, OPT_PF,
+	      OPT_DEBUG, OPT_DUMPDATA};
+
+	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},
+		{"config", 'c', POPT_ARG_STRING, NULL, OPT_CONFIG, "set openchangebackup configuration file path", NULL},
+		{"backup-db", 'b', POPT_ARG_STRING, NULL, OPT_BACKUPDB, "set the openchangebackup store path", NULL},
+		{"debuglevel", 0, 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 }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "openchangemapidump");
+
+	pc = poptGetContext("openchangemapidump", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt)  {
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc));
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_CONFIG:
+			opt_config = poptGetOptArg(pc);
+			break;
+		case OPT_BACKUPDB:
+			opt_backupdb = poptGetOptArg(pc);
+			break;
+		}
+	}
+
+	/* Sanity check on options */
+	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());
+		exit (1);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+
+	/* If no profile is specified try to load the default one from
+	 * the database 
+	 */
+	if (!opt_profname) {
+		retval = GetDefaultProfile(&opt_profname);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			exit (1);
+		}
+	}
+
+	if (!opt_backupdb) {
+		opt_backupdb = talloc_asprintf(mem_ctx, DEFAULT_OCBDB, 
+					       getenv("HOME"),
+					       opt_profname);
+	}
+
+	/* Initialize OpenChange Backup subsystem */
+	if (!(ocb_ctx = ocb_init(mem_ctx, opt_backupdb))) {
+		talloc_free(mem_ctx);
+		exit(-1);
+	}
+
+	/* We only need to log on EMSMDB to backup Mailbox store or Public Folders */
+	retval = MapiLogonProvider(&session, opt_profname, opt_password, PROVIDER_ID_EMSMDB);
+	talloc_free(opt_profname);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		exit (1);
+	}
+
+	/* Open default message store */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenMsgStore", GetLastError());
+		exit (1);
+	}
+
+	retval = mapidump_walk(mem_ctx, ocb_ctx, &obj_store);
+
+	/* Uninitialize MAPI and OCB subsystem */
+	mapi_object_release(&obj_store);
+	MAPIUninitialize();
+	ocb_release(ocb_ctx);
+	talloc_free(mem_ctx);
+
+	return 0;
+}

Added: trunk/openchange/utils/exchange2ical/exchange2ical.c
===================================================================
--- trunk/openchange/utils/exchange2ical/exchange2ical.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical/exchange2ical.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,391 @@
+/*
+   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 <utils/exchange2ical/exchange2ical.h>
+#include <samba/popt.h>
+#include <param.h>
+#include <utils/openchange-tools.h>
+
+static void exchange2ical_init(TALLOC_CTX *mem_ctx, struct exchange2ical *exchange2ical)
+{
+	exchange2ical->mem_ctx = mem_ctx;
+
+	exchange2ical->method = ICAL_METHOD_NONE;
+	exchange2ical->partstat = ICAL_PARTSTAT_NONE;
+	exchange2ical->Recurring = NULL;
+	exchange2ical->RecurrencePattern = NULL;
+	exchange2ical->TimeZoneStruct = NULL;
+	exchange2ical->TimeZoneDesc = 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->vcalendar = NULL;
+	exchange2ical->vevent = NULL;
+	exchange2ical->vtimezone = NULL;
+	exchange2ical->valarm = NULL;
+}
+
+static void exchange2ical_reset(struct exchange2ical *exchange2ical)
+{
+	if (exchange2ical->RecurrencePattern) {
+		talloc_free(exchange2ical->RecurrencePattern);
+	}
+
+	if (exchange2ical->TimeZoneStruct) {
+		talloc_free(exchange2ical->TimeZoneStruct);
+	}
+
+	if (exchange2ical->vcalendar) {
+		icalcomponent_free(exchange2ical->vcalendar);
+	}
+	exchange2ical_init(exchange2ical->mem_ctx, exchange2ical);
+}
+
+static int exchange2ical_get_properties(TALLOC_CTX *mem_ctx, struct SRow *aRow, struct exchange2ical *exchange2ical)
+{
+	struct Binary_r	*apptrecur;
+	struct Binary_r	*TimeZoneStruct;
+
+	exchange2ical->Keywords = (const struct StringArray_r *) octool_get_propval(aRow, PidNameKeywords);
+	exchange2ical->method = get_ical_method((const char *) octool_get_propval(aRow, PR_MESSAGE_CLASS_UNICODE));
+	if (!exchange2ical->method) return -1;
+
+	exchange2ical->Recurring = (uint8_t *) octool_get_propval(aRow, PidLidRecurring);
+	apptrecur = (struct Binary_r *) octool_get_propval(aRow, PidLidAppointmentRecur);
+	exchange2ical->RecurrencePattern = get_RecurrencePattern(mem_ctx, apptrecur);
+
+	exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription);
+	TimeZoneStruct = (struct Binary_r *) octool_get_propval(aRow, PidLidTimeZoneStruct);
+	exchange2ical->TimeZoneStruct = get_TimeZoneStruct(mem_ctx, TimeZoneStruct);
+
+	// TODO: should we use PidLidGlobalObjectId here instead of PidLidCleanGlobalObjectId?
+	exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidCleanGlobalObjectId);
+	exchange2ical->apptStateFlags = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentStateFlags);
+	exchange2ical->Contacts = (const struct StringArray_r *)octool_get_propval(aRow, PidLidContacts);
+	exchange2ical->apptStartWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentStartWhole);
+	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->ExceptionReplaceTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidExceptionReplaceTime);
+	exchange2ical->NonSendableBcc = (const char *) octool_get_propval(aRow, PidLidNonSendableBcc);
+	exchange2ical->Sequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentSequence);
+	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->partstat = get_ical_partstat((const char *) octool_get_propval(aRow, PR_MESSAGE_CLASS_UNICODE));
+	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;
+}
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	int				ret;
+	struct SRowSet			SRowSet;
+	struct SRow			aRow;
+	struct SPropValue		*lpProps;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	struct exchange2ical		exchange2ical;
+	struct mapi_session		*session = NULL;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_message;
+	mapi_id_t			fid;
+	uint32_t			count;
+	poptContext			pc;
+	int				opt;
+	uint32_t			i;
+	const char			*opt_profdb = NULL;
+	const char			*opt_profname = NULL;
+	const char			*opt_password = NULL;
+	const char			*opt_debug = NULL;
+	bool				opt_dumpdata = false;
+
+	enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_DEBUG, OPT_DUMPDATA };
+
+	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 },
+		{ "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 }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "exchange2ical");
+	exchange2ical_init(mem_ctx, &exchange2ical);
+
+	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_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;
+		}
+	}
+
+	/* 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());
+		exit (1);
+	}
+	
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+
+	session = octool_init_mapi(opt_profname, opt_password, 0);
+	MAPI_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, mem_ctx);
+
+	/* Open Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenMsgStore", GetLastError());
+		exit (1);
+	}
+
+	/* Open default calendar folder */
+/* 	retval = GetDefaultFolder(&obj_store, &fid, olFolderInbox); */
+	retval = GetDefaultFolder(&obj_store, &fid, olFolderCalendar);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("GetDefaultFolder", GetLastError());
+		exit (1);
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, fid, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenFolder", GetLastError());
+		exit (1);
+	}
+
+	/* Open the contents table */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_folder, &obj_table, 0, &count);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	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());
+	}
+
+	while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_folder,
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     SRowSet.aRow[i].lpProps[1].value.d,
+					     &obj_message, 0);
+			if (retval != MAPI_E_NOT_FOUND) {
+				retval = GetRecipientTable(&obj_message, 
+							   &exchange2ical.Recipients.SRowSet,
+							   &exchange2ical.Recipients.SPropTagArray);
+
+				SPropTagArray = set_SPropTagArray(mem_ctx, 0x2F,
+								  PidNameKeywords,
+								  PidLidRecurring,
+								  PidLidAppointmentRecur,
+								  PidLidAppointmentStateFlags,
+								  PidLidTimeZoneDescription,
+								  PidLidTimeZoneStruct,
+								  PidLidContacts,
+								  PidLidAppointmentStartWhole,
+								  PidLidAppointmentEndWhole,
+								  PidLidAppointmentSubType,
+								  PidLidOwnerCriticalChange,
+								  PidLidLocation,
+								  PidLidExceptionReplaceTime,
+								  PidLidNonSendableBcc,
+								  PidLidAppointmentSequence,
+								  PidLidBusyStatus,
+								  PidLidIntendedBusyStatus,
+								  PidLidCleanGlobalObjectId,
+								  PidLidAttendeeCriticalChange,
+								  PidLidAppointmentReplyTime,
+								  PidLidAppointmentNotAllowPropose,
+								  PidLidAllowExternalCheck,
+								  PidLidAppointmentLastSequence,
+								  PidLidAppointmentSequenceTime,
+								  PidLidAutoFillLocation,
+								  PidLidAutoStartCheck,
+								  PidLidCollaborateDoc,
+								  PidLidConferencingCheck,
+								  PidLidConferencingType,
+								  PidLidDirectory,
+								  PidLidMeetingWorkspaceUrl,
+								  PidLidNetShowUrl,
+								  PidLidOnlinePassword,
+								  PidLidOrganizerAlias,
+								  PidLidReminderSet,
+								  PidLidReminderDelta,
+								  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);
+
+				retval = GetProps(&obj_message, SPropTagArray, &lpProps, &count);
+				MAPIFreeBuffer(SPropTagArray);
+
+				if (retval == MAPI_E_SUCCESS) {
+					aRow.ulAdrEntryPad = 0;
+					aRow.cValues = count;
+					aRow.lpProps = lpProps;
+
+					ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical);
+					if (!ret) {
+						char filename[10];
+						snprintf(filename, 10, "test%i.vcf", i);
+						ical_component_VCALENDAR(&exchange2ical);
+						// Just for temporary debugging...
+						// writeVObjectToFile(filename, exchange2ical.vcalendar);
+						DEBUG(0, ("%u\n\n", i));
+						printf("ICAL file:\n%s\n", icalcomponent_as_ical_string(exchange2ical.vcalendar));
+					}
+					exchange2ical_reset(&exchange2ical);
+					MAPIFreeBuffer(lpProps);
+				}
+
+				mapi_object_release(&obj_message);
+			}
+		}
+	}
+
+	/* Uninitialize MAPI subsystem */
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	MAPIUninitialize();
+	poptFreeContext(pc);
+	talloc_free(mem_ctx);
+
+	return 0;
+}

Added: trunk/openchange/utils/exchange2ical/exchange2ical.h
===================================================================
--- trunk/openchange/utils/exchange2ical/exchange2ical.h	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical/exchange2ical.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,203 @@
+/*
+   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 <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;
+};
+
+struct exchange2ical {
+	TALLOC_CTX			*mem_ctx;
+	struct message_recipients	Recipients;
+	enum icalproperty_method	method;
+	enum icalparameter_partstat	partstat;
+	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;
+};
+
+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_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 exchange2ical_utils.c */
+struct icaltimetype get_icaltime_from_FILETIME(const struct FILETIME *);
+struct icaltimetype get_icaldate_from_FILETIME(const struct FILETIME *);
+struct tm *get_tm_from_FILETIME(const struct FILETIME *);
+struct icaltimetype get_icaltimetype_from_tm(struct tm *tm);
+struct icaldatetimeperiodtype get_icaldatetimeperiodtype_from_tm(struct tm *tm);
+
+bool has_component_DAYLIGHT(struct exchange2ical *);
+
+char *get_ical_date(TALLOC_CTX *, struct SYSTEMTIME *);
+enum icalproperty_method get_ical_method(const char *);
+enum icalparameter_partstat get_ical_partstat(const char *);
+const char *get_ical_calendartype(uint16_t);
+enum icalproperty_class get_ical_class(uint32_t);
+
+/* 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_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_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_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 *);
+
+__END_DECLS
+
+#endif /* __EXCHANGE2ICAL_H_ */

Added: trunk/openchange/utils/exchange2ical/exchange2ical_component.c
===================================================================
--- trunk/openchange/utils/exchange2ical/exchange2ical_component.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical/exchange2ical_component.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -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 <utils/exchange2ical/exchange2ical.h>
+
+#include <libical/icalderivedproperty.h>
+
+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);
+
+	/* TODO: This appears wrong - should be a parameter of the VEVENT component, ATTENDEE property */
+	if (exchange2ical->partstat != ICAL_PARTSTAT_NONE) {
+		icalparameter *param = icalparameter_new_partstat(exchange2ical->partstat);
+		icalproperty_add_parameter(prop, param);
+	}
+
+	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);
+
+	ical_component_VEVENT(exchange2ical);
+
+}
+
+void ical_component_VEVENT(struct exchange2ical *exchange2ical)
+{
+	exchange2ical->vevent = icalcomponent_new_vevent();
+	if ( ! (exchange2ical->vevent) ) {
+		return;
+	}
+	icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent);
+	/* ATTACH property FIXME */
+	ical_property_ATTENDEE(exchange2ical);
+	ical_property_CATEGORIES(exchange2ical);
+	ical_property_CLASS(exchange2ical);
+	ical_property_CONTACT(exchange2ical);
+	ical_property_CREATED(exchange2ical);
+	ical_property_DTSTART(exchange2ical);
+	ical_property_DTEND(exchange2ical);
+	ical_property_DTSTAMP(exchange2ical);
+	ical_property_DESCRIPTION(exchange2ical);
+	ical_property_EXDATE(exchange2ical);
+	ical_property_LAST_MODIFIED(exchange2ical);
+	ical_property_LOCATION(exchange2ical);
+	ical_property_ORGANIZER(exchange2ical);
+	ical_property_PRIORITY(exchange2ical);
+	ical_property_RDATE(exchange2ical);
+	ical_property_RRULE(exchange2ical);
+	/* RECURRENCE-ID property:FIXME */
+	ical_property_RECURRENCE_ID(exchange2ical);
+	ical_property_RESOURCES(exchange2ical);
+	ical_property_SEQUENCE(exchange2ical);
+	ical_property_SUMMARY(exchange2ical);
+	ical_property_TRANSP(exchange2ical);
+	ical_property_UID(exchange2ical);
+
+	/* X-ALT-DESC FIXME */
+	ical_property_X_MICROSOFT_CDO_ATTENDEE_CRITICAL_CHANGE(exchange2ical);
+	ical_property_X_MICROSOFT_CDO_BUSYSTATUS(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();
+	icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vtimezone);
+
+	/* TZID property */
+	if (exchange2ical->TimeZoneDesc) {
+		icalproperty *tzid = icalproperty_new_tzid(exchange2ical->TimeZoneDesc);
+		icalcomponent_add_property(exchange2ical->vtimezone, tzid);
+	}
+
+	/* STANDARD sub-component */
+	ical_component_STANDARD(exchange2ical);
+	
+	/* DAYLIGHT component */
+	ical_component_DAYLIGHT(exchange2ical);
+}
+
+
+/**
+   STANDARD sub-component
+ */
+void ical_component_STANDARD(struct exchange2ical *exchange2ical)
+{
+	char		*dtstart = NULL;
+	int32_t		tzoffsetfrom;
+	int32_t		tzoffsetto;
+	icalcomponent	*standard;
+	icalproperty	*prop;
+
+	/* Sanity Check */
+	if (!exchange2ical->TimeZoneStruct) return;
+
+	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);
+	}
+
+	/* TODO: RRULE property */
+	// ical_property_RRULE(exchange2ical, exchange2ical->TimeZoneStruct->stStandardDate);
+
+	/* TZOFFSETFROM property */
+	tzoffsetfrom = -1 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lDaylightBias);
+	prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom);
+	icalcomponent_add_property(standard, prop);
+
+	/* TZOFFSETTO property */
+	tzoffsetto = -1 * (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;
+
+	/* Sanity check */
+	if (has_component_DAYLIGHT(exchange2ical) == false) return;
+
+	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);
+	}
+	/* TODO: RRULE property */
+	// ical_property_RRULE(exchange2ical, exchange2ical->TimeZoneStruct->stDaylightDate);
+	
+	/* TZOFFSETFROM property */
+	tzoffsetfrom = -1 * (exchange2ical->TimeZoneStruct->lBias + exchange2ical->TimeZoneStruct->lStandardBias);
+	prop = icalproperty_new_tzoffsetfrom(tzoffsetfrom);
+	icalcomponent_add_property(daylight, prop);
+
+	/* TZOFFSETTO property */
+	tzoffsetto = -1 * (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/utils/exchange2ical/exchange2ical_property.c
===================================================================
--- trunk/openchange/utils/exchange2ical/exchange2ical_property.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical/exchange2ical_property.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1264 @@
+/*
+   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 <utils/exchange2ical/exchange2ical.h>
+#include <utils/openchange-tools.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 }
+};
+
+// 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;
+	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;
+			icalparameter *participantType;
+
+			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);
+			}
+
+			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 0
+			// TODO: fix this
+			if (exchange2ical->partstat) {
+				icalparameter *partstat;
+				partstat = icalparameter_new_partstat(exchange2ical->partstat);
+				icalproperty_add_parameter(prop, partstat);
+			}
+#endif
+			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;
+	char*		categoryList;
+	icalproperty	*prop;
+
+	/* Sanity check */
+	if (!exchange2ical->Keywords) return;
+	if (!exchange2ical->Keywords->cValues) return;
+
+	categoryList = talloc_strdup(exchange2ical->mem_ctx, exchange2ical->Keywords->lppszA[0]);
+	for (i = 1; i < exchange2ical->Keywords->cValues; ++i) {
+		categoryList = talloc_strdup_append(categoryList, ",");
+		categoryList = talloc_strdup_append(categoryList, exchange2ical->Keywords->lppszA[i]);
+	}
+	prop = icalproperty_new_categories(categoryList); 
+	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(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 this is a recurring non all-day event */
+		if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0)) {
+			// TODO: we should handle recurrence here...
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
+			prop = icalproperty_new_dtstart(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		} else {
+			/* If this is a non recurring non all-day event */
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
+			prop = icalproperty_new_dtstart(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		}
+	}
+}
+
+
+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 this is a recurring non all-day event */
+		if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0)) {
+			// TODO: we should handle recurrence here...
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole);
+			prop = icalproperty_new_dtend(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		} else {
+			/* If this is a non recurring non all-day event */
+			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole);
+			prop = icalproperty_new_dtend(icaltime);
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		}
+	}
+}
+
+
+void ical_property_DTSTAMP(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	struct icaltimetype	icaltime;
+
+	/* Sanity check */
+	if (!exchange2ical->OwnerCriticalChange) return;
+
+	/* TODO: if the property doesn't exist, we should use system
+	 * time instead 
+	 */
+
+	icaltime = get_icaltime_from_FILETIME(exchange2ical->OwnerCriticalChange);
+
+	prop = icalproperty_new_dtstamp(icaltime);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+}
+
+
+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;
+	NTTIME		time;
+	struct timeval	t;
+	struct tm	*tm;
+	icalproperty	*prop;
+
+	/* Sanity check */
+	if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
+	if (!exchange2ical->RecurrencePattern) return;
+	if (!exchange2ical->RecurrencePattern->DeletedInstanceCount) return;
+
+	for (i = 0; i < exchange2ical->RecurrencePattern->DeletedInstanceCount; i++) {
+		/* If this is an all-day appointment */
+		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			/* There is a bug in MS-OXOCAL
+			 * documentation. For all-day appointment,
+			 * DeletedInstanceDates is set to a value
+			 * which can't be the number of minutes since
+			 * blabla */
+		} else {
+			/* number of minutes between midnight of the specified
+			 * day and midnight, January 1, 1601 */
+			time = exchange2ical->RecurrencePattern->DeletedInstanceDates[i];
+			time *= 60;
+			time *= 10000000;
+			nttime_to_timeval(&t, time);
+			tm = localtime(&t.tv_sec);
+
+			prop = icalproperty_new_exdate(get_icaltimetype_from_tm(tm));
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		}
+	}
+}
+
+
+void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical)
+{
+	icalproperty		*prop;
+	struct icaltimetype	icaltime;
+
+	/* Sanity check */
+	if (!exchange2ical->LastModified) return;
+
+	/* TODO: if the property doesn't exist, we should use system
+	 * time instead 
+	 */
+
+	icaltime = get_icaltime_from_FILETIME(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);
+			}
+			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_RDATE(struct exchange2ical *exchange2ical)
+{
+	uint32_t	i;
+	NTTIME		time;
+	struct timeval	t;
+	struct tm	*tm;
+	icalproperty	*prop;
+
+	/* Sanity check */
+	if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
+	if (!exchange2ical->RecurrencePattern) return;
+	if (!exchange2ical->RecurrencePattern->ModifiedInstanceCount) return;
+
+	for (i = 0; i < exchange2ical->RecurrencePattern->ModifiedInstanceCount; i++) {
+		/* If this is an all-day appointment */
+		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
+			/* There is a bug in MS-OXOCAL
+			 * documentation. For all-day appointment,
+			 * DeletedInstanceDates is set to a value
+			 * which can't be the number of minutes since
+			 * January 1st, 1601 */
+		} else {
+			/* number of minutes between midnight of the specified
+			 * day and midnight, January 1st, 1601 */
+			time = exchange2ical->RecurrencePattern->ModifiedInstanceDates[i];
+			time *= 60;
+			time *= 10000000;
+			nttime_to_timeval(&t, time);
+			tm = localtime(&t.tv_sec);
+
+			prop = icalproperty_new_rdate(get_icaldatetimeperiodtype_from_tm(tm));
+			icalcomponent_add_property(exchange2ical->vevent, prop);
+			if (exchange2ical->TimeZoneDesc) {
+				icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
+				icalproperty_add_parameter(prop, tzid);
+			}
+		}
+	}	
+}
+
+
+#if 0
+static const char *get_RRULE_byday(uint16_t DayOfWeek)
+{
+	uint16_t	i;
+
+	for (i = 0; RRULE_byday[i].DayName; i++) {
+		if (DayOfWeek == RRULE_byday[i].DayOfWeek) {
+			return RRULE_byday[i].DayName;
+		}
+	}
+	
+	return NULL;
+}
+#endif
+
+
+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);
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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;
+
+	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;
+
+	recurrence.count = pat->OccurrenceCount;
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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;
+
+	recurrence.count = pat->OccurrenceCount;
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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;
+	}
+
+	recurrence.count = pat->OccurrenceCount;
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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(exchange2ical->apptStartWhole);
+	recurrence.by_month[0] = icaltime.month;
+	recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
+
+	recurrence.count = pat->OccurrenceCount;
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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;
+
+	// TODO: need answers from Microsoft on what is happening here
+	printf("endType:0x%x\n", pat->EndType);
+	printf("seeing %i occurences\n", pat->OccurrenceCount);
+	if (pat->EndType == END_AFTER_N_OCCURRENCES) {
+		printf("seeing %i occurences\n", pat->OccurrenceCount);
+		recurrence.count = pat->OccurrenceCount;
+	} else if (pat->EndType == END_AFTER_DATE) {
+	      // TODO: set recurrence.until = pat->EndDate;
+	}
+
+	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_RECURRENCE_ID(struct exchange2ical *exchange2ical)
+{
+	/* Sanity check */
+	if (!exchange2ical->ExceptionReplaceTime) return;
+
+	/* TODO: I'm too lazy to implement this today */
+	DEBUG(0, ("RECURRENCE-ID:\n"));
+}
+
+
+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 = lcid_langcode2langtag( *(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;
+
+	/* Sanity check */
+	if (!exchange2ical->GlobalObjectId) {
+		// printf("GlobalObjectId not found\n");
+		return;
+	}
+	
+	GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
+	if (!GlbObjId) {
+		// printf("could not get GlbObjId\n");
+		return;
+	}
+
+	outstr=talloc_init("uid");
+	if (GlbObjId->Size >= 12 && (0 == memcmp(GlbObjId->Data, GLOBAL_OBJECT_ID_DATA_START, 12))) {
+		// TODO: could this code overrun GlobalObjectId->lpb?
+		// TODO: I think we should start at 12, not at zero...
+		for (i = 0; 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 {
+		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);
+		}
+	}
+	prop = icalproperty_new_uid(outstr);
+	icalcomponent_add_property(exchange2ical->vevent, prop);
+	talloc_free(outstr);
+	talloc_free(GlbObjId);
+}
+
+
+static void ical_property_add_x_property_value(icalcomponent *parent, const char* propname, const char* value)
+{
+	icalproperty *prop;
+
+	/* Sanity checks */
+	if (!parent) return;
+	if (!propname) return;
+	if (!value) return;
+
+	prop = icalproperty_new_x(value);
+	icalproperty_set_x_name(prop, propname);
+	icalcomponent_add_property(parent, prop);
+}
+
+
+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)
+{
+	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_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;
+
+	/* FIXME: if the property doesn't exist, we should use system
+	 * time instead 
+	 */
+
+	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;
+
+	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)
+{
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-DIRECTORY", exchange2ical->Directory);
+}
+
+
+void ical_property_X_MS_OLK_MWSURL(struct exchange2ical *exchange2ical)
+{
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-MWSURL", exchange2ical->MWSURL);
+}
+
+
+void ical_property_X_MS_OLK_NETSHOWURL(struct exchange2ical *exchange2ical)
+{
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-NETSHOWURL", exchange2ical->NetShowURL);
+}
+
+void ical_property_X_MS_OLK_ONLINEPASSWORD(struct exchange2ical *exchange2ical)
+{
+	ical_property_add_x_property_value(exchange2ical->vevent, "X-MS-OLK-ONLINEPASSWORD", exchange2ical->OnlinePassword);
+}
+
+void ical_property_X_MS_OLK_ORGALIAS(struct exchange2ical *exchange2ical)
+{
+	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/utils/exchange2ical/exchange2ical_utils.c
===================================================================
--- trunk/openchange/utils/exchange2ical/exchange2ical_utils.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2ical/exchange2ical_utils.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,249 @@
+/*
+   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 <utils/exchange2ical/exchange2ical.h>
+
+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;
+}
+
+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;
+}
+
+
+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 }
+};
+
+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;
+}
+
+
+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			}
+};
+
+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(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;
+}
+
+
+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		}
+};
+
+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;
+}
+
+struct icaltimetype get_icaltimetype_from_tm(struct tm *tm)
+{
+	icaltimetype tt;
+
+	tt.year   = tm->tm_year;
+	tt.month  = tm->tm_mon;
+	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 icaldatetimeperiodtype get_icaldatetimeperiodtype_from_tm(struct tm *tm)
+{
+	struct icaldatetimeperiodtype tt;
+
+	// TODO: build tt here!
+
+	return tt;
+}
+
+struct tm *get_tm_from_FILETIME(const struct FILETIME *ft)
+{
+	NTTIME		time;
+	struct timeval	t;
+	struct tm	*tm;
+
+	time = ft->dwHighDateTime;
+	time = time << 32;
+	time |= ft->dwLowDateTime;
+	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 = ft->dwHighDateTime;
+	nttime = nttime << 32;
+	nttime |= ft->dwLowDateTime;
+	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 = ft->dwHighDateTime;
+	nttime = nttime << 32;
+	nttime |= ft->dwLowDateTime;
+	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   = 0;                                               
+	tt.minute = 0;                                                
+	tt.second = 0;
+	tt.is_date = 1;
+	tt.is_utc = 1;
+	tt.is_daylight = 0;
+	tt.zone = NULL;
+
+	return tt;
+}
\ No newline at end of file

Added: trunk/openchange/utils/exchange2mbox.c
===================================================================
--- trunk/openchange/utils/exchange2mbox.c	                        (rev 0)
+++ trunk/openchange/utils/exchange2mbox.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,820 @@
+/*
+   Convert Exchange mails to mbox
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include <samba/popt.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <param.h>
+#include <magic.h>
+
+#include "openchange-tools.h"
+
+/* Ugly and lazy but working ... */
+#define BOUNDARY	"DocE+STaALJfprDB"
+#define	MAX_READ_SIZE	0x4000
+#define	MESSAGEID	"Message-ID: "
+#define	MESSAGEID_LEN	11
+
+/**
+ * delete a message on the exchange server
+ */
+static bool delete_message(TALLOC_CTX *mem_ctx, char *msgid, 
+			   const char *profname, const char *password)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_table;
+	mapi_id_t		id_inbox;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		i;
+	uint64_t		id_message;
+
+	if (!msgid) {
+		return false;
+	}
+
+	retval = MapiLogonEx(&session, profname, password);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open the default message store */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Open Inbox */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_inbox);
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+					  PR_FID,
+					  PR_MID,
+					  PR_INTERNET_MESSAGE_ID);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &SRowSet)) == MAPI_E_SUCCESS) {
+		if (!SRowSet.cRows) break;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			const char     	*message_id;
+
+			message_id = (const char *)find_SPropValue_data(&(SRowSet.aRow[i]), PR_INTERNET_MESSAGE_ID);
+
+			if (message_id && !strncmp(message_id, msgid, strlen(msgid))) {
+				id_message = SRowSet.aRow[i].lpProps[1].value.d;
+				retval = DeleteMessage(&obj_inbox, &id_message, 1);
+				if (retval != MAPI_E_SUCCESS) return false;
+				break;
+			}
+		}
+	}
+	
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+/**
+ * Fetch message ids from the existing mbox
+ */
+static uint32_t update(TALLOC_CTX *mem_ctx, FILE *fp, 
+		       const char *profdb, char *profname,
+		       const char *password)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_profile	profile;
+	size_t			read_size;
+	char			*line = NULL;
+	ssize_t			size;
+	const char		*msgid;
+	char     		*id;
+	char			**mbox_msgids;
+	char			**prof_msgids;
+	unsigned int		mbox_count = 0;
+	unsigned int		count;
+	unsigned int		i, j;
+	bool			found = false;
+
+	retval = MAPIInitialize(profdb);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	if (!profname) {
+		retval = GetDefaultProfile(&profname);
+		MAPI_RETVAL_IF(retval, retval, NULL);
+	}
+
+	retval = OpenProfile(&profile, profname, password);
+	MAPI_RETVAL_IF(retval, retval, profname);
+
+	mbox_msgids = talloc_zero(mem_ctx, char *);
+	/* Add Message-ID attribute to the profile if it is missing */
+#if defined(__FreeBSD__)
+	while ((line = fgetln(fp, &read_size)) != NULL) {
+#else
+	while ((size = getline(&line, &read_size, fp)) != -1) {
+#endif
+		if (line && !strncmp(line, MESSAGEID, strlen(MESSAGEID))) {
+			msgid = strstr(line, MESSAGEID);
+			id = talloc_strdup(mem_ctx, msgid + strlen(MESSAGEID));
+			id[strlen(id) - 1] = 0;
+
+			mbox_msgids = talloc_realloc(mem_ctx, mbox_msgids, char *, mbox_count + 2);
+			mbox_msgids[mbox_count] = talloc_strdup(mem_ctx, id);
+			mbox_count++;
+
+			retval = FindProfileAttr(&profile, "Message-ID", id);
+			if (GetLastError() == MAPI_E_NOT_FOUND) {
+				errno = 0;
+				printf("[+] Adding %s to %s\n", id, profname);
+				retval = mapi_profile_add_string_attr(profname, "Message-ID", id);
+				if (retval != MAPI_E_SUCCESS) {
+					mapi_errstr("mapi_profile_add_string_attr", GetLastError());
+					talloc_free(profname);
+					MAPIUninitialize();
+					return -1;
+				}
+			}
+			talloc_free(id);
+		}
+		
+	}
+	if (line)
+		free(line);
+
+	/* Remove Message-ID and update Exchange mailbox if a
+	 * Message-ID is missing in mbox 
+	 */
+	retval = GetProfileAttr(&profile, "Message-ID", &count, &prof_msgids);
+	MAPI_RETVAL_IF(retval, retval, profname);
+
+	if (count != mbox_count) {
+		printf("{+] Synchonizing mbox with Exchange mailbox\n");
+		for (i = 0; i < count; i++) {
+			found = false;
+			for (j = 0; j < mbox_count; j++) {
+				if (!strcmp(prof_msgids[i], mbox_msgids[j])) {
+					found = true;
+				}
+			}
+			if (found == false) {
+				if (delete_message(mem_ctx, prof_msgids[i], profname, password) == true) {
+					printf("%s deleted from the Exchange server\n", prof_msgids[i]);
+					mapi_profile_delete_string_attr(profname, "Message-ID", prof_msgids[i]);
+				}
+			}
+		}
+	} else {
+		printf("[+] mbox already synchronized with Exchange Mailbox\n");
+	}
+
+	talloc_free(prof_msgids);
+	talloc_free(mbox_msgids);
+	talloc_free(profname);
+	MAPIUninitialize();
+
+	return MAPI_E_SUCCESS;
+}
+
+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;
+}
+
+
+static char *get_base64_attachment(TALLOC_CTX *mem_ctx, mapi_object_t obj_attach, const uint32_t size, char **magic)
+{
+	enum MAPISTATUS	retval;
+	const char     	*tmp;
+	mapi_object_t	obj_stream;
+	uint32_t	stream_size;
+	uint16_t	read_size;
+	unsigned char  	buf[MAX_READ_SIZE];
+	uint32_t	max_read_size = MAX_READ_SIZE;
+	DATA_BLOB	data;
+	magic_t		cookie = NULL;
+
+	data.length = 0;
+	data.data = talloc_size(mem_ctx, size);
+
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (size < MAX_READ_SIZE) {
+		retval = ReadStream(&obj_stream, buf, size, &read_size);
+		if (retval != MAPI_E_SUCCESS) return NULL;
+		memcpy(data.data, buf, read_size);
+	}
+
+	for (stream_size = 0; stream_size < size; stream_size += 0x4000) {
+		retval = ReadStream(&obj_stream, buf, max_read_size, &read_size);
+		if (retval != MAPI_E_SUCCESS) return NULL;
+		memcpy(data.data + stream_size, buf, read_size);
+	}
+
+	data.length = size;
+
+	cookie = magic_open(MAGIC_MIME);
+	if (cookie == NULL) {
+		printf("%s\n", magic_error(cookie));
+		return NULL;
+	}
+	if (magic_load(cookie, NULL) == -1) {
+		printf("%s\n", magic_error(cookie));
+		return NULL;
+	}
+	tmp = magic_buffer(cookie, (void *)data.data, data.length);
+	*magic = talloc_strdup(mem_ctx, tmp);
+	magic_close(cookie);
+
+	/* convert attachment to base64 */
+	return (ldb_base64_encode(mem_ctx, (const char *)data.data, data.length));
+}
+
+/**
+   Sample mbox mail:
+
+   From Administrator Mon Apr 23 14:43:01 2007
+   Date: Mon Apr 23 14:43:01 2007
+   From: Administrator 
+   To: Julien Kerihuel
+   Subject: This is the subject
+
+   This is a sample mail
+
+**/
+
+static bool message2mbox(TALLOC_CTX *mem_ctx, FILE *fp, 
+			 struct SRow *aRow, mapi_object_t *obj_message)
+{
+	enum MAPISTATUS			retval;
+	mapi_object_t			obj_tb_attach;
+	mapi_object_t			obj_attach;
+	const uint64_t			*delivery_date;
+	const char			*date = NULL;
+	const char			*from = NULL;
+	const char			*to = NULL;
+	const char			*cc = NULL;
+	const char			*bcc = NULL;
+	const char			*subject = NULL;
+	const char			*msgid;
+	DATA_BLOB			body;
+	const char			*attach_filename;
+	const uint32_t			*attach_size;
+	char				*attachment_data;
+	const uint32_t			*has_attach = NULL;
+	const uint32_t			*attach_num = NULL;
+	char				*magic;
+	char				*line = NULL;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	struct SPropValue		*lpProps;
+	struct SRow			aRow2;
+	struct SRowSet			rowset_attach;
+	uint32_t			count;
+	uint8_t				format;
+	unsigned int			i;
+	ssize_t				len;
+
+	has_attach = (const uint32_t *) octool_get_propval(aRow, PR_HASATTACH);
+	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);
+
+	if (!to && !cc && !bcc) {
+		return false;
+	}
+
+	delivery_date = (const uint64_t *)octool_get_propval(aRow, PR_MESSAGE_DELIVERY_TIME);
+	if (delivery_date) {
+		date = nt_time_string(mem_ctx, *delivery_date);
+	} else {
+		date = "None";
+	}
+
+	subject = (const char *) octool_get_propval(aRow, PR_CONVERSATION_TOPIC);
+	msgid = (const char *) octool_get_propval(aRow, PR_INTERNET_MESSAGE_ID);
+
+	retval = octool_get_body(mem_ctx, obj_message, aRow, &body);
+
+	/* First line From */
+	line = talloc_asprintf(mem_ctx, "From \"%s\" %s\n", from, date);
+	if (line) {
+		len = fwrite(line, strlen(line), 1, fp);
+	}
+	talloc_free(line);
+
+	/* Second line: Date */
+	line = talloc_asprintf(mem_ctx, "Date: %s\n", date);
+	if (line) {
+		len = fwrite(line, strlen(line), 1, fp);
+	}
+	talloc_free(line);
+
+	/* Third line From */
+	line = talloc_asprintf(mem_ctx, "From: %s\n", from);
+	if (line) {
+		len = fwrite(line, strlen(line), 1, fp);
+	}
+	talloc_free(line);
+
+	/* To, Cc, Bcc */
+	if (to) {
+		line = talloc_asprintf(mem_ctx, "To: %s\n", to);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	if (cc) {
+		line = talloc_asprintf(mem_ctx, "Cc: %s\n", cc);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	if (bcc) {
+		line = talloc_asprintf(mem_ctx, "Bcc: %s\n", bcc);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	/* Subject */
+	if (subject) {
+		line = talloc_asprintf(mem_ctx, "Subject: %s\n", subject);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	if (msgid) {
+		line = talloc_asprintf(mem_ctx, "Message-ID: %s\n", msgid);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	/* Set multi-type if we have attachment */
+	if (has_attach && *has_attach) {
+		line = talloc_asprintf(mem_ctx, "Content-Type: multipart/mixed; boundary=\"%s\"\n", BOUNDARY);
+		if (line) {
+			len = fwrite(line, strlen(line), 1, fp);
+		}
+		talloc_free(line);
+	}
+
+	/* body */
+	if (body.length) {
+		if (has_attach && *has_attach) {
+			line = talloc_asprintf(mem_ctx, "--%s\n", BOUNDARY);
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);
+		}
+		retval = GetBestBody(obj_message, &format);
+		switch (format) {
+		case olEditorText:
+			line = talloc_asprintf(mem_ctx, "Content-Type: text/plain; charset=us-ascii\n");
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);
+			
+			/* Just display UTF8 content inline */
+			line = talloc_asprintf(mem_ctx, "Content-Disposition: inline\n");
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);
+			break;
+		case olEditorHTML:
+			line = talloc_asprintf(mem_ctx, "Content-Type: text/html\n");
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);		
+			break;
+		case olEditorRTF:
+			line = talloc_asprintf(mem_ctx, "Content-Type: text/rtf\n");
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);					
+
+			line = talloc_asprintf(mem_ctx, "--%s\n", BOUNDARY);
+			if (line) {
+				len = fwrite(line, strlen(line), 1, fp);
+			}
+			talloc_free(line);
+			break;
+		}
+
+		len = fwrite(body.data, body.length, 1, fp);
+		talloc_free(body.data);
+	} 
+
+	/* We are now fetching attachments */
+	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);
+			MAPIFreeBuffer(SPropTagArray);
+			MAPI_RETVAL_IF(retval, retval, NULL);
+			
+			retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
+			MAPI_RETVAL_IF(retval, retval, NULL);
+			
+			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(obj_message, *attach_num, &obj_attach);
+				if (retval == MAPI_E_SUCCESS) {
+					SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+									  PR_ATTACH_FILENAME,
+									  PR_ATTACH_LONG_FILENAME,
+									  PR_ATTACH_SIZE);
+					lpProps = talloc_zero(mem_ctx, struct SPropValue);
+					retval = GetProps(&obj_attach, SPropTagArray, &lpProps, &count);
+					MAPIFreeBuffer(SPropTagArray);
+					if (retval == MAPI_E_SUCCESS) {
+						aRow2.ulAdrEntryPad = 0;
+						aRow2.cValues = count;
+						aRow2.lpProps = lpProps;
+
+						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));
+						}
+						attach_size = (const uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_SIZE);						
+						attachment_data = get_base64_attachment(mem_ctx, obj_attach, *attach_size, &magic);
+						if (attachment_data) {
+							line = talloc_asprintf(mem_ctx, "\n\n--%s\n", BOUNDARY);
+							if (line) {
+								len = fwrite(line, strlen(line), 1, fp);
+							}
+							talloc_free(line);
+
+							line = talloc_asprintf(mem_ctx, "Content-Disposition: attachment; filename=\"%s\"\n", attach_filename);
+							if (line) {
+								len = fwrite(line, strlen(line), 1, fp);
+							}
+							talloc_free(line);
+							
+							line = talloc_asprintf(mem_ctx, "Content-Type: \"%s\"\n", magic);
+							if (line) {
+								len = fwrite(line, strlen(line), 1, fp);
+							}
+							talloc_free(line);
+							
+							line = talloc_asprintf(mem_ctx, "Content-Transfer-Encoding: base64\n\n");
+							if (line) {
+								len = fwrite(line, strlen(line), 1, fp);
+							}
+							talloc_free(line);
+							
+							len = fwrite(attachment_data, strlen(attachment_data), 1, fp);
+							talloc_free(attachment_data);
+						}
+					}
+					MAPIFreeBuffer(lpProps);
+				}
+			}
+			if (has_attach && *has_attach) {
+				line = talloc_asprintf(mem_ctx, "\n\n--%s--\n\n\n", BOUNDARY);
+				if (line) {
+					len = fwrite(line, strlen(line), 1, fp);
+				}
+				talloc_free(line);
+			}
+		}
+		
+	}
+	
+	len = fwrite("\n\n\n", 3, 1, fp);
+
+	return true;
+}
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX			*mem_ctx;
+	enum MAPISTATUS			retval;
+	struct mapi_session		*session = NULL;
+	struct mapi_profile		*profile;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_inbox;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_message;
+	mapi_id_t			id_inbox;
+	uint32_t			count;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	struct SPropValue		*lpProps;
+	struct SRow			aRow;
+	struct SRowSet			rowset;
+	poptContext			pc;
+	int				opt;
+	FILE				*fp;
+	unsigned int			i;
+	const char			*opt_profdb = NULL;
+	char				*opt_profname = NULL;
+	const char			*opt_password = NULL;
+	const char			*opt_mbox = NULL;
+	bool				opt_update = false;
+	bool				opt_dumpdata = false;
+	const char			*opt_debug = NULL;
+	const char			*msgid;
+
+	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_MBOX, OPT_UPDATE,
+	      OPT_DEBUG, OPT_DUMPDATA};
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"},
+		{"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"},
+		{"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"},
+		{"mbox", 'm', POPT_ARG_STRING, NULL, OPT_MBOX, "set the mbox file", "FILENAME"},
+		{"update", 'u', POPT_ARG_NONE, 0, OPT_UPDATE, "mirror mbox changes back to the Exchange server", NULL},
+		{"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set the debug level", "LEVEL"},
+		{"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL},
+		POPT_OPENCHANGE_VERSION
+		{ NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "exchange2mbox");
+
+	pc = poptGetContext("exchange2mbox", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc));
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_MBOX:
+			opt_mbox = poptGetOptArg(pc);
+			break;
+		case OPT_UPDATE:
+			opt_update = true;
+			break;
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		}
+	}
+
+	/**
+	 * Sanity checks
+	 */
+
+	if (!opt_profdb) {
+		opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+	}
+
+	if (!opt_mbox) {
+		opt_mbox = talloc_asprintf(mem_ctx, DEFAULT_MBOX, getenv("HOME"));
+	}
+
+	/**
+	 * Open the MBOX
+	 */
+
+	if ((fp = fopen(opt_mbox, "a+")) == NULL) {
+		perror("fopen");
+		exit (1);
+	}
+
+	if (opt_update == true) {
+		retval = update(mem_ctx, fp, opt_profdb, opt_profname, opt_password);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			printf("Problem encountered during update\n");
+			exit (1);
+		}
+	}
+	
+	/**
+	 * Initialize MAPI subsystem
+	 */
+
+	retval = MAPIInitialize(opt_profdb);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+
+	/* if no profile is supplied use the default one */
+	if (!opt_profname) {
+		retval = GetDefaultProfile(&opt_profname);
+		if (retval != MAPI_E_SUCCESS) {
+			printf("No profile specified and no default profile found\n");
+			exit (1);
+		}
+	}
+	
+	retval = MapiLogonEx(&session, opt_profname, opt_password);
+	talloc_free(opt_profname);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		exit (1);
+	}
+	profile = session->profile;
+
+	/* Open the default message store */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenMsgStore", GetLastError());
+		exit (1);
+	}
+
+	/* Open Inbox */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	mapi_object_init(&obj_inbox);
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_INTERNET_MESSAGE_ID);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		for (i = 0; i < rowset.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_store, 
+					     rowset.aRow[i].lpProps[0].value.d, 
+					     rowset.aRow[i].lpProps[1].value.d, 
+					     &obj_message, 0);
+			if (GetLastError() == MAPI_E_SUCCESS) {
+				SPropTagArray = set_SPropTagArray(mem_ctx, 0x13,
+								  PR_INTERNET_MESSAGE_ID,
+								  PR_INTERNET_MESSAGE_ID_UNICODE,
+								  PR_CONVERSATION_TOPIC,
+								  PR_CONVERSATION_TOPIC_UNICODE,
+								  PR_MESSAGE_DELIVERY_TIME,
+								  PR_MSG_EDITOR_FORMAT,
+								  PR_BODY,
+								  PR_BODY_UNICODE,
+								  PR_HTML,
+								  PR_RTF_COMPRESSED,
+								  PR_SENT_REPRESENTING_NAME,
+								  PR_SENT_REPRESENTING_NAME_UNICODE,
+								  PR_DISPLAY_TO,
+								  PR_DISPLAY_TO_UNICODE,
+								  PR_DISPLAY_CC,
+								  PR_DISPLAY_CC_UNICODE,
+								  PR_DISPLAY_BCC,
+								  PR_DISPLAY_BCC_UNICODE,
+								  PR_HASATTACH);
+				retval = GetProps(&obj_message, SPropTagArray, &lpProps, &count);
+				MAPIFreeBuffer(SPropTagArray);
+				if (retval != MAPI_E_SUCCESS) return false;
+
+				/* Build a SRow structure */
+				aRow.ulAdrEntryPad = 0;
+				aRow.cValues = count;
+				aRow.lpProps = lpProps;
+
+				msgid = (const char *) octool_get_propval(&aRow, PR_INTERNET_MESSAGE_ID);
+				if (msgid) {
+					retval = FindProfileAttr(profile, "Message-ID", msgid);
+					if (GetLastError() == MAPI_E_NOT_FOUND) {
+						message2mbox(mem_ctx, fp, &aRow, &obj_message);
+						if (mapi_profile_add_string_attr(profile->profname, "Message-ID", msgid) != MAPI_E_SUCCESS) {
+							mapi_errstr("mapi_profile_add_string_attr", GetLastError());
+						} else {
+							printf("Message-ID: %s added to profile %s\n", msgid, profile->profname);
+						}
+					} 
+				}
+				talloc_free(lpProps);
+			} 
+			mapi_object_release(&obj_message);
+			errno = 0;
+		}
+	}
+
+	fclose(fp);
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+
+	return 0;
+}

Added: trunk/openchange/utils/mapiprofile.c
===================================================================
--- trunk/openchange/utils/mapiprofile.c	                        (rev 0)
+++ trunk/openchange/utils/mapiprofile.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,739 @@
+/*
+   Wrapper over the MAPI Profile API
+
+   OpenChange Project
+
+   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
+   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 <samba/popt.h>
+#include <param.h>
+#include "openchange-tools.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#define	DEFAULT_DIR	"%s/.openchange"
+#define	DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
+#define	DEFAULT_LCID	"0x409" /* language code ID: en-US */
+
+static void mapiprofile_createdb(const char *profdb, const char *ldif_path)
+{
+	enum MAPISTATUS retval;
+	
+	if (access(profdb, F_OK) == 0) {
+		fprintf(stderr, "[ERROR] mapiprofile: %s already exists\n", profdb);
+		exit (1);
+	}
+
+	retval = CreateProfileStore(profdb, ldif_path);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("CreateProfileStore", GetLastError());
+		exit (1);
+	}
+}
+
+static uint32_t callback(struct SRowSet *rowset, void *private)
+{
+	uint32_t		i;
+	struct SPropValue	*lpProp;
+	FILE			*fd;
+	uint32_t		index;
+	char     		entry[10];
+	const char		*label = (const char *)private;
+	char			*s;
+
+	printf("%s:\n", label);
+	for (i = 0; i < rowset->cRows; i++) {
+		lpProp = get_SPropValue_SRow(&(rowset->aRow[i]), PR_DISPLAY_NAME);
+		if (lpProp && lpProp->value.lpszA) {
+			printf("\t[%u] %s\n", i, lpProp->value.lpszA);
+		}
+	}
+	printf("\t[%u] cancel operation\n", i);
+	fd = fdopen(0, "r");
+getentry:
+	printf("Enter username id [0]: ");
+	s = fgets(entry, 10, fd);
+	index = atoi(entry);
+	if (index > i) {
+		printf("Invalid id - Must be a value between 0 and %u\n", i);
+		goto getentry;
+	}
+	
+	fclose(fd);
+	return (index);
+}
+
+const char *g_profname;
+
+static void signal_delete_profile(void)
+{
+	enum MAPISTATUS	retval;
+
+	fprintf(stderr, "CTRL-C caught ... Deleting profile\n");
+	if ((retval = DeleteProfile(g_profname)) != MAPI_E_SUCCESS) {
+		mapi_errstr("DeleteProfile", GetLastError());
+	}
+
+	(void) signal(SIGINT, SIG_DFL);
+	exit (1);
+}
+
+static void 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 *domain, const char *realm,
+			       uint32_t flags,
+			       bool opt_dumpdata, const char *opt_debuglevel)
+{
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session = NULL;
+	TALLOC_CTX		*mem_ctx;
+	struct mapi_profile	profile;
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile_create");
+
+	/* catch CTRL-C */
+	g_profname = profname;
+
+#if defined (__FreeBSD__)
+	(void) signal(SIGINT, (sig_t) signal_delete_profile);
+#else
+	(void) signal(SIGINT, (sighandler_t) signal_delete_profile);
+#endif
+
+	retval = MAPIInitialize(profdb);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debuglevel) {
+		SetMAPIDebugLevel(atoi(opt_debuglevel));
+	}
+
+	/* Sanity check */
+	retval = OpenProfile(&profile, profname, NULL);
+	if (retval == MAPI_E_SUCCESS) {
+		fprintf(stderr, "[ERROR] mapiprofile: profile \"%s\" already exists\n", profname);
+		exit (1);
+	}
+
+	retval = CreateProfile(profname, username, password, flags);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("CreateProfile", GetLastError());
+		exit (1);
+	}
+
+	mapi_profile_add_string_attr(profname, "binding", address);
+	mapi_profile_add_string_attr(profname, "workstation", workstation);
+	mapi_profile_add_string_attr(profname, "domain", domain);
+
+	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));
+	}
+	if (!lcid_valid_locale(strtoul(lcid, 0, 16))) {
+		lcid = DEFAULT_LCID;
+		printf("Language code not recognised, using default (%s) instead\n", lcid);
+	}
+
+	/* 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");
+
+	retval = MapiLogonProvider(&session, profname, password, PROVIDER_ID_NSPI);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonProvider", GetLastError());
+		printf("Deleting profile\n");
+		if ((retval = DeleteProfile(profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("DeleteProfile", GetLastError());
+		}
+		talloc_free(mem_ctx);
+		exit (1);
+	}
+
+	if (pattern) {
+		username = pattern;
+	}
+
+	retval = ProcessNetworkProfile(session, username, (mapi_profile_callback_t) callback, "Select a user id");
+	if (retval != MAPI_E_SUCCESS && retval != 0x1) {
+		mapi_errstr("ProcessNetworkProfile", GetLastError());
+		printf("Deleting profile\n");
+		if ((retval = DeleteProfile(profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("DeleteProfile", GetLastError());
+		}
+		talloc_free(mem_ctx);
+		exit (1);
+	}
+
+	printf("Profile %s completed and added to database %s\n", profname, profdb);
+
+	talloc_free(mem_ctx);
+
+	MAPIUninitialize();
+}
+
+static void mapiprofile_delete(const char *profdb, const char *profname)
+{
+	enum MAPISTATUS retval;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	if ((retval = DeleteProfile(profname)) != MAPI_E_SUCCESS) {
+		mapi_errstr("DeleteProfile", GetLastError());
+		exit (1);
+	}
+
+	printf("Profile %s deleted from database %s\n", profname, profdb);
+
+	MAPIUninitialize();
+}
+
+
+static void mapiprofile_rename(const char *profdb, const char *old_profname, const char *new_profname)
+{
+	TALLOC_CTX	*mem_ctx;
+	enum MAPISTATUS	retval;
+	char		*profname;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", retval);
+		exit (1);
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile_rename");
+
+	if (!old_profname) {
+		if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", retval);
+			talloc_free(mem_ctx);
+			exit (1);
+		}
+	} else {
+		profname = talloc_strdup(mem_ctx, old_profname);
+	}
+
+	if ((retval = RenameProfile(profname, new_profname)) != MAPI_E_SUCCESS) {
+		mapi_errstr("RenameProfile", retval);
+		talloc_free(profname);
+		talloc_free(mem_ctx);
+		exit (1);
+	}
+
+	talloc_free(profname);
+	talloc_free(mem_ctx);
+	MAPIUninitialize();
+}
+
+
+static void mapiprofile_set_default(const char *profdb, const char *profname)
+{
+	enum MAPISTATUS retval;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	if ((retval = SetDefaultProfile(profname)) != MAPI_E_SUCCESS) {
+		mapi_errstr("SetDefaultProfile", GetLastError());
+		exit (1);
+	}
+
+	printf("Profile %s is now set the default one\n", profname);
+
+	MAPIUninitialize();
+}
+
+static void mapiprofile_get_default(const char *profdb)
+{
+	enum MAPISTATUS retval;
+	char		*profname;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+	
+	if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+		mapi_errstr("GetDefaultProfile", GetLastError());
+		exit (1);
+	}
+
+	printf("Default profile is set to %s\n", profname);
+
+	talloc_free(profname);
+	MAPIUninitialize();
+}
+
+static void mapiprofile_get_fqdn(const char *profdb, 
+				 const char *opt_profname, 
+				 const char *password,
+				 bool opt_dumpdata)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session = NULL;
+	const char		*serverFQDN;
+	char			*profname;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	SetMAPIDumpData(opt_dumpdata);
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile_get_fqdn");
+
+	if (!opt_profname) {
+		if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			talloc_free(mem_ctx);
+			exit (1);
+		}
+	} else {
+		profname = talloc_strdup(mem_ctx, (char *)opt_profname);
+	}
+
+	retval = MapiLogonProvider(&session, profname, password, PROVIDER_ID_NSPI);
+	talloc_free(profname);
+	talloc_free(mem_ctx);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonProvider", GetLastError());
+		exit (1);
+	}
+
+	retval = RfrGetFQDNFromLegacyDN(session, &serverFQDN);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("RfrGetFQDNFromLegacyDN", GetLastError());
+		exit (1);
+	}
+
+	printf("%s is at %s\n", global_mapi_ctx->session->profile->homemdb, serverFQDN);
+
+	MAPIUninitialize();
+}
+
+static void mapiprofile_list(const char *profdb)
+{
+	enum MAPISTATUS retval;
+	struct SRowSet	proftable;
+	uint32_t	count = 0;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	memset(&proftable, 0, sizeof (struct SRowSet));
+	if ((retval = GetProfileTable(&proftable)) != MAPI_E_SUCCESS) {
+		mapi_errstr("GetProfileTable", GetLastError());
+		exit (1);
+	}
+
+	printf("We have %u profiles in the database:\n", proftable.cRows);
+
+	for (count = 0; count != proftable.cRows; count++) {
+		const char	*name = NULL;
+		uint32_t	dflt = 0;
+
+		name = proftable.aRow[count].lpProps[0].value.lpszA;
+		dflt = proftable.aRow[count].lpProps[1].value.l;
+
+		if (dflt) {
+			printf("\tProfile = %s [default]\n", name);
+		} else {
+			printf("\tProfile = %s\n", name);
+		}
+
+	}
+
+	MAPIUninitialize();
+}
+
+static void mapiprofile_dump(const char *profdb, const char *opt_profname)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_profile	profile;
+	char			*profname;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile_dump");
+
+	if (!opt_profname) {
+		if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			talloc_free(mem_ctx);
+			exit (1);
+		}
+	} else {
+		profname = talloc_strdup(mem_ctx, (const char *)opt_profname);
+	}
+
+	retval = OpenProfile(&profile, profname, NULL);
+	talloc_free(profname);
+	talloc_free(mem_ctx);
+	if (retval && (retval != MAPI_E_INVALID_PARAMETER)) {
+		mapi_errstr("OpenProfile", GetLastError());
+		exit (1);
+	}
+
+	printf("Profile: %s\n", profile.profname);
+	printf("\tusername       == %s\n", profile.username);
+	printf("\tpassword       == %s\n", profile.password);
+	printf("\tmailbox        == %s\n", profile.mailbox);
+	printf("\tworkstation    == %s\n", profile.workstation);
+	printf("\tdomain         == %s\n", profile.domain);
+	printf("\tserver         == %s\n", profile.server);
+
+	MAPIUninitialize();
+}
+
+static void mapiprofile_attribute(const char *profdb, const char *opt_profname, 
+				  const char *attribute)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_profile	profile;
+	char			*profname = NULL;
+	char			**value = NULL;
+	unsigned int		count = 0;
+	unsigned int		i;
+
+	if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile_attribute");
+
+	if (!opt_profname) {
+		if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			exit (1);
+		}
+	} else {
+		profname = talloc_strdup(mem_ctx, (const char *)opt_profname);
+	}
+
+	retval = OpenProfile(&profile, profname, NULL);
+	if (retval && (retval != MAPI_E_INVALID_PARAMETER)) {
+		mapi_errstr("OpenProfile", GetLastError());
+		talloc_free(profname);
+		talloc_free(mem_ctx);
+		exit (1);
+	}
+
+	if ((retval = GetProfileAttr(&profile, attribute, &count, &value))) {
+		mapi_errstr("ProfileGetAttr", GetLastError());
+		talloc_free(profname);
+		talloc_free(mem_ctx);
+		exit (1);
+	}
+
+	printf("Profile %s: results(%u)\n", profname, count);
+	for (i = 0; i < count; i++) {
+		printf("\t%s = %s\n", attribute, value[i]);
+	}
+	MAPIFreeBuffer(value);
+	talloc_free(profname);
+	talloc_free(mem_ctx);
+
+	MAPIUninitialize();
+}
+
+static void show_help(poptContext pc, const char *param)
+{
+	printf("%s argument missing\n", param);
+	poptPrintUsage(pc, stderr, 0);
+	exit (1);
+}
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX	*mem_ctx;
+	int		error;
+	poptContext	pc;
+	int		opt;
+	char		*default_path;
+	bool		create = false;
+	bool		delete = false;
+	bool		list = false;
+	bool		listlangs = false;
+	bool		dump = false;
+	bool		newdb = false;
+	bool		setdflt = false;
+	bool		getdflt = false;
+	bool		getfqdn = false;
+	bool		opt_dumpdata = false;
+	const char	*opt_debuglevel = NULL;
+	const char	*ldif = NULL;
+	const char	*address = NULL;
+	const char	*workstation = NULL;
+	const char	*domain = NULL;
+	const char	*realm = NULL;
+	const char	*username = NULL;
+	const char      *lcid = NULL;
+	const char	*pattern = NULL;
+	const char	*password = NULL;
+	const char	*profdb = NULL;
+	const char	*profname = NULL;
+	const char	*rename = NULL;
+	const char	*attribute = NULL;
+	uint32_t	nopass = 0;
+	char		hostname[256];
+
+	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_ADDRESS, OPT_WORKSTATION,
+	      OPT_DOMAIN, OPT_REALM, OPT_USERNAME, OPT_LCID, 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};
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{"ldif", 'L', POPT_ARG_STRING, NULL, OPT_PROFILE_LDIF, "set the ldif path", "PATH"},
+		{"getdefault", 'G', POPT_ARG_NONE, NULL, OPT_PROFILE_GET_DFLT, "get the default profile", NULL},
+		{"default", 'S', POPT_ARG_NONE, NULL, OPT_PROFILE_SET_DFLT, "set the default profile", NULL},
+		{"newdb", 'n', POPT_ARG_NONE, NULL, OPT_PROFILE_NEWDB, "create a new profile store", NULL},
+		{"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"},
+		{"profile", 'P', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"},
+		{"address", 'I', POPT_ARG_STRING, NULL, OPT_ADDRESS, "set the exchange server IP address", "xxx.xxx.xxx.xxx"},
+		{"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"},
+		{"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"},
+		{"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},
+		{"create", 'c', POPT_ARG_NONE, NULL, OPT_CREATE_PROFILE, "create a profile in the database", NULL},
+		{"delete", 'r', POPT_ARG_NONE, NULL, OPT_DELETE_PROFILE, "delete a profile in the database", NULL},
+		{"rename", 'R', POPT_ARG_STRING, NULL, OPT_RENAME_PROFILE, "rename a profile in the database", NULL},
+		{"list", 'l', POPT_ARG_NONE, NULL, OPT_LIST_PROFILE, "list existing profiles in the database", NULL},
+		{"listlangs", 0, POPT_ARG_NONE, NULL, OPT_LIST_LANGS, "list all recognised languages", NULL},
+		{"dump", 0, POPT_ARG_NONE, NULL, OPT_DUMP_PROFILE, "dump a profile entry", NULL},
+		{"attr", 'a', POPT_ARG_STRING, NULL, OPT_DUMP_ATTR, "print an attribute value", "VALUE"},
+		{"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL},
+		{"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUGLEVEL, "set the debug level", "LEVEL"},
+		{"getfqdn", 0, POPT_ARG_NONE, NULL, OPT_GETFQDN, "returns the DNS FQDN of the NSPI server matching the legacyDN", NULL},
+		POPT_OPENCHANGE_VERSION
+		{ NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "mapiprofile");
+
+	pc = poptGetContext("mapiprofile", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch(opt) {
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		case OPT_DEBUGLEVEL:
+			opt_debuglevel = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE_LDIF:
+			ldif = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE_NEWDB:
+			newdb = true;
+			break;
+		case OPT_PROFILE_SET_DFLT:
+			setdflt = true;
+			break;
+		case OPT_PROFILE_GET_DFLT:
+			getdflt = true;
+			break;
+		case OPT_PROFILE_DB:
+			profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			profname = poptGetOptArg(pc);
+			break;
+		case OPT_ADDRESS:
+			address = poptGetOptArg(pc);
+			break;
+		case OPT_WORKSTATION:
+			workstation = poptGetOptArg(pc);
+			break;
+		case OPT_DOMAIN:
+			domain = poptGetOptArg(pc);
+			break;
+		case OPT_REALM:
+			realm = poptGetOptArg(pc);
+			break;
+		case OPT_USERNAME:
+			username = poptGetOptArg(pc);
+			break;
+		case OPT_LCID:
+			lcid = poptGetOptArg(pc);
+			break;
+		case OPT_PATTERN:
+			pattern = poptGetOptArg(pc);
+			break;
+		case OPT_PASSWORD:
+			password = poptGetOptArg(pc);
+			break;
+		case OPT_NOPASS:
+			nopass = 1;
+			break;
+		case OPT_CREATE_PROFILE:
+			create = true;
+			break;
+		case OPT_DELETE_PROFILE:
+			delete = true;
+			break;
+		case OPT_RENAME_PROFILE:
+			rename = poptGetOptArg(pc);
+			break;
+		case OPT_LIST_PROFILE:
+			list = true;
+			break;
+		case OPT_LIST_LANGS:
+			listlangs = true;
+			break;
+		case OPT_DUMP_PROFILE:
+			dump = true;
+			break;
+		case OPT_DUMP_ATTR:
+			attribute = poptGetOptArg(pc);
+			break;
+		case OPT_GETFQDN:
+			getfqdn = true;
+			break;
+		}
+	}
+
+	/* Sanity check on options */
+	if (!profdb) {
+		default_path = talloc_asprintf(mem_ctx, DEFAULT_DIR, getenv("HOME"));
+		error = mkdir(default_path, 0700);
+		talloc_free(default_path);
+		if ((error == -1) && (errno != EEXIST)) {
+			perror("mkdir");
+			talloc_free(mem_ctx);
+			exit (1);
+		}
+		profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, 
+					 getenv("HOME"));
+	}
+
+	if ((list == false) && (getfqdn == false) && (newdb == false) && (listlangs == false)
+	    && (getdflt == false) && (dump == false) && (rename == NULL) && 
+	    (!attribute) && (!profname || !profdb)) {
+		poptPrintUsage(pc, stderr, 0);
+		exit (1);
+	}
+
+	if (newdb == true) {
+		if (!ldif) {
+			ldif = talloc_strdup(mem_ctx, mapi_profile_get_ldif_path());
+		}
+		if (!ldif) show_help(pc, "ldif");
+		mapiprofile_createdb(profdb, ldif);
+	}
+
+	/* Process the code here */
+
+	if (!workstation) {
+		gethostname(hostname, sizeof(hostname) - 1);
+		hostname[sizeof(hostname) - 1] = 0;
+		workstation = hostname;
+	}
+
+	if (create == true) {
+		if (!profname) show_help(pc, "profile");
+		if (!password) show_help(pc, "password");
+		if (!username) show_help(pc, "username");
+		if (!address) show_help(pc, "address");
+		if (!workstation) show_help(pc, "workstation");
+		if (!domain) show_help(pc, "domain");
+
+		if (!lcid) {
+		  lcid = talloc_asprintf(mem_ctx, DEFAULT_LCID);
+		}
+		mapiprofile_create(profdb, profname, pattern, username, password, address,
+				   lcid, workstation, domain, realm, nopass, opt_dumpdata, opt_debuglevel);
+	}
+
+	if (rename) {
+		mapiprofile_rename(profdb, profname, rename);
+	}
+
+	if (getfqdn == true) {
+		mapiprofile_get_fqdn(profdb, profname, password, opt_dumpdata);
+	}
+
+	if (listlangs == true) {
+		lcid_print_languages();
+	}
+
+	if (setdflt == true) {
+		mapiprofile_set_default(profdb, profname);
+	}
+
+	if (getdflt == true) {
+		mapiprofile_get_default(profdb);
+	}
+
+	if (delete == true) {
+		mapiprofile_delete(profdb, profname);
+	}
+
+	if (list == true) {
+		mapiprofile_list(profdb);
+	}
+
+	if (dump == true) {
+		mapiprofile_dump(profdb, profname);
+	}
+
+	if (attribute) {
+		mapiprofile_attribute(profdb, profname, attribute);
+	}
+
+	talloc_free(mem_ctx);
+
+	return (0);
+}

Added: trunk/openchange/utils/mapitest/Doxyfile.in
===================================================================
--- trunk/openchange/utils/mapitest/Doxyfile.in	                        (rev 0)
+++ trunk/openchange/utils/mapitest/Doxyfile.in	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1270 @@
+# Doxyfile 1.5.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MAPI Tests
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = @PACKAGE_VERSION@
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = apidocs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = YES
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = utils/mapitest utils/mapitest/modules
+
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.h *.c *.doxy
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                =  *_private.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.yy.c *_private.h
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = doc/doxygen/pictures/
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = "sed \
+			-e '20,40s/.*\<libmapi\/libmapi.h\>//'			\
+			-e '20,40s/.*\<samba\/popt.h\>//'			\
+			-e '20,40s/.*\<samba\/version.h\>//'			\
+			-e '20,40s/.*\<utils\/openchange-tools.h\>//'		\
+			-e '20,40s/.*\<utils\/mapitest\/mapitest.h\>//'		\
+			-e '20,40s/.*\<utils\/mapitest\/proto.h\>//'		\
+			-e '20,40s/.*\<errno.h\>//'				\
+			-e '20,40s/.*\<err.h\>//'				\
+			-e '20,40s/.*\<fcntl.h\>//'				\
+			-e '20,40s/.*\<param.h\>//'				\
+			-e '20,40s/.*\<time.h\>//'				\
+			-e 's/_PUBLIC_//'"
+
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html/mapitest
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = doc/doxygen/header.html
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = doc/doxygen/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = doc/doxygen/apidocs.css
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = _PUBLIC_
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen will always 
+# show the root nodes and its direct children regardless of this setting.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO

Added: trunk/openchange/utils/mapitest/mapitest.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,333 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+#include <samba/popt.h>
+#include <param.h>
+
+#include <utils/openchange-tools.h>
+#include "utils/mapitest/mapitest.h"
+
+/**
+	\file
+	Core of %mapitest implementation
+*/
+
+/**
+   Initialize %mapitest structure
+ */
+static void mapitest_init(TALLOC_CTX *mem_ctx, struct mapitest *mt)
+{
+	mt->mem_ctx = mem_ctx;
+	mt->stream = NULL;
+	memset(&mt->info, 0, sizeof (mt->info));
+	mt->session = NULL;
+
+	mt->session = NULL;
+	mt->mapi_all = true;
+	mt->confidential = false;
+	mt->no_server = false;
+	mt->color = false;
+	mt->online = false;
+	mt->mapi_suite = false;
+	mt->cmdline_calls = NULL;
+	mt->cmdline_suite = NULL;
+}
+
+/**
+  Initialize %mapitest output stream
+
+  \param mt pointer to mapitest context
+  \param filename filename to write to (can be null, for output to stdout)
+*/
+static void mapitest_init_stream(struct mapitest *mt, const char *filename)
+{
+	if (filename == NULL) {
+		mt->stream = fdopen(STDOUT_FILENO, "a");
+	} else {
+		mt->stream = fopen(filename, "w+");
+	}
+
+	if (mt->stream == NULL) {
+		err(errno, "fdopen/fopen");
+	}
+}
+
+/**
+  Clean up %mapitest output stream
+
+  \param mt pointer to mapitest context
+*/
+static void mapitest_cleanup_stream(struct mapitest *mt)
+{
+	fclose(mt->stream);
+}
+
+
+static bool mapitest_get_testnames(TALLOC_CTX *mem_ctx, struct mapitest *mt,
+				   const char *parameter)
+{
+	struct mapitest_unit	*el = NULL;
+	char			*tmp = NULL;
+
+	if ((tmp = strtok((char *)parameter, ";")) == NULL) {
+		fprintf(stderr, "Invalid testname list [;]\n");
+		return false;
+	}
+
+	el = talloc_zero(mem_ctx, struct mapitest_unit);
+	el->name = talloc_strdup(mem_ctx, tmp);
+	DLIST_ADD(mt->cmdline_calls, el);
+
+	while ((tmp = strtok(NULL, ";")) != NULL) {
+		el = talloc_zero(mem_ctx, struct mapitest_unit);
+		el->name = talloc_strdup(mem_ctx, tmp);
+		DLIST_ADD_END(mt->cmdline_calls, el, struct mapitest_unit *);
+	}
+
+	return true;
+}
+
+
+static void mapitest_list(struct mapitest *mt, const char *name)
+{
+	struct mapitest_suite		*sel;
+	struct mapitest_test		*el;
+
+	/* List all tests */
+	if (!name) {
+		for (sel = mt->mapi_suite; sel; sel = sel->next) {
+			printf("[*] Suite %s\n", sel->name);
+			printf("===================================\n");
+			printf("    * %-15s %s\n", "Name:", sel->name);
+			printf("    * %-15s %5s\n", "Description:", sel->description);
+			printf("    * Running Tests:\n");
+			for (el = sel->tests; el; el = el->next) {
+				printf("\t    - %-35s: %-10s\n", el->name, el->description);
+			}
+			printf("\n\n");
+		}
+	}
+}
+
+
+/**
+ * Retrieve server specific information
+ */
+static bool mapitest_get_server_info(struct mapitest *mt,
+				     char *opt_profname,
+				     const char *password,
+				     bool opt_dumpdata,
+				     const char *opt_debug)
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct emsmdb_info	*info = NULL;
+	struct mapi_session	*session = NULL;
+	char			*profname = NULL;
+
+	if (mt->no_server == true) return 0;
+
+	mem_ctx = talloc_named(NULL, 0, "mapitest_get_server_info");
+
+	if (!profname) {
+	  retval = GetDefaultProfile(&profname);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", retval);
+			talloc_free(mem_ctx);
+			return false;
+		}
+	} else {
+		profname = talloc_strdup(mem_ctx, opt_profname);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+
+	retval = MapiLogonEx(&session, profname, password);
+	MAPIFreeBuffer(profname);
+	talloc_free(mem_ctx);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", retval);
+		return false;
+	}
+	mt->session = session;
+
+	info = emsmdb_get_info(session);
+	memcpy(&mt->info, info, sizeof (struct emsmdb_info));
+
+	/* extract org and org_unit from info.mailbox */
+	mt->org = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/o=");
+	mt->org_unit = x500_get_dn_element(mt->mem_ctx, info->szDNPrefix, "/ou=");
+	
+	return true;
+}
+
+
+
+/**
+ *  main program
+ */
+int main(int argc, const char *argv[])
+{
+	enum MAPISTATUS		retval;
+	int32_t			num_tests_failed;
+	TALLOC_CTX		*mem_ctx;
+	struct mapitest		mt;
+	poptContext		pc;
+	int			opt;
+	bool			ret;
+	bool			opt_dumpdata = false;
+	const char     		*opt_debug = NULL;
+	const char		*opt_profdb = NULL;
+	char			*opt_profname = NULL;
+	const char		*opt_username = NULL;
+	const char		*opt_password = NULL;
+	const char		*opt_outfile = NULL;
+
+	enum { OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_USERNAME, OPT_PASSWORD,
+	       OPT_CONFIDENTIAL, OPT_OUTFILE, OPT_MAPI_ALL, OPT_MAPI_CALLS,
+	       OPT_MAPIADMIN_ALL, OPT_NO_SERVER, OPT_LIST_ALL, OPT_DUMP_DATA,
+	       OPT_DEBUG, OPT_COLOR };
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{ "database",     'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB,    "set the profile database", NULL },
+		{ "profile",      'p', POPT_ARG_STRING, NULL, OPT_PROFILE,       "set the profile name", NULL },
+		{ "username",     'u', POPT_ARG_STRING, NULL, OPT_USERNAME,      "set the account username", NULL },
+		{ "password",     'p', POPT_ARG_STRING, NULL, OPT_PASSWORD,      "set the profile or account password", NULL },
+		{ "confidential",  0,  POPT_ARG_NONE,   NULL, OPT_CONFIDENTIAL,  "remove any sensitive data from the report", NULL },
+		{ "color",         0,  POPT_ARG_NONE,   NULL, OPT_COLOR,         "color MAPI retval", NULL },
+		{ "outfile",      'o', POPT_ARG_STRING, NULL, OPT_OUTFILE,       "set the report output file", NULL },
+		{ "mapi-calls",    0,  POPT_ARG_STRING, NULL, OPT_MAPI_CALLS,    "test custom ExchangeRPC tests", NULL },
+		{ "list-all",      0,  POPT_ARG_NONE,   NULL, OPT_LIST_ALL,      "list suite and tests - names and description", NULL },
+		{ "no-server",     0,  POPT_ARG_NONE,   NULL, OPT_NO_SERVER,     "only run tests that do not require server connection", NULL },
+		{ "dump-data",     0,  POPT_ARG_NONE,   NULL, OPT_DUMP_DATA,     "dump the hex data", NULL },
+		{ "debuglevel",   'd', POPT_ARG_STRING, NULL, OPT_DEBUG,         "set debug level", NULL },
+		POPT_OPENCHANGE_VERSION
+		{ NULL, 0, 0, NULL, 0, NULL, NULL }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "mapitest");
+	mapitest_init(mem_ctx, &mt);
+	mapitest_register_modules(&mt);
+
+	pc = poptGetContext("mapitest", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_DUMP_DATA:
+			opt_dumpdata = true;
+			break;
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+		  opt_profname = talloc_strdup(mem_ctx, (char *)poptGetOptArg(pc));
+			break;
+		case OPT_USERNAME:
+			opt_username = poptGetOptArg(pc);
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_CONFIDENTIAL:
+			mt.confidential = true;
+			break;
+		case OPT_OUTFILE:
+			opt_outfile = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_CALLS:
+			ret = mapitest_get_testnames(mem_ctx, &mt, poptGetOptArg(pc));
+			if (ret == false) exit (-1);
+			mt.mapi_all = false;
+			break;
+		case OPT_NO_SERVER:
+			mt.no_server = true;
+			break;
+		case OPT_COLOR:
+			mt.color = true;
+			break;
+		case OPT_LIST_ALL:
+			mapitest_list(&mt, NULL);
+			talloc_free(mem_ctx);
+			poptFreeContext(pc);
+			return 0;
+			break;
+		}
+	}
+
+	poptFreeContext(pc);
+
+	/* Sanity check */
+	if (mt.cmdline_calls && (mt.mapi_all == true)) {
+		fprintf(stderr, "mapi-calls and mapi-all can't be set at the same time\n");
+		return -1;
+	}
+
+	/* Initialize MAPI subsystem */
+	if (!opt_profdb) {
+		opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+	}
+
+	retval = MAPIInitialize(opt_profdb);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", retval);
+		return -2;
+	}
+
+	mapitest_init_stream(&mt, opt_outfile);
+	
+	mt.online = mapitest_get_server_info(&mt, opt_profname, opt_password,
+					     opt_dumpdata, opt_debug);
+
+	mapitest_print_headers(&mt);
+
+	/* Run custom tests */
+	if (mt.cmdline_calls) {
+		struct mapitest_unit	*el;
+		bool			ret;
+		
+		for (el = mt.cmdline_calls; el; el = el->next) {
+			printf("[*] %s\n", el->name);
+			ret = mapitest_run_test(&mt, el->name);
+		}
+	} else {
+		mapitest_run_all(&mt);
+	}
+
+	num_tests_failed = mapitest_stat_dump(&mt);
+
+	mapitest_cleanup_stream(&mt);
+
+	/* Uninitialize and free memory */
+	MAPIUninitialize();
+	talloc_free(mt.mem_ctx);
+
+	return num_tests_failed;
+}

Added: trunk/openchange/utils/mapitest/mapitest.h
===================================================================
--- trunk/openchange/utils/mapitest/mapitest.h	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,204 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 __MAPITEST_H__
+#define	__MAPITEST_H__
+
+#include <libmapi/libmapi.h>
+
+#include <errno.h>
+#include <err.h>
+
+/* forward declaration */
+struct mapitest;
+struct mapitest_suite;
+
+#include "utils/mapitest/proto.h"
+
+/**
+	\file mapitest.h
+ 	Data structures for %mapitest
+ */
+
+/**
+	A list of %mapitest tests
+
+	%mapitest tests are grouped into test suites. This linked
+	list data structure represents the various tests as a
+	list of tests (i.e. the linked list is a suite of tests).
+
+	The function that executes the test is pointed to by the
+	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 */
+};
+
+/**
+	List of test names
+
+	This linked list data structure has a list of names of tests. It is
+	used with mapitest_stat to record the failed tests.
+*/
+struct mapitest_unit {
+	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 */
+};
+
+/**
+	%mapitest statistics
+
+	During a %mapitest run, %mapitest collects statistics on each test suite.
+
+	This data structure records the results for one run of a test suite.
+
+	There should be one entry in the failure_info list for each failure.
+*/
+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 */
+	struct mapitest_unit	*failure_info; /*!< List of names of the tests that failed */
+	bool			enabled;       /*!< Whether this statistics structure is valid */
+};
+
+/**
+	A list of test suites
+
+	%mapitest executes a set of tests. Those tests are grouped into
+	suites of related tests (e.g. all tests that do not require a 
+	server are in one suite, the tests for NSPI are in another suite,
+	and so on). This linked list data structure represents the various
+	test suites to be executed.
+*/
+struct mapitest_suite {
+	struct mapitest_suite	*prev;        /*!< Pointer to the previous test suite */
+	struct mapitest_suite	*next;        /*!< Pointer to the next test suite */
+	char			*name;        /*!< The name of the test suite */
+	char			*description; /*!< Description of the test suite */
+	bool			online;       /*!< Whether this suite requires a server */
+	struct mapitest_test	*tests;       /*!< The tests in this suite */
+	struct mapitest_stat	*stat;        /*!< Results of running this test */
+};
+
+/**
+	The context structure for a %mapitest run
+*/
+struct mapitest {
+	TALLOC_CTX		*mem_ctx;	/*!< talloc memory context for memory allocations */
+	struct mapi_session	*session;
+	bool			confidential;	/*!< true if confidential information should be omitted */
+	bool			no_server;	/*!< true if only non-server tests should be run */
+	bool			mapi_all;	/*!< true if all tests should be run */
+	bool			online;		/*!< true if the server could be accessed */
+	bool			color;		/*!< true if the output should be colored */
+	struct emsmdb_info	info;
+	struct mapitest_suite	*mapi_suite;	/*!< the various test suites */
+	struct mapitest_unit   	*cmdline_calls;
+	struct mapitest_unit   	*cmdline_suite;
+	const char		*org;
+	const char		*org_unit;
+	FILE			*stream;
+	void			*priv;
+};
+
+struct mapitest_module {
+	char			*name;
+	
+};
+
+/**
+   Context for %mapitest test folder
+*/
+struct mt_common_tf_ctx
+{
+	mapi_object_t	obj_store;
+	mapi_object_t	obj_top_folder;
+	mapi_object_t	obj_test_folder;
+	mapi_object_t	obj_test_msg[10];
+};
+
+
+/*
+ *  Defines
+ */
+#define	MAPITEST_SUCCESS	0
+#define	MAPITEST_ERROR		-1
+
+#define	MT_STREAM_MAX_SIZE	0x3000
+
+#define	MT_YES			"[yes]"
+#define	MT_NO			"[no]"
+
+#define	MT_CONFIDENTIAL	"[Confidential]"
+
+#define	MT_HDR_START		"#############################[mapitest report]#################################\n"
+#define	MT_HDR_END		"###############################################################################\n"
+#define	MT_HDR_FMT		"[*] %-25s: %-20s\n"
+#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_DIRNAME_TOP		"[MT] Top of Mailbox"
+#define	MT_DIRNAME_APPOINTMENT	"[MT] Calendar"
+#define	MT_DIRNAME_CONTACT	"[MT] Contact"
+#define	MT_DIRNAME_JOURNAL	"[MT] Journal"
+#define	MT_DIRNAME_POST		"[MT] Post"
+#define	MT_DIRNAME_NOTE		"[MT] Note"
+#define	MT_DIRNAME_STICKYNOTE	"[MT] Sticky Notes"
+#define	MT_DIRNAME_TASK		"[MT] Tasks"
+#define	MT_DIRNAME_TEST		"[MT] Test Folder1"
+
+#define	MT_MAIL_SUBJECT		"[MT] Sample E-MAIL"
+#define	MT_MAIL_ATTACH		"[MT]_Sample_Attachment.txt"
+#define	MT_MAIL_ATTACH2		"[MT]_Sample_Attachment2.txt"
+
+#define	MODULE_TITLE		"[MODULE] %s\n"
+#define	MODULE_TITLE_DELIM	'#'
+#define	MODULE_TITLE_NEWLINE	2
+#define	MODULE_TITLE_LINELEN	80
+
+#define	MODULE_TEST_TITLE	"[TEST] %s\n"
+#define	MODULE_TEST_RESULT	"[RESULT] %s: %s\n"
+#define	MODULE_TEST_DELIM	'-'
+#define	MODULE_TEST_DELIM2	'='
+#define	MODULE_TEST_LINELEN	72
+#define	MODULE_TEST_NEWLINE	1
+#define	MODULE_TEST_SUCCESS	"[SUCCESS]"
+#define	MODULE_TEST_FAILURE	"[FAILURE]"
+
+#define	MT_ERROR       	"[ERROR]: %s\n"
+
+#define	MT_STAT_TITLE	"[STAT] FAILURE REPORT\n"
+#define	MT_STAT_FAILURE	"* %-35s: %s\n"
+
+#define MT_SUMMARY_TITLE "[STAT] TEST SUMMARY\n"
+
+#define	MT_WHITE	   "\033[0;29m"
+#define MT_RED             "\033[1;31m"
+#define MT_GREEN           "\033[1;32m"
+
+#endif /* !__MAPITEST_H__ */

Added: trunk/openchange/utils/mapitest/mapitest_common.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_common.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest_common.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,534 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+
+#include <utils/openchange-tools.h>
+#include <utils/mapitest/mapitest.h>
+
+#include <fcntl.h>
+
+/**
+	\file
+	Support functions for %mapitest modules
+
+	These functions implement commonly needed functionality that
+	would otherwise be copied into each module implementation
+*/
+
+/**
+     Opens a default folder
+
+     This function opens one of the default (standard) folders,
+     returning the folder as obj_child. olNum may be one of:
+	- olFolderTopInformationStore
+	- olFolderDeletedItems
+	- olFolderOutbox
+	- olFolderSentMail
+	- olFolderInbox
+	- olFolderCalendar
+	- olFolderContacts
+	- olFolderJournal
+	- olFolderNotes
+	- olFolderTasks
+	- olFolderDrafts
+
+     \param mt pointer to the top level mapitest structure
+     \param obj_parent parent folder (usually the message store, must be opened)
+     \param obj_child the folder that has been opened
+     \param olNum the folder identifier (see list above)
+
+     \return true on success, false on failure
+ */
+_PUBLIC_ bool mapitest_common_folder_open(struct mapitest *mt,
+					  mapi_object_t *obj_parent, 
+					  mapi_object_t *obj_child,
+					  uint32_t olNum)
+{
+	enum MAPISTATUS	retval;
+	mapi_id_t	id_child;
+
+	retval = GetDefaultFolder(obj_parent, &id_child, olNum);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetDefaultFolder", GetLastError());
+		return false;
+	}
+
+	retval = OpenFolder(obj_parent, id_child, obj_child);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenFolder", GetLastError());
+		return false;
+	}
+
+	return true;
+}
+
+/**
+   This function deletes messages in a folder, based on matching the subject
+   name. This is meant to clean up a folder after a test has been run.
+
+   \param mt pointer to the top level mapitest structure
+   \param obj_folder the folder to search through
+   \param subject the message subject to match
+*/
+_PUBLIC_ bool mapitest_common_message_delete_by_subject(struct mapitest *mt,
+							mapi_object_t *obj_folder,
+							const char *subject)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		msgids[1];
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		count;
+	const char		*msubject = NULL;
+	uint32_t		i;
+
+	/* Sanity checks */
+	if (subject == NULL) return false;
+
+	/* Retrieve the contents table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(obj_folder, &obj_ctable, 0, &count);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetContentsTable", GetLastError());
+		mapi_object_release(&obj_ctable);
+		return false;
+	}
+
+	/* Customize the content table view */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
+					  PR_MID,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != 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) {
+		for (i = 0; i < SRowSet.cRows; i++) {
+			if (retval == MAPI_E_SUCCESS) {
+				msgids[0] = SRowSet.aRow[i].lpProps[0].value.d;
+				msubject = (const char *)find_SPropValue_data(&SRowSet.aRow[i], PR_SUBJECT);
+				if (msubject && !strncmp(subject, msubject, strlen(subject))) {
+					DeleteMessage(obj_folder, msgids, 1);
+				}
+			}
+		}
+	}
+	mapi_object_release(&obj_ctable);
+	return false;
+}
+
+
+/**
+   Find a folder within a container
+ */
+_PUBLIC_ bool mapitest_common_find_folder(struct mapitest *mt,
+					  mapi_object_t *obj_parent,
+					  mapi_object_t *obj_child,
+					  const char *name)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		rowset;
+	mapi_object_t		obj_htable;
+	const char		*tmp;
+	char			*newname;
+	const uint64_t		*fid;
+	uint32_t		count;
+	uint32_t		index;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(obj_parent, &obj_htable, 0, &count);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_htable);
+		return false;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
+					  PR_DISPLAY_NAME,
+					  PR_FID);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_htable);
+		return false;
+	}
+
+	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 = 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);
+		}
+	}
+
+	mapi_object_release(&obj_htable);
+	return false;
+}
+
+
+/**
+ * Create a message ready to submit
+ */
+_PUBLIC_ bool mapitest_common_message_create(struct mapitest *mt,
+					     mapi_object_t *obj_folder, 
+					     mapi_object_t *obj_message,
+					     const char *subject)
+{
+	enum MAPISTATUS		retval;
+
+	/* Create the mesage */
+	retval = CreateMessage(obj_folder, obj_message);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateMessage", GetLastError());
+		return false;
+	}
+
+	return mapitest_common_message_fill(mt, obj_message, subject);
+}
+
+/**
+ * Create a message ready to submit
+ */
+_PUBLIC_ bool mapitest_common_message_fill(struct mapitest *mt,
+					   mapi_object_t *obj_message,
+					   const char *subject)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct SPropValue	SPropValue;
+	struct SPropValue	lpProps[4];
+	const char	       	*username[2];
+	const char		*body;
+	uint32_t		msgflag;
+	uint32_t		format;
+
+	/* Sanity checks */
+	if (subject == NULL) return false;
+
+	/* Resolve recipients */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	username[0] = (const char *)mt->info.szDisplayName;
+	username[1] = NULL;
+
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	flaglist = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+
+	retval = ResolveNames(mapi_object_get_session(obj_message), username, SPropTagArray, 
+			      &SRowSet, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "ResolveNames", GetLastError());
+		talloc_free(SRowSet);
+		talloc_free(SPropTagArray);
+		talloc_free(flaglist);
+		return false;
+	}
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+
+	/* Set Recipients */
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
+	retval = ModifyRecipients(obj_message, SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
+	if (retval != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "ModifyRecipients", retval);
+		return false;
+	}
+
+	/* Set message properties */
+	msgflag = MSGFLAG_SUBMIT;
+	set_SPropValue_proptag(&lpProps[0], PR_SUBJECT, (const void *) subject);
+	set_SPropValue_proptag(&lpProps[1], PR_MESSAGE_FLAGS, (const void *)&msgflag);
+	body = talloc_asprintf(mt->mem_ctx, "Body of message with subject: %s", subject);
+	set_SPropValue_proptag(&lpProps[2], PR_BODY, (const void *)body);
+	format = EDITOR_FORMAT_PLAINTEXT;
+	set_SPropValue_proptag(&lpProps[3], PR_MSG_EDITOR_FORMAT, (const void *)&format);
+
+	retval = SetProps(obj_message, lpProps, 4);
+	if (retval != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetProps", retval);
+		return false;
+	}
+
+	errno = 0;
+	return true;
+}
+
+
+/**
+   Generate a random blob of readable data
+
+   \param mem_ctx the talloc memory context to create the blob in
+   \param len the length of the blob to create
+
+   \return random blob of readable data, of length len bytes, with a
+           null terminator.
+
+   \note the data is from 0..len, and the null terminator is at position
+         len+1. So the returned array is actually len+1 bytes in total.
+
+ */
+_PUBLIC_ char *mapitest_common_genblob(TALLOC_CTX *mem_ctx, size_t len)
+{
+	int		fd;
+	int		ret;
+	unsigned int	i;
+	char		*retstr;
+	const char	*list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,";
+	int		list_len = strlen(list);
+
+	/* Sanity check */
+	if (!mem_ctx || (len == 0)) {
+		return NULL;
+	}
+
+	fd = open("/dev/urandom", O_RDONLY, 0);
+	if (fd == -1) {
+		return NULL;
+	}
+
+	retstr = talloc_array(mem_ctx, char, len + 1);
+	if ((ret = read(fd, retstr, len)) == -1) {
+		talloc_free(retstr);
+		return NULL;
+	}
+
+	for (i = 0; i < len; i++) {
+		retstr[i] = list[retstr[i] % list_len];
+		if (!retstr[i]) {
+			retstr[i] = 'X';
+		}
+	}
+	retstr[i] = '\0';
+
+	return retstr;
+}
+
+/**
+	Create a test folder, and fill with 10 sample messages
+
+	This function creates a test folder (name set by the MT_DIRNAME_TEST define),
+	and fills it with 5 messages with the same subject and 5 messages with the
+	same sender.
+
+	\param mt pointer to the mapitest context
+*/
+_PUBLIC_ bool mapitest_common_create_filled_test_folder(struct mapitest *mt)
+{
+	struct mt_common_tf_ctx	*context;
+	enum MAPISTATUS		retval;
+	const char		*from = NULL;
+	const char		*subject = NULL;
+	const char		*body = NULL;
+	struct SPropValue	lpProp[3];
+	int 			i;
+	uint32_t		format;
+
+	context = mt->priv;
+
+	/* Create test folder */
+	mapi_object_init(&(context->obj_test_folder));
+        retval = CreateFolder(&(context->obj_top_folder), FOLDER_GENERIC,
+			      MT_DIRNAME_TEST, NULL,
+                              OPEN_IF_EXISTS, &(context->obj_test_folder));
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create the test folder", GetLastError());
+		return false;
+	}
+
+	/* Create 5 test messages in the test folder with the same subject */
+	for (i = 0; i < 5; ++i) {
+		mapi_object_init(&(context->obj_test_msg[i]));
+		retval = mapitest_common_message_create(mt, &(context->obj_test_folder),
+							&(context->obj_test_msg[i]), MT_MAIL_SUBJECT);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create test message", GetLastError());
+			mapi_object_release(&(context->obj_test_folder));
+			return false;
+		}
+
+		from = talloc_asprintf(mt->mem_ctx, "[MT] Dummy%i", i);
+		set_SPropValue_proptag(&lpProp[0], PR_SENDER_NAME, (const void *)from);
+		body = talloc_asprintf(mt->mem_ctx, "Body of message %i", i);
+		set_SPropValue_proptag(&lpProp[1], PR_BODY, (const void *)body);
+		format = EDITOR_FORMAT_PLAINTEXT;
+		set_SPropValue_proptag(&lpProp[2], PR_MSG_EDITOR_FORMAT, (const void *)&format);
+		retval = SetProps(&(context->obj_test_msg[i]), lpProp, 3);
+		MAPIFreeBuffer((void *)from);
+		MAPIFreeBuffer((void *)body);
+		if (retval != MAPI_E_SUCCESS) {
+			mapitest_print(mt, "* %-35s: 0x%.8x\n", "Set props on message", GetLastError());
+			mapi_object_release(&(context->obj_test_folder));
+			return false;
+		}
+		retval = SaveChangesMessage(&(context->obj_test_folder), &(context->obj_test_msg[i]), KeepOpenReadWrite);
+		if (retval != MAPI_E_SUCCESS) {
+			mapitest_print(mt, "* %-35s: 0x%.8x\n", "Save changes to  message", GetLastError());
+			mapi_object_release(&(context->obj_test_folder));
+			return false;
+		}
+	}
+
+	/* Create 5 test messages in the test folder with the same sender */
+	for (i = 5; i < 10; ++i) {
+		mapi_object_init(&(context->obj_test_msg[i]));
+		subject = talloc_asprintf(mt->mem_ctx, "[MT] Subject%i", i);
+		retval = mapitest_common_message_create(mt, &(context->obj_test_folder),
+							&(context->obj_test_msg[i]), subject);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create test message", GetLastError());
+			return false;
+		}
+
+		from = talloc_asprintf(mt->mem_ctx, "[MT] Dummy From");
+		set_SPropValue_proptag(&lpProp[0], PR_SENDER_NAME, (const void *)from);
+		body = talloc_asprintf(mt->mem_ctx, "Body of message %i", i);
+		set_SPropValue_proptag(&lpProp[1], PR_BODY, (const void *)body);
+		format = EDITOR_FORMAT_PLAINTEXT;
+		set_SPropValue_proptag(&lpProp[2], PR_MSG_EDITOR_FORMAT, (const void *)&format);
+		retval = SetProps(&(context->obj_test_msg[i]), lpProp, 3);
+		MAPIFreeBuffer((void *)from);
+		MAPIFreeBuffer((void *)body);
+		if (retval != MAPI_E_SUCCESS) {
+			mapitest_print(mt, "* %-35s: 0x%.8x\n", "Set props on message", GetLastError());
+			return false;
+		}
+		retval = SaveChangesMessage(&(context->obj_test_folder), &(context->obj_test_msg[i]), KeepOpenReadWrite);
+		if (retval != MAPI_E_SUCCESS) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+/**
+   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
+   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 count the number of rows in the top level hierarchy table
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_common_setup(struct mapitest *mt, mapi_object_t *obj_htable, uint32_t *count)
+{
+	bool			ret = false;
+	struct mt_common_tf_ctx	*context;
+
+	context = talloc(mt->mem_ctx, struct mt_common_tf_ctx);
+	mt->priv = context;
+
+	mapi_object_init(&(context->obj_store));
+	OpenMsgStore(mt->session, &(context->obj_store));
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&(context->obj_top_folder));
+	ret = mapitest_common_folder_open(mt, &(context->obj_store), &(context->obj_top_folder), 
+					  olFolderTopInformationStore);
+	if (ret == false) {
+		return false;
+	}
+
+	/* We do this before getting the hierachy 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) {
+		return false;
+	}
+
+	mapi_object_init(obj_htable);
+	GetHierarchyTable(&(context->obj_top_folder), obj_htable, 0, count);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+/**
+   Convenience function to clean up after logging into the server
+
+   This functions cleans up after a mapitest_common_setup() call
+
+   \param mt pointer to the top-level mapitest structure
+*/
+_PUBLIC_ void mapitest_common_cleanup(struct mapitest *mt)
+{
+	struct mt_common_tf_ctx	*context;
+	int			i;
+
+	context = mt->priv;
+
+	for (i = 0; i<10; ++i) {
+		mapi_object_release(&(context->obj_test_msg[i]));
+	}
+
+	EmptyFolder(&(context->obj_test_folder));
+	if (GetLastError() != 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) {
+		mapitest_print(mt, "* %-35s: 0x%.8x\n", "Delete test folder", GetLastError());
+	}
+
+	mapi_object_release(&(context->obj_test_folder));
+	mapi_object_release(&(context->obj_top_folder));
+	mapi_object_release(&(context->obj_store));
+
+	talloc_free(mt->priv);
+}
+

Added: trunk/openchange/utils/mapitest/mapitest_print.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_print.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest_print.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,476 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+#include <samba/version.h>
+#include <utils/mapitest/mapitest.h>
+
+#include <time.h>
+
+static int count = 0;
+
+#define	CNT_INDENT()	{ count++; }
+#define	CNT_DEINDENT()	{ count--; if (count < 0) count = 0; }
+#define	CNT_PRINT(s)	{ int i; for (i = 0; i < count; i++) { fprintf(s, "\t"); } }
+
+/**
+	\file
+	Print / display functions for %mapitest output
+*/
+
+/**
+   \details Indent the mapitest_print tabulation counter
+ */
+_PUBLIC_ void mapitest_indent(void)
+{
+	CNT_INDENT();
+}
+
+
+/**
+   \details Deindent the mapitest_print tabulation counter
+ */
+_PUBLIC_ void mapitest_deindent(void)
+{
+	CNT_DEINDENT();
+}
+
+
+/**
+   \details Print tabulations given the internal counter
+
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_tab(struct mapitest *mt)
+{
+	CNT_PRINT(mt->stream);
+}
+
+
+/**
+   \details Print a string in the stream
+
+   \param mt pointer to the top-level mapitest structure
+   \param format the format string
+   \param ... the format string parameters
+ */
+_PUBLIC_ void mapitest_print(struct mapitest *mt, const char *format, ...)
+{
+	va_list		ap;
+	char		*s = NULL;
+	int		ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	mapitest_print_tab(mt);
+	fprintf(mt->stream, s, strlen(s));
+	free(s);
+}
+
+/**
+   \details Print newline characters
+
+   \param mt pointer to the top-level mapitest structure
+   \param count number of newline characters to print
+ */
+_PUBLIC_ void mapitest_print_newline(struct mapitest *mt, int count)
+{
+	int	i;
+
+	for (i = 0; i < count; i++) {
+		fprintf(mt->stream, "\n");
+	}
+}
+
+/**
+   \details Print a line using a delimiter
+
+   \param mt pointer to the top-level mapitest structure
+   \param len the length of the line to print
+   \param delim the line delimiter
+ */
+_PUBLIC_ void mapitest_print_line(struct mapitest *mt, int len, char delim)
+{
+	int	i;
+
+	for (i = 0; i < len; i++) {
+		fprintf(mt->stream, "%c", delim);
+	}
+	mapitest_print_newline(mt, 1);
+}
+
+
+/**
+   \details Underline a string
+
+   \param mt pointer to the top-level mapitest structure
+   \param str string to underline
+   \param delim the line delimiter
+ */
+_PUBLIC_ void mapitest_underline(struct mapitest *mt, const char *str, char delim)
+{
+	if (!str) return;
+
+	/* print str */
+	mapitest_print_tab(mt);
+	fprintf(mt->stream, "%s", str);
+
+	/* underline str using delim */
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, strlen(str), delim);
+}
+
+/**
+   \details Private general routine used to print a title
+
+   Avoid code redundancy over the API
+
+   \param mt pointer to the top-level mapitest structure
+   \param str the title
+   \param delim the underline delimiter
+ */
+_PUBLIC_ void mapitest_print_title(struct mapitest *mt, const char *str, char delim)
+{
+	mapitest_underline(mt, str, delim);
+	mapitest_indent();
+}
+
+
+/**
+   \details Print the module title
+
+   \param mt pointer to the top-level mapitest structure
+   \param str the module title string
+ */
+_PUBLIC_ void mapitest_print_module_title_start(struct mapitest *mt, const char *str)
+{
+	char	*title = NULL;
+
+	if (!str) return;
+
+	title = talloc_asprintf(mt->mem_ctx, MODULE_TITLE, str);
+	mapitest_print(mt, "%s", title);
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, MODULE_TITLE_LINELEN, MODULE_TITLE_DELIM);
+	mapitest_indent();
+	talloc_free(title);
+}
+
+/**
+   \details Print the content at the end of the module
+
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_module_title_end(struct mapitest *mt)
+{
+	mapitest_deindent();
+
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, MODULE_TITLE_LINELEN, MODULE_TITLE_DELIM);
+	mapitest_print_newline(mt, MODULE_TITLE_NEWLINE);
+}
+
+
+/**
+   \details print the test tile
+   
+   \param mt pointer to the top-level mapitest structure
+   \param str the test title
+ */
+_PUBLIC_ void mapitest_print_test_title_start(struct mapitest *mt, const char *str)
+{
+	char		*title = NULL;
+
+	if (!str) return;
+
+	title = talloc_asprintf(mt->mem_ctx, MODULE_TEST_TITLE, str);
+	mapitest_print(mt, "%s", title);
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM);
+	mapitest_indent();
+	talloc_free(title);
+}
+
+
+/**
+   \details Write the content at the end of a test
+
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_test_title_end(struct mapitest *mt)
+{
+	mapitest_deindent();
+
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM);
+}
+
+
+/**
+   \details Starts the header output
+
+   \param mt pointer on the top-level mapitest structure
+ */
+static void mapitest_print_headers_start(struct mapitest *mt)
+{
+	mapitest_print(mt, MT_HDR_START);
+}
+
+
+/**
+   \details Ends the header output
+ */
+static void mapitest_print_headers_end(struct mapitest *mt)
+{
+	mapitest_print(mt, MT_HDR_END);
+}
+
+/**
+   \details Print mapitest report headers information
+   
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_headers_info(struct mapitest *mt)
+{
+	time_t		t;
+	char		*date;
+
+	time (&t);
+	date = ctime(&t);
+
+	mapitest_print(mt, MT_HDR_FMT_DATE, "Date", date);
+	mapitest_print(mt, MT_HDR_FMT, "Confidential mode", 
+		       (mt->confidential == true) ? MT_YES : MT_NO);
+	mapitest_print(mt, MT_HDR_FMT, "Samba Information", SAMBA_VERSION_STRING);
+	mapitest_print(mt, MT_HDR_FMT, "OpenChange Information", OPENCHANGE_VERSION_STRING);
+
+	mapitest_print_newline(mt, 1);
+	mapitest_print(mt, MT_HDR_FMT_SECTION, "System Information");
+	mapitest_indent();
+	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Kernel name", OPENCHANGE_SYS_KERNEL_NAME);
+	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Kernel release", OPENCHANGE_SYS_KERNEL_RELEASE);
+	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Processor", OPENCHANGE_SYS_PROCESSOR);
+	mapitest_deindent();
+}
+
+
+/**
+   \details Print a report of the Exchange server and account information
+
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_headers_server_info(struct mapitest *mt)
+{
+	if (mt->online == false) {
+		return;
+	}
+
+	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(mt, MT_HDR_FMT_SUBSECTION, "Username",
+		       (mt->confidential == true) ? MT_CONFIDENTIAL : mt->info.szDisplayName);
+	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Organization",
+		       (mt->confidential == true) ? MT_CONFIDENTIAL : mt->org);
+	mapitest_print(mt, MT_HDR_FMT_SUBSECTION, "Organization Unit",
+		       (mt->confidential == true) ? MT_CONFIDENTIAL : mt->org_unit);
+	mapitest_deindent();
+}
+
+
+/**
+   \details Print mapitest report headers
+
+   \param mt pointer to the top-level mapitest structure
+ */
+_PUBLIC_ void mapitest_print_headers(struct mapitest *mt)
+{
+	mapitest_print_headers_start(mt);
+	mapitest_indent();
+	mapitest_print_headers_info(mt);
+	if (mt->no_server == false) {
+		mapitest_print_headers_server_info(mt);
+	}
+	mapitest_deindent();
+	mapitest_print_headers_end(mt);
+	mapitest_print_newline(mt, 2);
+}
+
+
+/**
+   \details Print %mapitest test result
+
+   \param mt pointer to the top-level mapitest structure
+   \param name the test name
+   \param ret boolean value with the test result
+ */
+_PUBLIC_ void mapitest_print_test_result(struct mapitest *mt, char *name, bool ret)
+{
+	mapitest_print(mt, MODULE_TEST_RESULT, name, (ret == true) ? 
+		       MODULE_TEST_SUCCESS : MODULE_TEST_FAILURE);
+	mapitest_print_tab(mt);
+	mapitest_print_line(mt, MODULE_TEST_LINELEN, MODULE_TEST_DELIM2);
+	mapitest_print_newline(mt, MODULE_TEST_NEWLINE);
+}
+
+
+/**
+   \details Print %mapitest return value
+
+   \param mt pointer to the top-level mapitest structure
+   \param name the test name
+
+   \sa mapitest_print_retval_fmt for a version providing an additional format string
+ */
+_PUBLIC_ void mapitest_print_retval(struct mapitest *mt, char *name)
+{
+	const char	*retstr = NULL;
+
+	retstr = mapi_get_errstr(GetLastError());
+
+	if (mt->color == true) {
+		if (retstr) {
+			mapitest_print(mt, "* %-35s: %s %s %s \n", name, (GetLastError() ? MT_RED : MT_GREEN), retstr, MT_WHITE);
+		} else {
+			mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s\n", name, MT_RED, GetLastError(), MT_WHITE);
+		}
+	} else {
+		if (retstr) {
+			mapitest_print(mt, "* %-35s: %s\n", name, retstr);
+		} else {
+			mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x)\n", name, GetLastError());
+		}
+	}
+}
+
+
+/**
+   \details Print %mapitest return value with additional format string
+
+   \param mt pointer to the top-level mapitest structure
+   \param name the test name
+   \param format the format string
+   \param ... the format string parameters
+ */
+_PUBLIC_ void mapitest_print_retval_fmt(struct mapitest *mt, char *name, const char *format, ...)
+{
+	const char	*retstr = NULL;
+	va_list		ap;
+	char		*s = NULL;
+	int		ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	retstr = mapi_get_errstr(GetLastError());
+
+	if (mt->color == true) {
+		if (retstr) {
+			mapitest_print(mt, "* %-35s: %s %s %s %s\n", name, (GetLastError() ? MT_RED: MT_GREEN), retstr, MT_WHITE, s);
+		} else {
+			mapitest_print(mt, "* %-35s: %s Unknown Error (0x%.8x) %s %s\n", name, MT_RED, GetLastError(), MT_WHITE, s);
+		}
+	} else {
+		if (retstr) {
+			mapitest_print(mt, "* %-35s: %s %s\n", name, retstr, s);
+		} else {
+			mapitest_print(mt, "* %-35s: Unknown Error (0x%.8x) %s\n", name, GetLastError(), s);
+		}
+	}
+	free(s);
+}
+
+
+/**
+   \details Print %mapitest return value for a given step
+
+   \param mt pointer tp the top-level mapitest structure
+   \param step the test step
+   \param name the test name
+
+   \sa mapitest_print_retval_step_fmt for a version providing an additional format string
+ */
+_PUBLIC_ void mapitest_print_retval_step(struct mapitest *mt, char *step, char *name)
+{
+	const char	*retstr = NULL;
+
+	retstr = mapi_get_errstr(GetLastError());
+
+	if (mt->color == true) {
+		if (retstr) {
+			mapitest_print(mt, "* Step %-5s %-35s: %s %s %s\n", step, name, (GetLastError() ? MT_RED : MT_GREEN), retstr, MT_WHITE);
+		} else {
+			mapitest_print(mt, "* Step %-5s %-35s: %s Unknown Error (0x%.8x) %s\n", step, name, MT_RED, GetLastError(), MT_WHITE);
+		}
+	} else {
+		if (retstr) {
+			mapitest_print(mt, "* Step %-5s %-35s: %s\n", step, name, retstr);
+		} else {
+			mapitest_print(mt, "* Step %-5s %-35s: Unknown Error (0x%.8x)\n", step, name, GetLastError());
+		}
+	}
+}
+
+
+/**
+   \details Print %mapitest return value for a given step with additional format string
+
+   \param mt pointer to the top-level mapitest structure
+   \param step the test step
+   \param name the test name
+   \param format the format string
+   \param ... the format string parameters
+ */
+_PUBLIC_ void mapitest_print_retval_step_fmt(struct mapitest *mt, char *step, char *name, const char *format, ...)
+{
+	const char	*retstr = NULL;
+	va_list		ap;
+	char		*s = NULL;
+	int		ret;
+
+	va_start(ap, format);
+	ret = vasprintf(&s, format, ap);
+	va_end(ap);
+
+	retstr = mapi_get_errstr(GetLastError());
+
+	if (mt->color == true) {
+		if (retstr) {
+			mapitest_print(mt, "* Step %-5s %-35s: %s %s %s %s\n", step, name, (GetLastError() ? MT_RED : MT_GREEN), retstr, MT_WHITE, s);
+		} else {
+			mapitest_print(mt, "* Step %-5s %-35s: %s Unknown Error (0x%.8x) %s %s\n", step, name, MT_RED, GetLastError(), MT_WHITE, s);
+		}
+	} else {
+		if (retstr) {
+			mapitest_print(mt, "* Step %-5s %-35s: %s %s\n", step, name, retstr, s);
+		} else {
+			mapitest_print(mt, "* Step %-5s %-35s: Unknown Error (0x%.8x) %s\n", step, name, GetLastError(), s);
+		}
+	}
+	free(s);
+}

Added: trunk/openchange/utils/mapitest/mapitest_stat.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_stat.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest_stat.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,126 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+
+/**
+	\file
+	mapitest statistics functions
+
+	mapitest records and prints the results of each test
+	using these functions
+*/
+
+/**
+   \details Initialize the mapitest statistic structure
+   
+   \param mem_ctx memory allocation context
+
+   \return Allocated stat structure on success, otherwise NULL
+ */
+_PUBLIC_ struct mapitest_stat *mapitest_stat_init(TALLOC_CTX *mem_ctx)
+{
+	struct mapitest_stat	*stat = NULL;
+
+	/* Sanity check */
+	if (!mem_ctx) return NULL;
+
+	stat = talloc_zero(mem_ctx, struct mapitest_stat);
+	stat->success = 0;
+	stat->failure = 0;
+	stat->failure_info = NULL;
+	stat->enabled = false;
+
+	return stat;
+}
+
+
+/**
+   \details Add test result to the suite statistic parameter
+
+   \param suite the suite container
+   \param name the test name
+   \param result the test result
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t mapitest_stat_add_result(struct mapitest_suite *suite,
+					   const char *name,
+					   bool result)
+{
+	struct mapitest_unit	*el = NULL;
+
+	/* Sanity check */
+	if (!suite || !suite->stat || !name) return MAPITEST_ERROR;
+
+	if (result == true) {
+		suite->stat->success++;
+	} else {
+		suite->stat->failure++;
+		el = talloc_zero((TALLOC_CTX *) suite->stat, struct mapitest_unit);
+		el->name = talloc_strdup((TALLOC_CTX *)el, (char *)name);
+		DLIST_ADD_END(suite->stat->failure_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
+
+   \return the number of test steps that failed (i.e. 0 for all success)
+ */
+_PUBLIC_ int32_t mapitest_stat_dump(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite;
+	struct mapitest_unit	*el;
+	int32_t 		num_passed_tests = 0;
+	int32_t 		num_failed_tests = 0;
+
+	mapitest_print_title(mt, MT_STAT_TITLE, MODULE_TITLE_DELIM);
+
+	for (suite = mt->mapi_suite; suite; suite = suite->next) {
+		if (suite->stat->enabled == true) {
+			num_passed_tests += suite->stat->success;
+			num_failed_tests += suite->stat->failure;
+			if (suite->stat->failure) {
+				for (el = suite->stat->failure_info; el; el = el->next) {
+					mapitest_print(mt, MT_STAT_FAILURE, suite->name, el->name);
+				}
+			}
+		}
+	}
+
+	mapitest_print_test_title_end(mt);
+
+	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_test_title_end(mt);
+
+	return num_failed_tests;
+}

Added: trunk/openchange/utils/mapitest/mapitest_suite.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_suite.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/mapitest_suite.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,365 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+
+/**
+	\file
+
+	mapitest test suite functions
+*/
+
+/**
+   \details Initialize a mapitest suite
+   
+   \param mt the top-level mapitest structure
+   \param name the suite name
+   \param description the suite description
+   \param online whether this suite requires online (server) access
+
+   \return An allocated mapitest_suite pointer, otherwise NULL.
+ */
+_PUBLIC_ struct mapitest_suite *mapitest_suite_init(struct mapitest *mt, 
+						    const char *name,
+						    const char *description,
+						    bool online)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	/* Sanity check */
+	if (!mt || !mt->mem_ctx) return NULL;
+	if (!name) return NULL;
+
+	suite = talloc_zero(mt->mem_ctx, struct mapitest_suite);
+	suite->tests = NULL;
+	suite->stat = mapitest_stat_init((TALLOC_CTX *)suite);
+
+	suite->name = talloc_strdup((TALLOC_CTX *) suite, name);
+	if (!description) {
+		suite->description = NULL;
+	} else {
+		suite->description = talloc_strdup((TALLOC_CTX *)suite, description);
+	}
+
+	suite->online = online;
+
+	return suite;
+}
+
+
+/**
+   \details Register a mapitest suite
+
+   \param mt the top-level mapitest structure
+   \param suite the mapitest suite we want to add
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+
+   \sa mapitest_suite_init
+ */
+_PUBLIC_ uint32_t mapitest_suite_register(struct mapitest *mt, 
+					  struct mapitest_suite *suite)
+{
+	struct mapitest_suite *el = NULL;
+
+	/* Sanity check */
+	if (!mt || !mt->mem_ctx) return MAPITEST_ERROR;
+	if (!suite) return MAPITEST_ERROR;
+
+	/* Ensure the name is not yet registered */
+	for (el = mt->mapi_suite; el; el = el->next) {
+		if (el->name && !strcmp(el->name, suite->name)) {
+			fprintf(stderr, "Suite already registered\n");
+			return MAPITEST_ERROR;
+		}
+	}
+
+	DLIST_ADD_END(mt->mapi_suite, suite, struct mapitest_suite *);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details add a simple test to the mapitest suite
+
+   \param suite pointer on the parent suite
+   \param name the test name
+   \param run the test function
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+
+   \sa mapitest_suite_init, mapitest_suite_register
+ */
+_PUBLIC_ uint32_t mapitest_suite_add_simple_test(struct mapitest_suite *suite,
+						 const char *name,
+						 bool (*run) (struct mapitest *test))
+{
+	struct mapitest_test	*el = NULL;
+
+	/* Sanity check */
+	if (!suite || !name || !run) return MAPITEST_ERROR;
+
+	/* Ensure the test is not yet registered */
+	for (el = suite->tests; el; el = el->next) {
+		if (el->name && !strcmp(el->name, name)) {
+			return MAPITEST_ERROR;
+		}
+	}
+
+	el = talloc_zero((TALLOC_CTX *) suite, struct mapitest_test);
+	el->name = talloc_asprintf((TALLOC_CTX *)suite, "%s-%s", suite->name, name);
+	el->description = NULL;
+	el->fn = run;
+
+	DLIST_ADD_END(suite->tests, el, struct mapitest_test *);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details add a test to the mapitest suite with description
+
+   \param suite pointer on the parent suite
+   \param name the test name
+   \param description the test description
+   \param run the test function
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+   
+   \sa mapitest_suite_init, mapitest_suite_register
+*/
+_PUBLIC_ uint32_t mapitest_suite_add_test(struct mapitest_suite *suite,
+					  const char *name, const char *description,
+					  bool (*run) (struct mapitest *test))
+{
+	struct mapitest_test	*el = NULL;
+
+	/* Sanity check */
+	if (!suite || !name || !run || !description) return MAPITEST_ERROR;
+
+	/* Ensure the test is not yet registered */
+	for (el = suite->tests; el; el = el->next) {
+		if (el->name && !strcmp(el->name, name)) {
+			return MAPITEST_ERROR;
+		}
+	}
+
+	el = talloc_zero((TALLOC_CTX *) suite, struct mapitest_test);
+	el->name = talloc_asprintf((TALLOC_CTX *)suite, "%s-%s", suite->name, name);
+	el->description = talloc_strdup((TALLOC_CTX *)suite, description);
+	el->fn = run;
+
+	DLIST_ADD_END(suite->tests, el, struct mapitest_test *);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Find a suite given its name
+
+   \param mt top-level mapitest structure
+   \param name the suite name to be searched
+
+   \return Pointer on a suite on success, otherwise NULL
+ */
+_PUBLIC_ struct mapitest_suite *mapitest_suite_find(struct mapitest *mt, 
+						    const char *name)
+{
+	struct mapitest_suite	*suite = NULL;
+	
+	if (!name) return NULL;
+
+	for (suite = mt->mapi_suite; suite; suite = suite->next) {
+		if (!strcmp(name, suite->name)) {
+			return suite;
+		}
+	}
+
+	return NULL;
+}
+
+
+/**
+   \details run a test from a suite given its name
+   
+   \param mt pointer on the top-level mapitest structure
+   \param suite pointer on the mapitest suite
+   \param name the name of the test to be run
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_suite_run_test(struct mapitest *mt,
+				      struct mapitest_suite *suite, 
+				      const char *name)
+{
+	struct mapitest_test	*el;
+	bool			ret;
+	bool			(*fn)(struct mapitest *);
+
+	if (!suite || !name) return false;
+
+	for (el = suite->tests; el; el = el->next) {
+		if (!strcmp(el->name, name)) {
+			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);
+			return ret;
+		}
+	}
+
+	fprintf(stderr, "[ERROR] %s test doesn't exist\n", name);
+	return false;
+}
+
+
+/**
+   \details run the special SUITE-ALL test
+
+   \param mt the top-level mapitest structure
+   \param name the mapitest test name
+
+   \return true on success, otherwise -1
+ */
+static bool mapitest_run_test_all(struct mapitest *mt, const char *name)
+{
+	char			*test_name;
+	char			*sname;
+	char			*tmp;
+	struct mapitest_test	*el;
+	struct mapitest_suite	*suite;
+	bool			ret = false;
+
+	test_name = talloc_strdup(mt->mem_ctx, name);
+	if ((tmp = strtok(test_name, "-")) == NULL) {
+		talloc_free(test_name);
+	}
+
+	sname = talloc_strdup(mt->mem_ctx, tmp);
+	if ((tmp = strtok(NULL, "-")) == NULL) {
+		talloc_free(test_name);
+		talloc_free(sname);
+		return false;
+	}
+
+	if (!strcmp(tmp,"ALL")) {
+		suite = mapitest_suite_find(mt, sname);
+
+		if (suite) {
+			for (el = suite->tests; el; el = el->next) {
+				mapitest_suite_run_test(mt, suite, el->name);
+				ret = true;
+			}
+		}
+	}
+	talloc_free(sname);
+	talloc_free(test_name);
+	return ret;
+}
+
+
+/**
+   \details run a specific test from a particular suite
+
+   \param mt the top-level mapitest structure
+   \param name the mapitest test name
+
+   \return true on success, otherwise -1
+ */
+_PUBLIC_ bool mapitest_run_test(struct mapitest *mt, const char *name)
+{
+	struct mapitest_suite	*suite;
+	struct mapitest_test	*el;
+	bool			ret;
+
+	/* sanity check */
+	if (!mt || !name) return false;
+
+	/* try to find the test */
+	for (suite = mt->mapi_suite; suite; suite = suite->next) {
+		for (el = suite->tests; el; el = el->next) {
+			if (!strcmp(name, el->name)) {
+				if ((mt->online == suite->online) || (suite->online == false)) {
+					errno = 0;
+					ret = mapitest_suite_run_test(mt, suite, name);
+					return ret;
+				} else {
+					fprintf(stderr, "Server is offline, skipping test: \"%s\"\n", name);
+					return true;
+				}
+			}
+		}
+	}
+	
+	/* if no name matches, look it it matches ALL */
+	ret = mapitest_run_test_all(mt, name);
+
+	if (ret != true) {
+		fprintf(stderr, "[ERROR] Unknown test: \"%s\"\n", name);
+	}
+
+	return ret;
+}
+
+
+/**
+   \details all tests from all suites
+
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise -1
+ */
+_PUBLIC_ bool mapitest_run_all(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite;
+	struct mapitest_test	*el;
+	bool			(*fn)(struct mapitest *);
+	bool			ret = false;
+
+	for (suite = mt->mapi_suite; suite; suite = suite->next) {
+		if ((mt->online == suite->online) || (suite->online == false)) {
+			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);
+			}
+
+			mapitest_print_module_title_end(mt);
+		}
+	}
+	return ret;
+}

Added: trunk/openchange/utils/mapitest/module.c
===================================================================
--- trunk/openchange/utils/mapitest/module.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/module.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,363 @@
+/*
+   Stand-alone MAPI testsuite
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+_PUBLIC_ uint32_t mapitest_register_modules(struct mapitest *mt)
+{
+	uint32_t	ret;
+
+	ret = module_oxcstor_init(mt);
+	ret += module_oxcfold_init(mt);
+	ret += module_oxctable_init(mt);
+	ret += module_oxomsg_init(mt);
+	ret += module_oxcmsg_init(mt);
+	ret += module_oxcprpt_init(mt);
+	ret += module_oxorule_init(mt);
+	ret += module_oxcfxics_init(mt);
+	ret += module_nspi_init(mt);
+	ret += module_noserver_init(mt);
+	ret += module_errorchecks_init(mt);
+	ret += module_lcid_init(mt);
+
+	return ret;
+}
+
+
+/**
+   \details Register the Store Object Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcstor_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCSTOR", "Store Object Protocol", true);
+
+	mapitest_suite_add_test(suite, "LOGON", "Logon operation", mapitest_oxcstor_Logon);
+	mapitest_suite_add_test(suite, "GET-RECEIVE-FOLDER", "Retrieve the receive folder ID", mapitest_oxcstor_GetReceiveFolder);
+	mapitest_suite_add_test(suite, "SET-RECEIVE-FOLDER", "Set the receive folder", mapitest_oxcstor_SetReceiveFolder);
+	mapitest_suite_add_test(suite, "GET-RECEIVE-FOLDER-TABLE", "Retrieve the Receive Folder Table", mapitest_oxcstor_GetReceiveFolderTable);
+	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_register(mt, suite);
+	
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the Folder Object Protocol test suite
+
+   \param mt the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcfold_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCFOLD", "Folder Object Protocol", true);
+
+	mapitest_suite_add_test(suite, "OPEN",   "Open a folder", mapitest_oxcfold_OpenFolder);
+	mapitest_suite_add_test(suite, "CREATE", "Create a folder", mapitest_oxcfold_CreateFolder);
+	mapitest_suite_add_test(suite, "GET-HIERARCHY-TABLE", "Retrieve the hierarchy table", mapitest_oxcfold_GetHierarchyTable);
+	mapitest_suite_add_test(suite, "GET-CONTENTS-TABLE", "Retrieve the contents table", mapitest_oxcfold_GetContentsTable);
+	mapitest_suite_add_test(suite, "SET-SEARCHCRITERIA", "Set a search criteria on a container", mapitest_oxcfold_SetSearchCriteria);
+	mapitest_suite_add_test(suite, "GET-SEARCHCRITERIA", "Retrieve a search criteria associated to a container", mapitest_oxcfold_GetSearchCriteria);
+	mapitest_suite_add_test(suite, "MOVECOPY-MESSAGES", "Move or copy messages from a source to destination folder", mapitest_oxcfold_MoveCopyMessages);
+	mapitest_suite_add_test(suite, "MOVEFOLDER", "Move folder from source to destination", mapitest_oxcfold_MoveFolder);
+	mapitest_suite_add_test(suite, "COPYFOLDER", "Copy folder from source to destination", mapitest_oxcfold_CopyFolder);
+
+	mapitest_suite_register(mt, suite);
+	
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the E-mail Object Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxomsg_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXOMSG", "E-mail Object Protocol", true);
+	
+	mapitest_suite_add_test(suite, "ADDRESS-TYPES", "Address Types", mapitest_oxomsg_AddressTypes);
+	mapitest_suite_add_test(suite, "SUBMIT-MESSAGE", "Submit message", mapitest_oxomsg_SubmitMessage);
+	mapitest_suite_add_test(suite, "ABORT-SUBMIT", "Abort submitted message", mapitest_oxomsg_AbortSubmit);
+	mapitest_suite_add_test(suite, "SET-SPOOLER", "Client intends to act as a mail spooler", mapitest_oxomsg_SetSpooler);
+	mapitest_suite_add_test(suite, "SPOOLER-LOCK-MESSAGE", "Lock the specified message for spooling", mapitest_oxomsg_SpoolerLockMessage);
+	mapitest_suite_add_test(suite, "TRANSPORT-SEND", "Sends the specified message object out for message delivery", mapitest_oxomsg_TransportSend);
+	mapitest_suite_add_test(suite, "GET-TRANSPORT-FOLDER", "Retrieve the temporary transport folder ID", mapitest_oxomsg_GetTransportFolder);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the Message and Attachment Object Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcmsg_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite =  mapitest_suite_init(mt, "OXCMSG", "Message and Attachment Object Protocol", true);
+
+	mapitest_suite_add_test(suite, "CREATE-MESSAGE", "Create message", mapitest_oxcmsg_CreateMessage);
+	mapitest_suite_add_test(suite, "SET-MESSAGE-READ-FLAGS", "Set message read flag", mapitest_oxcmsg_SetMessageReadFlag);
+	mapitest_suite_add_test(suite, "SET-READ-FLAGS", "Set read flag on multiple messages", mapitest_oxcmsg_SetReadFlags);
+	mapitest_suite_add_test(suite, "MODIFY-RECIPIENTS", "Add new recipients", mapitest_oxcmsg_ModifyRecipients);
+	mapitest_suite_add_test(suite, "READ-RECIPIENTS", "Read recipients from a message", mapitest_oxcmsg_ReadRecipients);
+	mapitest_suite_add_test(suite, "REMOVE-ALL-RECIPIENTS", "Remove all recipients from a message", mapitest_oxcmsg_RemoveAllRecipients);
+	mapitest_suite_add_test(suite, "SAVE-CHANGES-MESSAGE", "Save changes on message", mapitest_oxcmsg_SaveChangesMessage);
+	mapitest_suite_add_test(suite, "GET-MESSAGE-STATUS", "Get message status", mapitest_oxcmsg_GetMessageStatus);
+	mapitest_suite_add_test(suite, "SET-MESSAGE-STATUS", "Set message status", mapitest_oxcmsg_SetMessageStatus);
+	mapitest_suite_add_test(suite, "OPEN-EMBEDDED-MESSAGE", "Open a message embedded in another message", mapitest_oxcmsg_OpenEmbeddedMessage);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the Table Object Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxctable_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCTABLE", "Table Object Protocol", true);
+	
+	mapitest_suite_add_test(suite, "SETCOLUMNS", "Set Table Columns", mapitest_oxctable_SetColumns);
+	mapitest_suite_add_test(suite, "QUERYCOLUMNS", "Query Table Columns", mapitest_oxctable_QueryColumns);
+	mapitest_suite_add_test(suite, "QUERYROWS", "Query Table Rows", mapitest_oxctable_QueryRows);
+	mapitest_suite_add_test(suite, "GETSTATUS", "Get Table Status", mapitest_oxctable_GetStatus);
+	mapitest_suite_add_test(suite, "SEEKROW", "Seek a row", mapitest_oxctable_SeekRow);
+	mapitest_suite_add_test(suite, "RESTRICT", "Apply filters to a table", mapitest_oxctable_Restrict);
+	mapitest_suite_add_test(suite, "SEEKROW-APPROX", "Seek an approximate row", mapitest_oxctable_SeekRowApprox);
+	mapitest_suite_add_test(suite, "CREATE-BOOKMARK", "Create a table bookmark", mapitest_oxctable_CreateBookmark);
+	mapitest_suite_add_test(suite, "SEEKROW-BOOKMARK", "Seek a row given a bookmark", mapitest_oxctable_SeekRowBookmark);
+	mapitest_suite_add_test(suite, "CATEGORY", "Expand/collapse category rows", mapitest_oxctable_Category);
+
+	mapitest_suite_register(mt, suite);
+	
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the Property and Stream Object Protocol test
+   suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcprpt_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCPRPT", "Property and Stream Object Protocol", true);
+
+	mapitest_suite_add_test(suite, "GET-PROPS", "Retrieve a specific set of properties", mapitest_oxcprpt_GetProps);
+	mapitest_suite_add_test(suite, "GET-PROPSALL", "Retrieve the whole property array", mapitest_oxcprpt_GetPropsAll);
+	mapitest_suite_add_test(suite, "GET-PROPLIST", "Retrieve the property list", mapitest_oxcprpt_GetPropList);
+	mapitest_suite_add_test(suite, "SET-PROPS", "Set a specific set of properties", mapitest_oxcprpt_SetProps);
+	mapitest_suite_add_test(suite, "DELETE-PROPS", "Delete a specific set of properties", mapitest_oxcprpt_DeleteProps);
+	mapitest_suite_add_test(suite, "DELETE-PROPS-NOREPL", "Delete a specific set of properties (no replicate)", mapitest_oxcprpt_DeletePropertiesNoReplicate);
+	mapitest_suite_add_test(suite, "COPY-PROPS", "Copy a specified set of properties", mapitest_oxcprpt_CopyProps);
+	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, "COPYTO-STREAM", "Copy stream from source to desination stream", mapitest_oxcprpt_CopyToStream);
+	mapitest_suite_add_test(suite, "NAME-ID", "Convert between Names and IDs", mapitest_oxcprpt_NameId);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the E-Mail Rules Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxorule_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXORULE", "E-Mail Rules Protocol", true);
+
+	mapitest_suite_add_test(suite, "GET-RULES-TABLE", "Retrieve the rules table associated to a folder", mapitest_oxorule_GetRulesTable);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the Bulk Data Transfer Protocol test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_oxcfxics_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "OXCFXICS", "Bulk Data Transfer Protocol", true);
+	
+	mapitest_suite_add_test(suite, "GET-LOCAL-REPLICA-IDS", "Reserve a range of IDs for local replica", mapitest_oxcfxics_GetLocalReplicaIds);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Register the NSPI test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_nspi_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "NSPI", "Name Service Provider Interface", true);
+	
+	mapitest_suite_add_test(suite, "UPDATESTAT", "Update the STAT structure", mapitest_nspi_UpdateStat);
+	mapitest_suite_add_test(suite, "QUERYROWS", "Returns a number of rows from a specified table", mapitest_nspi_QueryRows);
+	mapitest_suite_add_test(suite, "SEEKENTRIES", "Searches for and sets the logical position in a specific table", mapitest_nspi_SeekEntries);
+	mapitest_suite_add_test(suite, "GETMATCHES", "Returns an explicit table", mapitest_nspi_GetMatches);
+	mapitest_suite_add_test(suite, "RESORTRESTRICTION", "Apply a sort order to the objects in a restricted address book container", mapitest_nspi_ResortRestriction);
+	mapitest_suite_add_test(suite, "DNTOMID", "Maps a set of DN to a set of MId", mapitest_nspi_DNToMId);
+	mapitest_suite_add_test(suite, "GETPROPLIST", "Retrieve the list of properties associated to an object", mapitest_nspi_GetPropList);
+	mapitest_suite_add_test(suite, "GETPROPS", "Returns a row containing a set of the properties and values", mapitest_nspi_GetProps);
+	mapitest_suite_add_test(suite, "COMPAREMIDS", "Compare the position in an AB container of two objects", mapitest_nspi_CompareMIds);
+	mapitest_suite_add_test(suite, "MODPROPS", "Modify an address book object", mapitest_nspi_ModProps);
+	mapitest_suite_add_test(suite, "GETSPECIALTABLE", "Returns the rows of a special table to the client", mapitest_nspi_GetSpecialTable);
+	mapitest_suite_add_test(suite, "GETTEMPLATEINFO", "Returns information about template objects", mapitest_nspi_GetTemplateInfo);
+	mapitest_suite_add_test(suite, "MODLINKATT", "Modifies the values of a specific property of a specific row", mapitest_nspi_ModLinkAtt);
+	mapitest_suite_add_test(suite, "QUERYCOLUMNS", "Returns a list of all the properties the NSPI server is aware of", mapitest_nspi_QueryColumns);
+	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_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+
+/**
+   \details Return the no server test suite
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_noserver_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "NOSERVER", "No server operations", false);
+
+	mapitest_suite_add_test(suite, "LZFU", "Test Compressed RTF operations", mapitest_noserver_lzfu);
+	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_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+/**
+   \details Initialise the error / sanity-check test suite
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_errorchecks_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "ERRORCHECKS", "Error / sanity-check operations", false);
+
+	mapitest_suite_add_test(suite, "SIMPLEMAPI", "Test failure paths for simplemapi.c", mapitest_errorchecks_simplemapi_c);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}
+
+/**
+   \details Initialise the language code / ID test suite
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return MAPITEST_SUCCESS on success, otherwise MAPITEST_ERROR
+ */
+_PUBLIC_ uint32_t module_lcid_init(struct mapitest *mt)
+{
+	struct mapitest_suite	*suite = NULL;
+
+	suite = mapitest_suite_init(mt, "LCID", "Language code / ID operations", false);
+
+	mapitest_suite_add_test(suite, "CODE2TAG", "Tests for lcid_langcode2langtag", mapitest_lcid_langcode2langtag);
+
+	mapitest_suite_register(mt, suite);
+
+	return MAPITEST_SUCCESS;
+}

Added: trunk/openchange/utils/mapitest/modules/mapitest.doxy
===================================================================
--- trunk/openchange/utils/mapitest/modules/mapitest.doxy	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/mapitest.doxy	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,14 @@
+/**
+\mainpage %mapitest documentation
+
+%mapitest acts as stand-alone torture test of a range of MAPI function
+calls. It is intended to validate the implementation of various
+functions, and to ensure that existing functionality does not suffer
+regression between releases.
+
+As a general principle, %mapitest calls should leave the system in the
+same state at the end as at the start - it is meant to clean up after
+itself.
+
+*/
+

Added: trunk/openchange/utils/mapitest/modules/module_errorchecks.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_errorchecks.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_errorchecks.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,312 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - Error / sanity-check path tests
+
+   Copyright (C) Brad Hards 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/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_errorchecks.c
+
+   \brief Error / sanity-check path tests
+
+   \note These tests do not show how to use libmapi properly, and should
+  not be used as a programming reference.
+*/
+
+/**
+   \details Create a correctly initialized global context
+*/
+static void make_global_ctx_valid(char* mem_ctx)
+{
+	global_mapi_ctx = talloc_zero(mem_ctx, struct mapi_ctx);
+}
+
+/**
+   \details De-initialize the global context
+*/
+static void make_global_ctx_invalid(void)
+{
+	talloc_free(global_mapi_ctx);
+	global_mapi_ctx = 0;
+}
+
+/**
+   \details Verify simplemapi.c functions
+
+   This function:
+   -# Tests the sanity checks in GetDefaultPublicFolder
+   -# Tests the sanity checks in GetDefaultFolder
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/ 
+_PUBLIC_ bool mapitest_errorchecks_simplemapi_c(struct mapitest *mt)
+{
+	enum MAPISTATUS status;
+	mapi_object_t 	*obj_store = 0;
+	mapi_object_t	*obj_folder = 0;
+	mapi_object_t	*obj_message = 0;
+	mapi_object_t	tmp;
+	uint64_t	*folder = 0;
+	uint32_t	id = 0x99;
+	uint32_t	arg; 		// an all purpose argument...
+	TALLOC_CTX	*mem_ctx;
+
+	make_global_ctx_invalid();
+
+	status = GetDefaultPublicFolder(obj_store, folder, id);
+	if ( (status != MAPI_E_NOT_INITIALIZED) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 1 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 1 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	mem_ctx = talloc_autofree_context();
+	make_global_ctx_valid(mem_ctx);
+
+	status = GetDefaultPublicFolder(obj_store, folder, id);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 2 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 2 - MAPI_E_INVALID_PARAMETER");
+	}
+	obj_store = &tmp;
+	status = GetDefaultPublicFolder(obj_store, folder, id);
+	if ( ( status != MAPI_E_NOT_FOUND ) || (GetLastError() != MAPI_E_NOT_FOUND) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 3 - MAPI_E_NOT_FOUND", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 3 - MAPI_E_NOT_FOUND");
+	}
+
+	make_global_ctx_invalid();
+
+	obj_store = 0;
+
+	status = GetDefaultFolder(obj_store, folder, id);
+	if ( (status != MAPI_E_NOT_INITIALIZED) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 4 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 4 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = GetDefaultFolder(obj_store, folder, id);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 5 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 5 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_store = &tmp;
+	obj_store->private_data = 0;
+	status = GetDefaultFolder(obj_store, folder, id);
+	if ( ( status != MAPI_E_NOT_INITIALIZED ) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 6 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 6 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_invalid();
+
+	obj_store = 0;
+
+	status = GetFolderItemsCount(obj_folder, 0, 0);
+	if ( (status != MAPI_E_NOT_INITIALIZED) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 7 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 7 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = GetFolderItemsCount(obj_folder, 0, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 8 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 8 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_folder = &tmp;
+	status = GetFolderItemsCount(obj_folder, 0, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 9 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 9 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	status = GetFolderItemsCount(obj_folder, &arg, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 10 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 10 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	make_global_ctx_invalid();
+	obj_folder = 0;
+
+	/**************************************************************************************
+	   Testing AddUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
+	*/
+	status = AddUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_NOT_INITIALIZED ) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 11 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 11 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = AddUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 12 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 12 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_folder = &tmp;
+	status = AddUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 13 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 13 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	make_global_ctx_invalid();
+	obj_folder = 0;
+
+	/**************************************************************************************
+	  Testing ModifyUserPermission(mapi_object_t *obj_folder, const char *username, enum ACLRIGHTS role)
+	*/
+	status = ModifyUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_NOT_INITIALIZED ) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 14 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 14 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = ModifyUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 15 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 15 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_folder = &tmp;
+	status = ModifyUserPermission(obj_folder, 0, RightsNone);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 16 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 16 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	make_global_ctx_invalid();
+	obj_folder = 0;
+
+	/**************************************************************************************
+	  Testing RemoveUserPermission(mapi_object_t *obj_folder, const char *username)
+	*/
+	status = RemoveUserPermission(obj_folder, 0);
+	if ( ( status != MAPI_E_NOT_INITIALIZED ) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 17 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 17 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = RemoveUserPermission(obj_folder, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 18 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 18 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_folder = &tmp;
+	status = RemoveUserPermission(obj_folder, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 19 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 19 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	make_global_ctx_invalid();
+	obj_folder = 0;
+
+	/**************************************************************************************
+	  Testing GetBestBody(mapi_object_t *obj_message, uint8_t *format)
+	*/
+	status = GetBestBody(obj_message, 0);
+	if ( ( status != MAPI_E_NOT_INITIALIZED ) || (GetLastError() != MAPI_E_NOT_INITIALIZED) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 20 - MAPI_E_NOT_INITIALIZED", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 20 - MAPI_E_NOT_INITIALIZED");
+	}
+
+	make_global_ctx_valid(mem_ctx);
+
+	status = GetBestBody(obj_message, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 21 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 21 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	obj_message = &tmp;
+	status = GetBestBody(obj_message, 0);
+	if ( ( status != MAPI_E_INVALID_PARAMETER ) || (GetLastError() != MAPI_E_INVALID_PARAMETER) ) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - 0x%x\n", "Step 22 - MAPI_E_INVALID_PARAMETER", status);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 22 - MAPI_E_INVALID_PARAMETER");
+	}
+
+	make_global_ctx_invalid();
+	obj_message = 0;
+
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_lcid.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_lcid.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_lcid.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,82 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - MS-LCID 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_lcid.c
+
+   \brief Language Code checks (MS-LCID)
+
+   \note This is low level (internal) checking, and application programmers
+   do not normally need to deal with the functions checked in this test suite.
+*/
+
+/**
+   \details Verify libmapi/util/lcid.c functions
+
+   This function:
+   -# exercises lcid_langcode2langtag()
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/ 
+_PUBLIC_ bool mapitest_lcid_langcode2langtag(struct mapitest *mt)
+{
+	const char	*tag;
+
+	tag = lcid_langcode2langtag( 0x0409 );
+	if (strcmp(tag, "en-US") != 0) {
+		mapitest_print(mt, "* %-35s: [FAILURE] - %s\n", "Step 1 - mismatch", tag);
+		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);
+		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);
+		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);
+		return false;
+	} else {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Step 4");
+	}
+	return true;
+}
+

Added: trunk/openchange/utils/mapitest/modules/module_noserver.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_noserver.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_noserver.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1055 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - Non connection oriented tests
+
+   Copyright (C) Brad Hards 2008-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_noserver.c
+
+   \brief Non connection oriented tests
+*/
+
+/* From MS-OXRTFCP, Section 4.1.1 */
+#define RTF_COMPRESSED1_HEX "2d0000002b0000004c5a4675f1c5c7a703000a007263706731323542320af32068656c090020627705b06c647d0a800fa0"
+#define RTF_UNCOMPRESSED1 "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n"
+
+/* From MS-OXRTFCP, Section 4.1.2 */
+#define RTF_COMPRESSED2_HEX "1a0000001c0000004c5a4675e2d44b51410004205758595a0d6e7d010eb0"
+#define RTF_UNCOMPRESSED2 "{\\rtf1 WXYZWXYZWXYZWXYZWXYZ}"
+
+
+/**
+     \details Test the Compressed RTF decompression routine.
+
+   This function:
+   -# Loads some test data and checks it
+   -# Decompresses the test data
+   -# Checks that the decompressed data matches the expected result
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/ 
+_PUBLIC_ bool mapitest_noserver_lzfu(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	DATA_BLOB		uncompressed1;
+	DATA_BLOB		uncompressed2;
+	uint8_t			compressed_hex[1024];
+	uint8_t			*compressed;
+	uint32_t		compressed_length;
+
+	compressed = talloc_array(mt->mem_ctx, uint8_t, 1024);
+
+	memcpy(compressed_hex, RTF_COMPRESSED1_HEX, 98);
+	compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 98);
+	if (compressed_length != 49) {
+		mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU");
+		return false;
+	}
+
+	retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed1);
+	if (retval != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "uncompress_rtf - step 1");
+		return false;
+	}	   
+
+	if (!strncmp((char*)uncompressed1.data, RTF_UNCOMPRESSED1, uncompressed1.length)) {
+		mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 1");
+	} else {
+		mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 1", (char*)uncompressed1.data);
+		return false;
+	}
+
+	memcpy(compressed_hex, RTF_COMPRESSED2_HEX, 60);
+	compressed_length = strhex_to_str((char*)compressed, 1024, (char*)compressed_hex, 60);
+	if (compressed_length != 30) {
+		mapitest_print(mt, "* %-40s: uncompress RTF - Bad length\n", "LZFU");
+		return false;
+	}
+
+	retval = uncompress_rtf(mt->mem_ctx, compressed, compressed_length, &uncompressed2);
+	if (retval != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "uncompress_rtf - step 2");
+		return false;
+	}	   
+
+	if (!strncmp((char*)uncompressed2.data, RTF_UNCOMPRESSED2, uncompressed2.length)) {
+		mapitest_print(mt, "* %-40s: PASSED\n", "uncompress_rtf - step 2");
+	} else {
+		mapitest_print(mt, "* %-40s: FAILED - %s\n", "uncompress_rtf - step 2", (char*)uncompressed2.data);
+		return false;
+	}
+	
+	/* TODO: add an uncompressed test here */
+
+	return true;
+}
+
+#define SROWSET_UNTAGGED "005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203800005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203900005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203700005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203600005b4d545d2044756d6d793400426f6479206f66206d657373616765203400005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203500005b4d545d2044756d6d793300426f6479206f66206d657373616765203300005b4d545d2044756d6d793100426f6479206f66206d657373616765203100005b4d545d2044756d6d793200426f6479206f66206d657373616765203200005b4d545d2044756d6d793000426f6479206f66206d657373616765203000"
+#define SROWSET_UNTAGGED_LEN 330
+
+static bool mapitest_noserver_srowset_untagged(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct loadparm_context	*lp_ctx = NULL;
+	DATA_BLOB		rawData;
+	uint8_t			rawDataHex[1024];
+	struct SRowSet		rowSet;
+	struct SRowSet		referenceRowSet;
+	struct SPropTagArray	*proptags;
+	uint32_t		rowNum;
+	int		i;
+
+	retval = GetLoadparmContext(&lp_ctx);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	rawData.data = talloc_array(mt->mem_ctx, uint8_t, 1024);
+	memcpy(rawDataHex, SROWSET_UNTAGGED, 2*SROWSET_UNTAGGED_LEN);
+	rawData.length = strhex_to_str((char*)rawData.data, 1024, (char*)rawDataHex, 2*SROWSET_UNTAGGED_LEN);
+	if (rawData.length != SROWSET_UNTAGGED_LEN) {
+		mapitest_print(mt, "* %-40s: untagged - Bad length\n", "SRowSet");
+		return false;
+	}
+
+	proptags = set_SPropTagArray(mt->mem_ctx, 2, PR_SENDER_NAME,  PR_BODY);
+	rowSet.cRows = 10;
+	rowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, 10);
+	emsmdb_get_SRowSet(mt->mem_ctx, lp_ctx, &rowSet, proptags, &rawData);
+
+	/* Check the resulting SRowSet */
+	if (rowSet.cRows != 10) {
+		mapitest_print(mt, "* %-40s: unexpected row count: %i\n", "SRowSet", rowSet.cRows);
+		return false;
+	}
+
+	/* Build reference RowSet */
+	referenceRowSet.cRows = rowSet.cRows;
+	referenceRowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, rowSet.cRows);
+	for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) {
+		referenceRowSet.aRow[rowNum].ulAdrEntryPad = 0;
+		referenceRowSet.aRow[rowNum].cValues = 2;
+		referenceRowSet.aRow[rowNum].lpProps = talloc_array(mt->mem_ctx, struct SPropValue, 2);
+		referenceRowSet.aRow[rowNum].lpProps[0].ulPropTag = PR_SENDER_NAME;
+		referenceRowSet.aRow[rowNum].lpProps[0].dwAlignPad = 0;
+		referenceRowSet.aRow[rowNum].lpProps[1].ulPropTag = PR_BODY;
+		referenceRowSet.aRow[rowNum].lpProps[1].dwAlignPad = 0;
+	}
+	referenceRowSet.aRow[0].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[0].lpProps[1].value.lpszA = "Body of message 8";
+	referenceRowSet.aRow[1].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[1].lpProps[1].value.lpszA = "Body of message 9";
+	referenceRowSet.aRow[2].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[2].lpProps[1].value.lpszA = "Body of message 7";
+	referenceRowSet.aRow[3].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[3].lpProps[1].value.lpszA = "Body of message 6";
+	referenceRowSet.aRow[4].lpProps[0].value.lpszA = "[MT] Dummy4";
+	referenceRowSet.aRow[4].lpProps[1].value.lpszA = "Body of message 4";
+	referenceRowSet.aRow[5].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[5].lpProps[1].value.lpszA = "Body of message 5";
+	referenceRowSet.aRow[6].lpProps[0].value.lpszA = "[MT] Dummy3";
+	referenceRowSet.aRow[6].lpProps[1].value.lpszA = "Body of message 3";
+	referenceRowSet.aRow[7].lpProps[0].value.lpszA = "[MT] Dummy1";
+	referenceRowSet.aRow[7].lpProps[1].value.lpszA = "Body of message 1";
+	referenceRowSet.aRow[8].lpProps[0].value.lpszA = "[MT] Dummy2";
+	referenceRowSet.aRow[8].lpProps[1].value.lpszA = "Body of message 2";
+	referenceRowSet.aRow[9].lpProps[0].value.lpszA = "[MT] Dummy0";
+	referenceRowSet.aRow[9].lpProps[1].value.lpszA = "Body of message 0";
+
+
+	/* compare result with reference rowset */
+	for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) {
+		/* check each row has expected number of properties */
+		if (rowSet.aRow[rowNum].cValues != referenceRowSet.aRow[rowNum].cValues) {
+			mapitest_print(mt, "* %-40s: unexpected props count, row %i: %i\n", "SRowSet", rowSet.aRow[rowNum].cValues, rowNum);
+			return false;
+		}
+		for (i=0; i < rowSet.aRow[rowNum].cValues; ++i) {
+			/* check property tags are as expected */
+			if (rowSet.aRow[rowNum].lpProps[i].ulPropTag != referenceRowSet.aRow[rowNum].lpProps[i].ulPropTag) {
+				mapitest_print(mt, "* %-40s: unexpected proptag (%i/%i): 0x%08x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].ulPropTag);
+				return false;
+			}
+			/* check property values are as expected */
+			if (strcmp(rowSet.aRow[rowNum].lpProps[i].value.lpszA, referenceRowSet.aRow[rowNum].lpProps[i].value.lpszA) != 0) {
+				mapitest_print(mt, "* %-40s: unexpected property value (%i/%i): %s\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.lpszA);
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+#define SROWSET_TAGGED	"01005b4d545d2044756d6d792046726f6d000a0f010480005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203500005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203600005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203700005b4d545d2044756d6d792046726f6d00426f6479206f66206d657373616765203800005b4d545d2044756d6d792046726f6d00426f6479206f66206d65737361676520390001005b4d545d2044756d6d7930000a0f010480005b4d545d2044756d6d793000426f6479206f66206d65737361676520300001005b4d545d2044756d6d7931000a0f010480005b4d545d2044756d6d793100426f6479206f66206d65737361676520310001005b4d545d2044756d6d7932000a0f010480005b4d545d2044756d6d793200426f6479206f66206d65737361676520320001005b4d545d2044756d6d7933000a0f010480005b4d545d2044756d6d793300426f6479206f66206d65737361676520330001005b4d545d2044756d6d7934000a0f010480005b4d545d2044756d6d793400426f6479206f66206d657373616765203400"
+#define SROWSET_TAGGED_LEN 448
+
+
+static bool mapitest_noserver_srowset_tagged(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct loadparm_context	*lp_ctx = NULL;
+	DATA_BLOB		rawData;
+	uint8_t			rawDataHex[1024];
+	struct SRowSet		rowSet;
+	struct SRowSet		referenceRowSet;
+	struct SPropTagArray	*proptags;
+	uint32_t		rowNum;
+	int		i;
+
+	retval = GetLoadparmContext(&lp_ctx);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	rawData.data = talloc_array(mt->mem_ctx, uint8_t, 1024);
+	memcpy(rawDataHex, SROWSET_TAGGED, 2*SROWSET_TAGGED_LEN);
+	rawData.length = strhex_to_str((char*)rawData.data, 1024, (char*)rawDataHex, 2*SROWSET_TAGGED_LEN);
+	if (rawData.length != SROWSET_TAGGED_LEN) {
+		mapitest_print(mt, "* %-40s: tagged - Bad length\n", "SRowSet");
+		return false;
+	}
+
+	proptags = set_SPropTagArray(mt->mem_ctx, 2, PR_SENDER_NAME,  PR_BODY);
+	rowSet.cRows = 16;
+	rowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, 16);
+	emsmdb_get_SRowSet(mt->mem_ctx, lp_ctx, &rowSet, proptags, &rawData);
+
+	/* Check the resulting SRowSet */
+	if (rowSet.cRows != 16) {
+		mapitest_print(mt, "* %-40s: unexpected row count: %i\n", "SRowSet", rowSet.cRows);
+		return false;
+	}
+
+	/* Build reference RowSet */
+	referenceRowSet.cRows = rowSet.cRows;
+	referenceRowSet.aRow = talloc_array(mt->mem_ctx, struct SRow, rowSet.cRows);
+	for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) {
+		referenceRowSet.aRow[rowNum].ulAdrEntryPad = 0;
+		referenceRowSet.aRow[rowNum].cValues = 2;
+		referenceRowSet.aRow[rowNum].lpProps = talloc_array(mt->mem_ctx, struct SPropValue, 2);
+		referenceRowSet.aRow[rowNum].lpProps[0].ulPropTag = PR_SENDER_NAME;
+		referenceRowSet.aRow[rowNum].lpProps[0].dwAlignPad = 0;
+		referenceRowSet.aRow[rowNum].lpProps[1].ulPropTag = PR_BODY;
+		referenceRowSet.aRow[rowNum].lpProps[1].dwAlignPad = 0;
+	}
+	referenceRowSet.aRow[0].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[0].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[0].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[1].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[1].lpProps[1].value.lpszA = "Body of message 5";
+	referenceRowSet.aRow[2].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[2].lpProps[1].value.lpszA = "Body of message 6";
+	referenceRowSet.aRow[3].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[3].lpProps[1].value.lpszA = "Body of message 7";
+	referenceRowSet.aRow[4].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[4].lpProps[1].value.lpszA = "Body of message 8";
+	referenceRowSet.aRow[5].lpProps[0].value.lpszA = "[MT] Dummy From";
+	referenceRowSet.aRow[5].lpProps[1].value.lpszA = "Body of message 9";
+	referenceRowSet.aRow[6].lpProps[0].value.lpszA = "[MT] Dummy0";
+	referenceRowSet.aRow[6].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[6].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[7].lpProps[0].value.lpszA = "[MT] Dummy0";
+	referenceRowSet.aRow[7].lpProps[1].value.lpszA = "Body of message 0";
+	referenceRowSet.aRow[8].lpProps[0].value.lpszA = "[MT] Dummy1";
+	referenceRowSet.aRow[8].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[8].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[9].lpProps[0].value.lpszA = "[MT] Dummy1";
+	referenceRowSet.aRow[9].lpProps[1].value.lpszA = "Body of message 1";
+	referenceRowSet.aRow[10].lpProps[0].value.lpszA = "[MT] Dummy2";
+	referenceRowSet.aRow[10].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[10].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[11].lpProps[0].value.lpszA = "[MT] Dummy2";
+	referenceRowSet.aRow[11].lpProps[1].value.lpszA = "Body of message 2";
+	referenceRowSet.aRow[12].lpProps[0].value.lpszA = "[MT] Dummy3";
+	referenceRowSet.aRow[12].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[12].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[13].lpProps[0].value.lpszA = "[MT] Dummy3";
+	referenceRowSet.aRow[13].lpProps[1].value.lpszA = "Body of message 3";
+	referenceRowSet.aRow[14].lpProps[0].value.lpszA = "[MT] Dummy4";
+	referenceRowSet.aRow[14].lpProps[1].ulPropTag = PR_BODY_ERROR;
+	referenceRowSet.aRow[14].lpProps[1].value.err = MAPI_E_NOT_FOUND;
+	referenceRowSet.aRow[15].lpProps[0].value.lpszA = "[MT] Dummy4";
+	referenceRowSet.aRow[15].lpProps[1].value.lpszA = "Body of message 4";
+
+	/* compare result with reference rowset */
+	for (rowNum = 0; rowNum < rowSet.cRows; ++rowNum) {
+		/* check each row has expected number of properties */
+		if (rowSet.aRow[rowNum].cValues != referenceRowSet.aRow[rowNum].cValues) {
+			mapitest_print(mt, "* %-40s: unexpected props count, row %i: %i\n", "SRowSet", rowSet.aRow[rowNum].cValues, rowNum);
+			return false;
+		}
+		for (i=0; i < rowSet.aRow[rowNum].cValues; ++i) {
+			/* check property tags are as expected */
+			if (rowSet.aRow[rowNum].lpProps[i].ulPropTag != referenceRowSet.aRow[rowNum].lpProps[i].ulPropTag) {
+				mapitest_print(mt, "* %-40s: unexpected proptag (%i/%i): 0x%08x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].ulPropTag);
+				return false;
+			}
+			/* check property values are as expected */
+			if ((rowSet.aRow[rowNum].lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) {
+				if (rowSet.aRow[rowNum].lpProps[i].value.err != referenceRowSet.aRow[rowNum].lpProps[i].value.err) {
+					mapitest_print(mt, "* %-40s: unexpected property error value (%i/%i): 0x%04x\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.err);
+					return false;
+				}
+			} else {
+				if (strcmp(rowSet.aRow[rowNum].lpProps[i].value.lpszA, referenceRowSet.aRow[rowNum].lpProps[i].value.lpszA) != 0) {
+					mapitest_print(mt, "* %-40s: unexpected property value (%i/%i): %s\n", "SRowSet", rowNum, i, rowSet.aRow[rowNum].lpProps[i].value.lpszA);
+					return false;
+				}
+			}
+		}
+	}
+	return true;
+}
+
+/**
+     \details Test the SRowSet parsing / assembly code
+
+   This function:
+   -# Loads some test data and checks it
+   -# Parses the test data 
+   -# Checks that the parsed data matches the expected result
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_noserver_srowset(struct mapitest *mt) 
+{
+	bool result;
+
+	result = mapitest_noserver_srowset_untagged(mt);
+	if (result == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SRowSet Untagged");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SRowSet Untagged");
+
+	result = mapitest_noserver_srowset_tagged(mt);
+	if (result == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SRowSet Tagged");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SRowSet Tagged");
+
+	return true;
+}
+
+static bool mapitest_no_server_props_i2(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	uint16_t i2 = 0x5693; /* just a random, not zero value */
+	const uint16_t *i2get;
+
+	set_SPropValue_proptag(&propvalue, PT_SHORT, &i2);
+	i2get = (const uint16_t*)get_SPropValue_data(&propvalue);
+	if (!i2get || (*i2get != i2)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_SHORT");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_SHORT");
+	return true;
+}
+
+static bool mapitest_no_server_props_i4(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	uint32_t i4 = 0x33870911;
+	const uint32_t *i4get;
+
+	set_SPropValue_proptag(&propvalue, PT_LONG, &i4);
+	i4get = (const uint32_t*)get_SPropValue_data(&propvalue);
+	if (!i4get || (*i4get != i4)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_LONG");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_LONG");
+
+	return true;
+}
+
+static bool mapitest_no_server_props_i8(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	uint64_t i8 = 0x098763aa;
+	const uint64_t *i8get;
+
+	set_SPropValue_proptag(&propvalue, PT_I8, &i8);
+	i8get = (const uint64_t*)get_SPropValue_data(&propvalue);
+	if (!i8get || (*i8get != i8)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_I8");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_I8");
+
+	return true;
+}
+
+
+static bool mapitest_no_server_props_bool(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	bool b = false;
+	const bool *boolget;
+
+	set_SPropValue_proptag(&propvalue, PT_BOOLEAN, &b);
+	boolget = (const bool*)get_SPropValue_data(&propvalue);
+	if (!boolget || (*boolget != b)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_BOOLEAN");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_BOOLEAN");
+
+	return true;
+}
+
+static bool mapitest_no_server_props_err(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	enum MAPISTATUS err = MAPI_E_NOT_ME;
+	enum MAPISTATUS *errget;
+
+	set_SPropValue_proptag(&propvalue, PT_ERROR, &err);
+	errget = (enum MAPISTATUS*)get_SPropValue_data(&propvalue);
+	if (!errget || (*errget != err)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_ERROR");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_ERROR");
+
+	return true;
+}
+
+/* this seems strange... */
+static bool mapitest_no_server_props_null(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	uint32_t nullval = 0;
+	const uint32_t *nullget;
+
+	set_SPropValue_proptag(&propvalue, PT_NULL, &nullval);
+	nullget = (const uint32_t*)get_SPropValue_data(&propvalue);
+	if (!nullget) {
+		printf("null nullget\n");
+	}
+	if (!nullget || (*nullget != nullval)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_NULL");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_NULL");
+
+	return true;
+}
+
+
+static bool mapitest_no_server_props_string8(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	char *string = "OpenChange Project";
+	const char **stringget;
+
+	set_SPropValue_proptag(&propvalue, PT_STRING8, &string);
+	stringget = (const char**)get_SPropValue_data(&propvalue);
+	if (!stringget || (strncmp(*stringget, string, sizeof(*stringget)) != 0)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_STRING8");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_STRING8");
+
+	return true;
+}
+
+static bool mapitest_no_server_props_unicode(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	char *string = "OpenChange Project"; /* OK, so it probably isn't valid UTF16.. */
+	const char **stringget;
+
+	set_SPropValue_proptag(&propvalue, PT_UNICODE, &string);
+	stringget = (const char**)get_SPropValue_data(&propvalue);
+	if (!stringget || (strncmp(*stringget, string, sizeof(*stringget)) != 0)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_UNICODE");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_UNICODE");
+
+	return true;
+}
+
+static bool mapitest_no_server_props_filetime(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	struct FILETIME ft;
+	const struct FILETIME *ftget;
+
+	ft.dwLowDateTime = 0x12345678;
+	ft.dwHighDateTime = 0x87653491;
+	set_SPropValue_proptag(&propvalue, PT_SYSTIME, &ft);
+	ftget = (const struct FILETIME *)get_SPropValue_data(&propvalue);
+	if (!ftget || (ft.dwLowDateTime != ftget->dwLowDateTime) || (ft.dwHighDateTime != ftget->dwHighDateTime)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_SYSTIME");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_SYSTIME");
+
+	return true;
+}
+#if 0
+static bool mapitest_no_server_props_flatuid(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct FlatUID_r uid;
+	const struct FlatUID_r *uidget;
+	int i;
+
+	// initialise uid
+	for (i = 0; i < 16; ++i) {
+		uid.ab[i] = 0x40 + i;
+	}
+	printf("uid:");
+	for (i = 0; i < 16; ++i) {
+		printf("%c", uid.ab[i]);
+	}
+	printf("\n");
+
+	res = set_SPropValue_proptag(&propvalue, PT_CLSID, &uid);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_CLSID");
+		return false;
+	}
+	uidget = (const struct FlatUID_r*)get_SPropValue_data(&propvalue);
+	if (!uidget) {
+		printf("null uidget\n");
+		return false;
+	}
+	printf("uidget:");
+	for (i = 0; i < 16; ++i) {
+		printf("%c", uidget->ab[i]);
+	}
+	printf("\n");
+	if (!uidget || (memcmp(uid.ab, uidget->ab, 16))) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_CLSID");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_CLSID");
+
+	return true;
+}
+#endif
+
+static bool mapitest_no_server_props_bin(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+
+	struct Binary_r bin;
+	const struct Binary_r *binget;
+	int i;
+
+	// initialise bin
+	bin.cb = 8;
+	bin.lpb = talloc_array(mt->mem_ctx, uint8_t, bin.cb);
+	for (i = 0; i < bin.cb; ++i) {
+		bin.lpb[i] = 0xF0 + i;
+	}
+
+	res = set_SPropValue_proptag(&propvalue, PT_BINARY, &bin);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_BINARY");
+		return false;
+	}
+	binget = (const struct Binary_r *)get_SPropValue_data(&propvalue);
+	if (!binget || (bin.cb != binget->cb) || (bin.lpb != binget->lpb)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_BINARY");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_BINARY");
+
+	talloc_free(bin.lpb);
+
+	return true;
+}
+
+
+static bool mapitest_no_server_props_mv_i2(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct ShortArray_r shortarray;
+	const struct ShortArray_r *shortarrayget;
+
+	// create and initialise shortarray
+	shortarray.cValues = 3;
+	shortarray.lpi = talloc_array(mt->mem_ctx, uint16_t, shortarray.cValues);
+	shortarray.lpi[0] = 0x1245;
+	shortarray.lpi[1] = 0x3498;
+	shortarray.lpi[2] = 0x5675;
+	res = set_SPropValue_proptag(&propvalue, PT_MV_SHORT, &shortarray);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_SHORT");
+		return false;
+	}
+	shortarrayget = (const struct ShortArray_r *)get_SPropValue_data(&propvalue);
+	if (!shortarrayget || (shortarray.cValues != shortarrayget->cValues) || (shortarray.lpi != shortarrayget->lpi)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_SHORT");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_SHORT");
+
+	talloc_free(shortarray.lpi);
+
+	return true;
+}
+
+static bool mapitest_no_server_props_mv_i4(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct LongArray_r longarray;
+	const struct LongArray_r *longarrayget;
+
+	// create and initialise longarray
+	longarray.cValues = 2;
+	longarray.lpl = talloc_array(mt->mem_ctx, uint32_t, longarray.cValues);
+	longarray.lpl[0] = 0x34124543;
+	longarray.lpl[1] = 0x88567576;
+	res = set_SPropValue_proptag(&propvalue, PT_MV_LONG, &longarray);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_LONG");
+		return false;
+	}
+	longarrayget = (const struct LongArray_r *)get_SPropValue_data(&propvalue);
+	if (!longarrayget || (longarray.cValues != longarrayget->cValues) || (longarray.lpl != longarrayget->lpl)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_LONG");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_LONG");
+
+	talloc_free(longarray.lpl);
+
+	return true;
+}
+
+static bool mapitest_no_server_props_mv_bin(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct BinaryArray_r binarray;
+	const struct BinaryArray_r *binarrayget;
+
+	// create and initialise binarray
+	struct Binary_r bin1, bin2;
+	int i;
+
+	// initialise bin
+	bin1.cb = 8;
+	bin1.lpb = talloc_array(mt->mem_ctx, uint8_t, bin1.cb);
+	for (i = 0; i < bin1.cb; ++i) {
+		bin1.lpb[i] = 0xC0 + i;
+	}
+	bin2.cb = 12;
+	bin2.lpb = talloc_array(mt->mem_ctx, uint8_t, bin2.cb);
+	for (i = 0; i < bin2.cb; ++i) {
+		bin2.lpb[i] = 0xA0 + i;
+	}
+
+	binarray.cValues = 2;
+	binarray.lpbin = talloc_array(mt->mem_ctx, struct Binary_r, binarray.cValues);
+	binarray.lpbin[0] = bin1;
+	binarray.lpbin[1] = bin2;
+
+	res = set_SPropValue_proptag(&propvalue, PT_MV_BINARY, &binarray);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_BINARY");
+		return false;
+	}
+	binarrayget = (const struct BinaryArray_r *)get_SPropValue_data(&propvalue);
+	if (!binarrayget || (binarray.cValues != binarrayget->cValues) || (binarray.lpbin != binarrayget->lpbin)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_BINARY");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_BINARY");
+
+	talloc_free(binarray.lpbin);
+	talloc_free(bin1.lpb);
+	talloc_free(bin2.lpb);
+
+	return true;
+}
+
+static bool mapitest_no_server_props_mv_string8(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct StringArray_r stringarray;
+	const struct StringArray_r *stringarrayget;
+
+	// create and initialise stringarray
+	stringarray.cValues = 4;
+	stringarray.lppszA = talloc_array(mt->mem_ctx, const char*, stringarray.cValues);
+	stringarray.lppszA[0] = "Fedora";
+	stringarray.lppszA[1] = "FreeBSD";
+	stringarray.lppszA[2] = "OpenSolaris";
+	stringarray.lppszA[3] = "Debian";
+
+	res = set_SPropValue_proptag(&propvalue, PT_MV_STRING8, &stringarray);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_STRING8");
+		return false;
+	}
+	stringarrayget = (const struct StringArray_r *)get_SPropValue_data(&propvalue);
+	if (!stringarrayget || (stringarray.cValues != stringarrayget->cValues) || (stringarray.lppszA != stringarrayget->lppszA)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_STRING8");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_STRING8");
+
+	talloc_free(stringarray.lppszA);
+
+	return true;
+}
+
+static bool mapitest_no_server_props_mv_unicode(struct mapitest *mt)
+{
+	bool res;
+	struct SPropValue propvalue;
+	struct WStringArray_r unicodearray;
+	const struct WStringArray_r *unicodearrayget;
+
+	// create and initialise unicodearray
+	unicodearray.cValues = 4;
+	unicodearray.lppszW = talloc_array(mt->mem_ctx, const char*, unicodearray.cValues);
+	unicodearray.lppszW[0] = "Fedora";  /* not valid UTF16, but should still be OK */
+	unicodearray.lppszW[1] = "FreeBSD";
+	unicodearray.lppszW[2] = "OpenSolaris";
+	unicodearray.lppszW[3] = "Debian";
+
+	res = set_SPropValue_proptag(&propvalue, PT_MV_UNICODE, &unicodearray);
+	if (res == false) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue set with PT_MV_UNICODE");
+		return false;
+	}
+	unicodearrayget = (const struct WStringArray_r *)get_SPropValue_data(&propvalue);
+	if (!unicodearrayget || (unicodearray.cValues != unicodearrayget->cValues) || (unicodearray.lppszW != unicodearrayget->lppszW)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_UNICODE");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_UNICODE");
+
+	talloc_free(unicodearray.lppszW);
+
+	return true;
+}
+
+
+static bool mapitest_no_server_props_mv_filetime(struct mapitest *mt)
+{
+	struct SPropValue propvalue;
+	struct FILETIME ft1, ft2, ft3;
+	struct DateTimeArray_r ftarray;
+	const struct DateTimeArray_r *ftarrayget;
+
+	ft1.dwLowDateTime = 0x12345678;
+	ft1.dwHighDateTime = 0x87653491;
+	ft2.dwLowDateTime = 0x10234324;
+	ft2.dwHighDateTime = 0x98748756;
+	ft3.dwLowDateTime = 0x53245324;
+	ft3.dwHighDateTime = 0x54324633;
+
+	ftarray.cValues = 3;
+	ftarray.lpft = talloc_array(mt->mem_ctx, struct FILETIME, ftarray.cValues);
+	ftarray.lpft[0] = ft1;
+	ftarray.lpft[1] = ft2;
+	ftarray.lpft[2] = ft3;
+
+	set_SPropValue_proptag(&propvalue, PT_MV_SYSTIME, &ftarray);
+	ftarrayget = (const struct DateTimeArray_r *)get_SPropValue_data(&propvalue);
+	if (!ftarrayget || (ftarray.cValues != ftarrayget->cValues) || (ftarray.lpft != ftarrayget->lpft)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "SPropValue get/set with PT_MV_SYSTIME");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "SPropValue get/set with PT_MV_SYSTIME");
+
+	talloc_free(ftarray.lpft);
+
+	return true;
+}
+
+/**
+     \details Test the property setter / getter code
+
+   This function:
+   -# Checks setting / getting on an SPropValue
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_noserver_properties(struct mapitest *mt) 
+{
+	if (! mapitest_no_server_props_i2(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_i4(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_i8(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_bool(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_err(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_null(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_string8(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_unicode(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_filetime(mt)) {
+		return false;
+	}
+
+#if 0
+	if (! mapitest_no_server_props_flatuid(mt)) {
+		return false;
+	}
+#endif
+
+	if (! mapitest_no_server_props_bin(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_i2(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_i4(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_string8(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_unicode(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_filetime(mt)) {
+		return false;
+	}
+
+	if (! mapitest_no_server_props_mv_bin(mt)) {
+		return false;
+	}
+
+	/*
+	    Types we don't test yet:
+	 */
+	// should this be a double_t?
+	// int64_t dbl;/* [case(0x0005)] */
+
+	// struct FlatUID_r *lpguid;/* [unique,case(0x0048)] */
+	// struct FlatUIDArray_r MVguid;/* [case(0x1048)] */
+	// uint32_t object;/* [case(0x000d)] */
+
+
+	return true;
+}
+
+/**
+     \details Test the mapi_SPropValue_array handling
+
+   This function:
+   -# Builds a mapi_SPropValue_array
+   -# Checks that appropriate values can be retrieved
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_noserver_mapi_properties(struct mapitest *mt) 
+{
+	struct mapi_SPropValue_array valarray;
+	const uint16_t *i2get;
+	const uint32_t *i4get;
+	const uint32_t *i8get;
+	const uint8_t *boolget;
+	const char *stringget;
+	const struct FILETIME *ftget;
+	const struct SBinary_short *binget;
+	const struct mapi_MV_LONG_STRUCT *mvi4get;
+
+	valarray.cValues = 8;
+	valarray.lpProps = talloc_array(mt->mem_ctx, struct mapi_SPropValue, valarray.cValues);
+
+	valarray.lpProps[0].ulPropTag = PR_GENDER;
+	valarray.lpProps[0].value.i = 0x0001;  /* Female */
+	valarray.lpProps[1].ulPropTag = PR_ORIGINAL_SENSITIVITY;
+	valarray.lpProps[1].value.l = 0x00000002; /* Private */
+	valarray.lpProps[2].ulPropTag = PR_ALTERNATE_RECIPIENT_ALLOWED;
+	valarray.lpProps[2].value.b = false; 
+	valarray.lpProps[3].ulPropTag = PR_CONVERSATION_TOPIC;
+	valarray.lpProps[3].value.lpszA = "Elizabeth's Birthday"; 
+	valarray.lpProps[4].ulPropTag = PR_MESSAGE_SIZE_EXTENDED;
+	valarray.lpProps[4].value.d = 43857;
+	valarray.lpProps[5].ulPropTag = PR_RECORD_KEY;
+	valarray.lpProps[5].value.bin.cb = 4;
+	valarray.lpProps[5].value.bin.lpb = talloc_array(mt->mem_ctx, uint8_t, 4);
+	valarray.lpProps[5].value.bin.lpb[0] = 0x44;
+	valarray.lpProps[5].value.bin.lpb[1] = 0x00;
+	valarray.lpProps[5].value.bin.lpb[2] = 0x20;
+	valarray.lpProps[5].value.bin.lpb[3] = 0x00;
+	valarray.lpProps[6].ulPropTag = PR_FREEBUSY_BUSY_MONTHS;
+	valarray.lpProps[6].value.MVl.cValues = 2;
+	valarray.lpProps[6].value.MVl.lpl = talloc_array(mt->mem_ctx, uint32_t, 2);
+	valarray.lpProps[6].value.MVl.lpl[0] = 32130;
+	valarray.lpProps[6].value.MVl.lpl[1] = 32131;
+	valarray.lpProps[7].ulPropTag = PidLidAppointmentEndWhole;
+	valarray.lpProps[7].value.ft.dwLowDateTime  = 0x12975909;
+	valarray.lpProps[7].value.ft.dwHighDateTime  = 0x98989204;
+
+	/* now start pulling the values back out */
+	i2get = find_mapi_SPropValue_data(&valarray, PR_GENDER);
+	if (!i2get || (*i2get != 0x0001)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_SHORT");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_SHORT");
+
+
+	i4get = find_mapi_SPropValue_data(&valarray, PR_ORIGINAL_SENSITIVITY);
+	if (!i4get || (*i4get != 0x00000002)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_LONG");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_LONG");
+
+
+	i8get = find_mapi_SPropValue_data(&valarray, PR_MESSAGE_SIZE_EXTENDED);
+	if (!i8get || (*i8get != 43857)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_I8");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_I8");
+
+
+	boolget = find_mapi_SPropValue_data(&valarray, PR_ALTERNATE_RECIPIENT_ALLOWED);
+	if (!boolget || (*boolget != false)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_BOOLEAN");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_BOOLEAN");
+
+
+	stringget = find_mapi_SPropValue_data(&valarray, PR_CONVERSATION_TOPIC);
+	if (!stringget || (strcmp(stringget, "Elizabeth's Birthday") !=0 )) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_STRING");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_STRING");
+
+	ftget = find_mapi_SPropValue_data(&valarray, PidLidAppointmentEndWhole);
+	if (!ftget || (ftget->dwLowDateTime != 0x12975909) || (ftget->dwHighDateTime != 0x98989204)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_FILETIME");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_FILETIME");
+
+	binget = find_mapi_SPropValue_data(&valarray, PR_RECORD_KEY);
+	if (!binget || (binget->cb != 4 ) || (binget->lpb[0] != 0x44) || (binget->lpb[1] != 0x00)
+	    || (binget->lpb[2] != 0x20) || (binget->lpb[3] != 0x00)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_BINARY");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_BINARY");
+
+
+	mvi4get = find_mapi_SPropValue_data(&valarray, PR_FREEBUSY_BUSY_MONTHS);
+	if (!mvi4get || (mvi4get->cValues != 2 ) || (mvi4get->lpl[0] != 32130) || (mvi4get->lpl[1] != 32131)) {
+		/* failure */
+		mapitest_print(mt, "* %-40s: [FAILURE]\n", "mapi_SPropValue find with PT_MV_LONG");
+		return false;
+	}
+	mapitest_print(mt, "* %-40s: [SUCCESS]\n", "mapi_SPropValue find with PT_MV_LONG");
+
+#if 0
+	// Types to still to test:
+        int64_t dbl;/* [case(0x0005)] */
+        uint32_t err;/* [case(0x000a)] */
+        const char * lpszW;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(0x001f)] */
+        struct GUID lpguid;/* [case(0x0048)] */
+        struct mapi_SRestriction_wrap Restrictions;/* [case(0x00fd)] */
+        struct RuleAction RuleAction;/* [case(0x00fe)] */
+        struct mapi_SLPSTRArray MVszA;/* [case(0x101e)] */
+        struct mapi_SPLSTRArrayW MVszW;/* [case(0x101f)] */
+        struct mapi_SGuidArray MVguid;/* [case(0x1048)] */
+        struct mapi_SBinaryArray MVbin;/* [case(0x1102)] */
+#endif
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_nspi.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_nspi.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_nspi.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,855 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - NSPI tests
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_nspi.c
+
+   \brief NSPI tests
+ */
+
+
+/**
+   \details Test the NspiUpdateStat RPC operation (0x02)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_UpdateStat(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	uint32_t       		plDelta = 1;
+	struct SRowSet		*SRowSet;
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, 0x2, &SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = nspi_UpdateStat(nspi_ctx, &plDelta);
+	mapitest_print_retval(mt, "NspiUpdateStat");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapitest_print(mt, "* %-35s: %d\n", "plDelta", plDelta);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiQueryRows RPC operation (0x3)
+   
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_QueryRows(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropTagArray	*MIds;
+	struct SRowSet		*SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProp;
+	struct Restriction_r	Filter;
+
+	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,
+					  PR_DISPLAY_TYPE);
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_ACCOUNT;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval(mt, "NspiGetMatches");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	/* Query the rows */
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi_ctx, NULL, MIds, 1, &SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiQueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiSeekEntries RPC operation (0x04)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_SeekEntries(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropValue	pTarget;
+	struct SPropTagArray	*pPropTags;
+	struct SRowSet		*SRowSet;
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	SRowSet = talloc_zero(mt->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);
+
+	retval = nspi_SeekEntries(nspi_ctx, SortTypeDisplayName, &pTarget, pPropTags, NULL, &SRowSet);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "NspiSeekEntries");
+		talloc_free(pPropTags);
+		talloc_free(SRowSet);
+		return false;
+	}
+
+	mapitest_print_retval(mt, "NspiSeekEntries");
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(pPropTags);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetMatches RPC operation (0x5)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetMatches(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropTagArray	*MIds;
+	struct SRowSet		*SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProp;
+	struct Restriction_r	Filter;
+
+	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,
+					  PR_DISPLAY_TYPE);
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_ACCOUNT;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(MIds);
+	mapitest_print_retval(mt, "NspiGetMatches");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiResortRestriction RPC operation (0x6)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_ResortRestriction(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct Restriction_r	Filter;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	*lpProp = NULL;
+	struct SPropTagArray	*MIds = NULL;
+	struct SPropTagArray	*ppMIds = NULL;
+
+	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,
+					  PR_DISPLAY_NAME,
+					  PR_OFFICE_TELEPHONE_NUMBER,
+					  PR_OFFICE_LOCATION,
+					  PR_TITLE,
+					  PR_COMPANY_NAME,
+					  PR_ACCOUNT,
+					  PR_ADDRTYPE,
+					  PR_ENTRYID,
+					  PR_DISPLAY_TYPE,
+					  PR_INSTANCE_KEY,
+					  PR_EMAIL_ADDRESS
+					  );
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_OBJECT_TYPE;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.l = 6;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiGetMatches");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	ppMIds = talloc_zero(nspi_ctx->mem_ctx, struct SPropTagArray);
+	retval = nspi_ResortRestriction(nspi_ctx, SortTypeDisplayName, MIds, &ppMIds);
+	mapitest_print_retval(mt, "NspiResortRestriction");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		MAPIFreeBuffer(ppMIds);
+		return false;
+	}
+
+	MAPIFreeBuffer(MIds);
+	MAPIFreeBuffer(ppMIds);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiDNToMId RPC operation (0x7)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_DNToMId(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct StringsArray_r	pNames;
+	struct SPropTagArray	*MId;
+
+	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[0] = global_mapi_ctx->session->profile->homemdb;
+
+	MId = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+
+	retval = nspi_DNToMId(nspi_ctx, &pNames, &MId);
+	MAPIFreeBuffer((char **)pNames.Strings);
+	MAPIFreeBuffer(MId);
+
+	mapitest_print_retval(mt, "NspiDNToMId");
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetPropList RPC operation (0x08)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetPropList(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropTagArray	*pPropTags;
+	struct SPropTagArray	*MIds;
+	struct SPropValue	*lpProp;
+	struct Restriction_r	Filter;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		*SRowSet;
+
+	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);
+	lpProp->ulPropTag = PR_ANR_UNICODE;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszW = global_mapi_ctx->session->profile->username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SRowSet);
+	if (retval != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		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);
+	MAPIFreeBuffer(MIds);
+	mapitest_print_retval(mt, "NspiGetPropList");
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(pPropTags);
+		return false;
+	}
+
+	mapitest_print(mt, "* %-35s: %d\n", "Properties number", pPropTags->cValues);
+	MAPIFreeBuffer(pPropTags);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetProps RPC operation (0x09)
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct StringsArray_r	pNames;
+	struct SPropTagArray	*MId;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		*SRowSet;
+
+	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[0] = global_mapi_ctx->session->profile->homemdb;
+
+	MId = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+
+	retval = nspi_DNToMId(nspi_ctx, &pNames, &MId);
+	MAPIFreeBuffer((char **)pNames.Strings);
+	mapitest_print_retval(mt, "NspiDNToMId");
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MId);
+		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);
+	mapitest_print_retval(mt, "NspiGetProps");
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(MId);
+	MAPIFreeBuffer(SRowSet);
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiCompareMIds RPC operation (0x0a)
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_CompareMIds(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	uint32_t		plResult;
+	struct SPropTagArray	*MIds;
+	struct SRowSet		*SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProp;
+	struct Restriction_r	Filter;
+
+	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);
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_OBJECT_TYPE;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.l = 6;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiGetMatches");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	/* Ensure we have at least two result to compare */
+	if (MIds->cValues < 2) {
+		mapitest_print(mt, "* Only one result found, can't compare\n");
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	retval = nspi_CompareMIds(nspi_ctx, MIds->aulPropTag[0], MIds->aulPropTag[1], &plResult);
+	mapitest_print_retval(mt, "NspiCompareMIds");
+	MAPIFreeBuffer(MIds);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapitest_print(mt, "* %-35s: %d\n", "value of the comparison", plResult);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiModProps RPC operation (0xb)
+ 
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_nspi_ModProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SRow		*pRow;
+	struct SPropTagArray	*pPropTags;
+	struct SPropValue	modProp;
+	struct SPropTagArray	*MIds;
+	struct SRowSet		*SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProp;
+	struct Restriction_r	Filter;
+
+	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,
+					  PR_DISPLAY_TYPE);
+
+	/* Build the restriction we want for NspiGetMatches */
+	lpProp = talloc_zero(mt->mem_ctx, struct SPropValue);
+	lpProp->ulPropTag = PR_ACCOUNT;
+	lpProp->dwAlignPad = 0;
+	lpProp->value.lpszA = global_mapi_ctx->session->profile->username;
+
+	Filter.rt = RES_PROPERTY;
+	Filter.res.resProperty.relop = RES_PROPERTY;
+	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);
+	MAPIFreeBuffer(lpProp);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval(mt, "NspiGetMatches");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	/* Query the rows */
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	retval = nspi_QueryRows(nspi_ctx, NULL, MIds, 1, &SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiQueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(MIds);
+		return false;
+	}
+
+	/* Build the SRow and SPropTagArray for NspiModProps */
+	pRow = talloc_zero(mt->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);
+
+	retval = nspi_ModProps(nspi_ctx, MIds->aulPropTag[0], pPropTags, pRow);
+	mapitest_print_retval(mt, "NspiModProps");
+	MAPIFreeBuffer(MIds);
+	MAPIFreeBuffer(pPropTags);
+	MAPIFreeBuffer(pRow);
+
+	/* Assuming true for the moment */
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetSpecialTable RPC operation (0x0c)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetSpecialTable(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SRowSet		*SRowSet;
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, 0x0, &SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiGetSpecialTable (Hierarchy Table)");
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+	retval = nspi_GetSpecialTable(nspi_ctx, 0x2, &SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	mapitest_print_retval(mt, "NspiGetSpecialTable (Address Creation Template)");
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetTemplateInfo RPC operation (0x0d)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetTemplateInfo(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SRow		*ppData = NULL;
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	ppData = talloc_zero(mt->mem_ctx, struct SRow);
+	retval = nspi_GetTemplateInfo(nspi_ctx, 
+				      TI_TEMPLATE|TI_SCRIPT|TI_EMT|TI_HELPFILE_NAME|TI_HELPFILE_CONTENTS,
+				      0, NULL, &ppData);
+	mapitest_print_retval(mt, "NspiGetTemplateInfo");
+	MAPIFreeBuffer(ppData);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiModLinkAtt RPC operation (0x0e)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_ModLinkAtt(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+/* 	struct SPropTagArray	*MIds; */
+	struct BinaryArray_r	*lpEntryIds;
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	lpEntryIds = talloc_zero(mt->mem_ctx, struct BinaryArray_r);
+	lpEntryIds->cValues = 0;
+	lpEntryIds->lpbin = NULL;
+
+	retval = nspi_ModLinkAtt(nspi_ctx, false, PR_EMS_AB_REPORTS, 0x0, lpEntryIds);
+	mapitest_print_retval(mt, "NspiModLinkAtt");
+	MAPIFreeBuffer(lpEntryIds);
+
+	/* Assuming true for the moment */
+	return true;
+}
+
+
+
+/**
+   \details Test the NspiQueryColumns RPC operation (0x10)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_QueryColumns(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+	
+	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+
+	retval = nspi_QueryColumns(nspi_ctx, true, &SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "NspiQueryColumns");
+		MAPIFreeBuffer(SPropTagArray);
+		return false;
+	}
+
+	mapitest_print(mt, "* %d columns returned\n", SPropTagArray->cValues);
+	mapitest_print_retval(mt, "NspiQueryColumns");
+	MAPIFreeBuffer(SPropTagArray);
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetNamesFromIDs RPC operation (0x11)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetNamesFromIDs(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	struct nspi_context		*nspi_ctx;
+	struct SPropTagArray		*ppReturnedPropTags;
+	struct PropertyNameSet_r	*ppNames;
+
+	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);
+	mapitest_print_retval(mt, "NspiGetNamesFromIDs");
+	MAPIFreeBuffer(ppReturnedPropTags);
+	MAPIFreeBuffer(ppNames);
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiGetIDsFromNames RPC operation (0x12)
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_GetIDsFromNames(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	struct nspi_context		*nspi_ctx;
+	struct SPropTagArray		*ppReturnedPropTags;
+	struct PropertyNameSet_r	*ppNames;
+
+	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);
+	mapitest_print_retval(mt, "NspiGetNamesFromIDs");
+	MAPIFreeBuffer(ppReturnedPropTags);
+
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(ppNames);
+		return false;
+	}
+
+	ppReturnedPropTags = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	retval = nspi_GetIDsFromNames(nspi_ctx, true, ppNames->cNames, ppNames->aNames, &ppReturnedPropTags);
+	mapitest_print_retval(mt, "NspiGetIDsFromNames");
+	MAPIFreeBuffer(ppReturnedPropTags);
+	MAPIFreeBuffer(ppNames);
+	
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}
+
+
+/**
+   \details Test the NspiResolveNames and NspiResolveNamesW RPC
+   operations (0x13 and 0x14)
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_nspi_ResolveNames(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct nspi_context	*nspi_ctx;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray	*flaglist = NULL;
+	const char     		*username[2];
+
+	nspi_ctx = (struct nspi_context *) mt->session->nspi->ctx;
+
+	/* Build the username array */
+	username[0] = (const char *)mt->info.szDisplayName;
+	username[1] = NULL;
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xd,
+					  PR_ENTRYID,
+					  PR_DISPLAY_NAME,
+					  PR_ADDRTYPE,
+					  PR_GIVEN_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_EMAIL_ADDRESS,
+					  PR_SEND_INTERNET_ENCODING,
+					  PR_SEND_RICH_INFO,
+					  PR_SEARCH_KEY,
+					  PR_TRANSMITTABLE_DISPLAY_NAME,
+					  PR_7BIT_DISPLAY_NAME);
+
+	/* NspiResolveNames (0x13) */
+	flaglist = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	SRowSet = talloc_zero(mt->mem_ctx, struct SRowSet);
+
+	retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &SRowSet, &flaglist, 0);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "NspiResolveNames");
+		MAPIFreeBuffer(SPropTagArray);
+		talloc_free(flaglist);
+		talloc_free(SRowSet);
+		return false;
+	}
+	talloc_free(flaglist);
+	talloc_free(SRowSet);
+	mapitest_print_retval(mt, "NspiResolveNames");
+
+	/* NspiResolveNamesW (0x14) */
+	retval = ResolveNames(mt->session, (const char **)username, SPropTagArray, &SRowSet, &flaglist, MAPI_UNICODE);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "NspiResolveNamesW");
+		talloc_free(flaglist);
+		talloc_free(SRowSet);
+		return false;
+	}
+	talloc_free(flaglist);
+	talloc_free(SRowSet);
+	mapitest_print_retval(mt, "NspiResolveNamesW");
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxcfold.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcfold.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcfold.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,948 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - FOLDER OBJECT PROTOCOL operations
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxcfold.c
+
+   \brief Folder Object Protocol test suite
+*/
+
+struct folders {
+	uint32_t	id;
+	uint64_t	fid;
+	const char	*name;
+};
+
+static struct folders top_folders[] = {
+	{ 0x0, 0x0, "Mailbox Root Folder" },
+	{ 0x1, 0x0, "Deferred Actions" },
+	{ 0x2, 0x0, "Spooler Queue" },
+	{ 0x3, 0x0, "Top of Information Store" },
+	{ 0x4, 0x0, "Inbox" },
+	{ 0x5, 0x0, "Outbox" },
+	{ 0x6, 0x0, "Sent Items" },
+	{ 0x7, 0x0, "Deleted Items" },
+	{ 0x8, 0x0, "Common Views" },
+	{ 0x9, 0x0, "Schedule" },
+	{ 0xa, 0x0, "Search" },
+	{ 0xb, 0x0, "Views" },
+	{ 0xc, 0x0, "Shortcuts" },
+	{ 0xd, 0x0, NULL }
+};
+
+static struct folders inbox_folders[] = {
+	{ olFolderCalendar,		0x0, "Calendar"		},
+	{ olFolderContacts,		0x0, "Contacts"		},
+	{ olFolderJournal,		0x0, "Journal"		},
+	{ olFolderNotes,		0x0, "Notes"		},
+	{ olFolderTasks,		0x0, "Tasks"		},
+	{ olFolderDrafts,		0x0, "Drafts"		},
+	{ 0x0,				0x0, NULL }
+};
+
+struct test_folders {
+	const char	*name;
+	const char	*class;
+};
+
+
+static struct test_folders subfolders[] = {
+	{ MT_DIRNAME_APPOINTMENT,	IPF_APPOINTMENT	},
+	{ MT_DIRNAME_CONTACT,		IPF_CONTACT	},
+	{ MT_DIRNAME_JOURNAL,		IPF_JOURNAL	},
+	{ MT_DIRNAME_POST,		IPF_POST	},
+	{ MT_DIRNAME_NOTE,		IPF_NOTE	},
+	{ MT_DIRNAME_STICKYNOTE,	IPF_STICKYNOTE	},
+	{ MT_DIRNAME_TASK,		IPF_TASK	},
+	{ NULL,				NULL		}
+};
+
+
+/**
+   \details Test the OpenFolder (0x2) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open folders located within the top information store folder
+	-# Open folders located within the Inbox folder
+
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_OpenFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_store_t	*store;
+	mapi_id_t		id_folder;
+	int			i;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Prepare the top folder check */
+	store = (mapi_object_store_t *) obj_store.private_data;
+	top_folders[0].fid = store->fid_mailbox_root;
+	top_folders[1].fid = store->fid_deferred_actions;
+	top_folders[2].fid = store->fid_spooler_queue;
+	top_folders[3].fid = store->fid_top_information_store;
+	top_folders[4].fid = store->fid_inbox;
+	top_folders[5].fid = store->fid_outbox;
+	top_folders[6].fid = store->fid_sent_items;
+	top_folders[7].fid = store->fid_deleted_items;
+	top_folders[8].fid = store->fid_common_views;
+	top_folders[9].fid = store->fid_schedule;
+	top_folders[10].fid = store->fid_search;
+	top_folders[11].fid = store->fid_views;
+	top_folders[12].fid = store->fid_shortcuts;
+
+	/* Step2. Check top folders (Private mailbox) */
+	mapitest_print(mt, "* Private Mailbox - Message Store (Owner)\n");
+	mapitest_indent();
+	for (i = 0; top_folders[i].name; i++) {
+		mapi_object_init(&obj_folder);
+		retval = OpenFolder(&obj_store, top_folders[i].fid, &obj_folder);
+		mapitest_print_retval_fmt(mt, "OpenFolder", "(%s)", top_folders[i].name);
+		if (retval != MAPI_E_SUCCESS) {
+			return false;
+		}
+		mapi_object_release(&obj_folder);
+	}
+	mapitest_deindent();
+
+	/* Step3. Check for Inbox folders */
+	mapitest_print(mt, "* Private Mailbox - Mailbox (Owner)\n");
+	mapitest_indent();
+	for (i = 0; inbox_folders[i].name; i++) {
+		mapi_object_init(&obj_folder);
+		GetDefaultFolder(&obj_store, &id_folder, inbox_folders[i].id);
+		retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+		mapitest_print_retval_fmt(mt, "OpenFolder", "(%s)", inbox_folders[i].name);
+		if (retval != MAPI_E_SUCCESS) {
+			return false;
+		}
+		mapi_object_release(&obj_folder);
+	}
+	mapitest_deindent();
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the CreateFolder (0x1c) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the top information folder
+        -# Create a test directory
+	-# Create sub directories with different container classes
+	-# Empty the folder
+	-# Delete the folder
+
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_CreateFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	lpProp[1];
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_top;
+	mapi_object_t		obj_child;
+	mapi_id_t		id_folder;
+	int			i;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Top Information Store folder */
+	mapi_object_init(&obj_folder);
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the top test folder */
+	mapitest_print(mt, "* Create GENERIC \"%s\" folder\n", MT_DIRNAME_TOP);
+	mapi_object_init(&obj_top);
+	retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+			      OPEN_IF_EXISTS, &obj_top);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Create sub directories */
+	mapitest_print(mt, "* Creating sub directories\n");
+	mapitest_indent();
+	for (i = 0; subfolders[i].name; i++) {
+		/* Step 4.1. Create the sub folder */
+		mapi_object_init(&obj_child);
+		retval = CreateFolder(&obj_top, FOLDER_GENERIC, subfolders[i].name, NULL,
+				      OPEN_IF_EXISTS, &obj_child);
+		mapitest_print_retval_fmt(mt, "CreateFolder", "(%s)", subfolders[i].name);
+
+		/* Step 4.2. Set its container class */
+		set_SPropValue_proptag(&lpProp[0], PR_CONTAINER_CLASS, (const void *) subfolders[i].class);
+		retval = SetProps(&obj_child, lpProp, 1);
+		mapitest_print_retval_fmt(mt, "SetProps", "(%s)", subfolders[i].name);		
+
+		mapi_object_release(&obj_child);
+	}
+	mapitest_deindent();
+
+	/* Step 5. Empty Folder */
+	retval = EmptyFolder(&obj_top);
+	mapitest_print_retval(mt, "EmptyFolder");
+
+	/* Step 6. DeleteFolder */
+	retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_top),
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+	
+	/* Release */
+	mapi_object_release(&obj_top);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetHierarchyTable (0x4) operation
+
+  This function:
+	-# Log on the user private mailbox
+	-# Open the top information folder
+	-# Call the GetHierarchyTable operation
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_GetHierarchyTable(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	mapi_id_t		id_folder;
+	uint32_t		RowCount;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Top Information Store folder */
+	mapi_object_init(&obj_folder);
+
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Get the Hierarchy Table */
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, &RowCount);
+	mapitest_print_retval_fmt(mt, "GetHierarchyTable", "(%d rows)", RowCount);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetContentsTable (0x5) operation
+
+  This function:
+	-# Log on the user private mailbox
+	-# Open the top information folder
+	-# Call the GetContentsTable operation
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_GetContentsTable(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		id_folder;
+	uint32_t		RowCount;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Top Information Store folder */
+	mapi_object_init(&obj_folder);
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderTopInformationStore);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Get the Contents Table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &RowCount);
+	mapitest_print_retval_fmt(mt, "GetContentsTable", "(%d rows)", RowCount);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the SetSearchCriteria (0x30) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Retrieve the inbox folder ID
+	-# Open the default search folder
+	-# Create a search folder within this folder
+	-# Set the message class property on this container
+	-# Set a restriction criteria
+	-# Call SetSearchCriteria
+	-# Delete the test search folder
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_SetSearchCriteria(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	bool				ret = true;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_search;
+	mapi_object_t			obj_searchdir;
+	mapi_id_t			id_inbox;
+	mapi_id_t			id_search;
+	mapi_id_array_t			id;
+	struct SPropValue		lpProps[1];
+	struct mapi_SRestriction	res;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Open Inbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Open Search folder */
+	retval = GetDefaultFolder(&obj_store, &id_search, olFolderFinder);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_search);
+	retval = OpenFolder(&obj_store, id_search, &obj_search);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Create a search folder */
+	mapi_object_init(&obj_searchdir);
+	retval = CreateFolder(&obj_search, FOLDER_SEARCH, "mapitest", 
+			      "mapitest search folder", OPEN_IF_EXISTS,
+			      &obj_searchdir);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Set properties on this search folder */
+	lpProps[0].ulPropTag = PR_CONTAINER_CLASS;
+	lpProps[0].value.lpszA = IPF_NOTE;
+	retval = SetProps(&obj_searchdir, lpProps, 1);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto error;
+	}
+
+	/* Step 6. Search criteria on this folder */
+	mapi_id_array_init(&id);
+	mapi_id_array_add_id(&id, id_inbox);
+
+	res.rt = RES_CONTENT;
+	res.res.resContent.fuzzy = FL_SUBSTRING;
+	res.res.resContent.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.value.lpszA = "[MT]";
+
+	retval = SetSearchCriteria(&obj_searchdir, &res,
+				   BACKGROUND_SEARCH|RECURSIVE_SEARCH, &id);
+	mapitest_print_retval(mt, "SetSearchCriteria");
+	mapi_id_array_release(&id);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+error:
+	retval = DeleteFolder(&obj_search, mapi_object_get_id(&obj_searchdir),
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+	mapi_object_release(&obj_searchdir);
+	mapi_object_release(&obj_search);
+	mapi_object_release(&obj_store);
+	return ret;
+}
+
+
+/**
+   \details Test the GetSearchCriteria (0x31) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Retrieve the inbox folder ID
+	-# Open the default search folder
+	-# Create a search folder within this folder
+	-# Set the message class property on this container
+	-# Set a restriction criteria
+	-# Call SetSearchCriteria
+	-# Call GetSearchCriteria
+	-# Delete the test search folder
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_GetSearchCriteria(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	bool				ret = true;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_search;
+	mapi_object_t			obj_searchdir;
+	mapi_id_t			id_inbox;
+	mapi_id_t			id_search;
+	mapi_id_array_t			id;
+	struct SPropValue		lpProps[1];
+	struct mapi_SRestriction	res;
+	uint32_t			ulSearchFlags;
+	uint16_t			count;
+	mapi_id_t			*fid;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Open Inbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_inbox, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Open Search folder */
+	retval = GetDefaultFolder(&obj_store, &id_search, olFolderFinder);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_search);
+	retval = OpenFolder(&obj_store, id_search, &obj_search);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Create a search folder */
+	mapi_object_init(&obj_searchdir);
+	retval = CreateFolder(&obj_search, FOLDER_SEARCH, "mapitest", 
+			      "mapitest search folder", OPEN_IF_EXISTS,
+			      &obj_searchdir);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Set properties on this search folder */
+	lpProps[0].ulPropTag = PR_CONTAINER_CLASS;
+	lpProps[0].value.lpszA = IPF_NOTE;
+	retval = SetProps(&obj_searchdir, lpProps, 1);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto error;
+	}
+
+	/* Step 6. Search criteria on this folder */
+	mapi_id_array_init(&id);
+	mapi_id_array_add_id(&id, id_inbox);
+
+	res.rt = RES_CONTENT;
+	res.res.resContent.fuzzy = FL_SUBSTRING;
+	res.res.resContent.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resContent.lpProp.value.lpszA = "[MT]";
+
+	retval = SetSearchCriteria(&obj_searchdir, &res,
+				   BACKGROUND_SEARCH|RECURSIVE_SEARCH, &id);
+	mapitest_print_retval(mt, "SetSearchCriteria");
+	mapi_id_array_release(&id);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto error;
+	}
+
+	/* Step 7. Call GetSearchCriteria */
+	retval = GetSearchCriteria(&obj_searchdir, &res, &ulSearchFlags, &count, &fid);
+	mapitest_print_retval(mt, "GetSearchCriteria");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto error;
+	}
+
+
+error:
+	retval = DeleteFolder(&obj_search, mapi_object_get_id(&obj_searchdir),
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+	mapi_object_release(&obj_searchdir);
+	mapi_object_release(&obj_search);
+	mapi_object_release(&obj_store);
+	return ret;
+}
+
+
+/**
+   \details Test the MoveCopyMessages (0x33) opetation.
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the Inbox folder (source)
+	-# Open the Deleted Items folder (destination)
+	-# Creates 3 sample messages
+	-# Move messages from source to destination
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_MoveCopyMessages(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder_src;
+	mapi_object_t		obj_folder_dst;
+	mapi_object_t		obj_message;
+	mapi_object_t		dst_contents;
+	uint32_t		dst_count;
+	struct mapi_SRestriction res;
+	struct SPropTagArray    *SPropTagArray;
+	struct SRowSet		SRowSet;
+	mapi_id_array_t		msg_id_array;
+	mapi_id_t		msgid[20];
+	mapi_id_t		id_folder;
+	uint32_t		i;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Source Inbox folder */
+	mapi_object_init(&obj_folder_src);
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder_src);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+		
+	/* Step 3. Open Destination Deleted Items folder */
+	mapi_object_init(&obj_folder_dst);
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderDeletedItems);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder_dst);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&(dst_contents));
+	GetContentsTable(&(obj_folder_dst), &(dst_contents), 0, &dst_count);
+	mapitest_print_retval(mt, "GetContentsTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 4. Create sample messages */
+	mapi_id_array_init(&msg_id_array);
+	for (i = 0; i < 3; i++) {
+		mapi_object_init(&obj_message);
+		retval = mapitest_common_message_create(mt, &obj_folder_src, &obj_message, MT_MAIL_SUBJECT);
+		mapitest_print_retval(mt, "mapitest_common_message_create");
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+		
+		retval = SaveChangesMessage(&obj_folder_src, &obj_message, KeepOpenReadOnly);
+		mapitest_print_retval(mt, "SaveChangesMessage");
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+		mapi_id_array_add_obj(&msg_id_array, &obj_message);
+		mapi_object_release(&obj_message);
+	}
+
+	/* Step 5. Move messages from source to destination */
+	retval = MoveCopyMessages(&obj_folder_src, &obj_folder_dst, &msg_id_array, 0);
+	mapitest_print_retval(mt, "MoveCopyMessages");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapi_id_array_release(&msg_id_array);
+
+	/* Step 6. Apply a filter */
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RES_PROPERTY;
+	res.res.resProperty.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT;
+
+	retval = Restrict(&(dst_contents), &res, NULL);
+	mapitest_print_retval(mt, "Restrict");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 7. Get the filtered row */
+        SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_MID);
+        SetColumns(&(dst_contents), SPropTagArray);
+	mapitest_print_retval(mt, "SetColumns");
+	MAPIFreeBuffer(SPropTagArray);
+
+	QueryRows(&(dst_contents), 20, TBL_NOADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if ( (retval == MAPI_E_SUCCESS) && (SRowSet.cRows > 0) ) {
+		for (i = 0; i < SRowSet.cRows; ++i) {
+			msgid[i] = SRowSet.aRow[i].lpProps[0].value.d;
+		}
+	}
+
+	/* Step 8. Delete Messages */
+	retval = DeleteMessage(&obj_folder_dst, msgid, i); 
+	mapitest_print_retval(mt, "DeleteMessage");
+
+	/* Release */
+	mapi_object_release(&obj_folder_src);
+	mapi_object_release(&obj_folder_dst);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the MoveFolder (0x35) operation.
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the Inbox folder (source)
+	-# Create a temporary folder
+	-# Create 1 message in this new folder
+	-# Open the Deleted Items folder (destination)
+	-# Move the temporary folder from Inbox to DeletedItems
+	-# Empty and delete the moved temporary folder
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_MoveFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_src;
+	mapi_object_t		obj_dst;
+	mapi_object_t		obj_message;
+	bool			ret = true;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open the inbox folder */
+	mapi_object_init(&obj_src);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_src, olFolderInbox);
+	if (ret == false) return ret;
+
+	/* Step 3. Create temporary folder */
+	mapi_object_init(&obj_folder);
+	retval = CreateFolder(&obj_src, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+			      OPEN_IF_EXISTS, &obj_folder);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Create message within this temporary folder */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval(mt, "mapitest_common_message_create");
+
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	mapi_object_release(&obj_message);
+
+	/* Step 5. Open the Deleted items folder */
+	mapi_object_init(&obj_dst);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_dst, olFolderDeletedItems);
+
+	/* Step 6. MoveFolder */
+	retval = MoveFolder(&obj_folder, &obj_src, &obj_dst, MT_DIRNAME_TOP, false);
+	mapitest_print_retval(mt, "MoveFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapi_object_release(&obj_folder);
+
+	/* Step 7. Delete the moved folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_find_folder(mt, &obj_dst, &obj_folder, MT_DIRNAME_TOP);
+	mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_find_folder", (ret == true) ? "true" : "false");
+
+	if (ret == true) {
+		retval = EmptyFolder(&obj_folder);
+		mapitest_print_retval(mt, "EmptyFolder");
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	
+		retval = DeleteFolder(&obj_dst, mapi_object_get_id(&obj_folder),
+				      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+		mapitest_print_retval(mt, "DeleteFolder");
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	}
+	
+
+	/* Release */
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_src);
+	mapi_object_release(&obj_dst);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the CopyFolder (0x36) operation.
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the Inbox folder (source)
+	-# Create a temporary folder
+	-# Create a subdirectory
+	-# Open the Deleted Items folder (destination)
+	-# Copy the temporary folder from Inbox to DeletedItems
+	-# Empty and delete the original and copied folder
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_CopyFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;	
+	mapi_object_t		obj_subfolder;
+	mapi_object_t		obj_src;
+	mapi_object_t		obj_dst;
+	bool			ret = true;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open the inbox folder */
+	mapi_object_init(&obj_src);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_src, olFolderInbox);
+	if (ret == false) return ret;
+
+	/* Step 3. Create temporary folder */
+	mapi_object_init(&obj_folder);
+	retval = CreateFolder(&obj_src, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+			      OPEN_IF_EXISTS, &obj_folder);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Create the sub folder */
+	mapi_object_init(&obj_subfolder);
+	retval = CreateFolder(&obj_folder, FOLDER_GENERIC, MT_DIRNAME_NOTE, NULL,
+			      OPEN_IF_EXISTS, &obj_subfolder);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapi_object_release(&obj_subfolder);
+
+	/* Step 5. Open the Deleted items folder */
+	mapi_object_init(&obj_dst);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_dst, olFolderDeletedItems);
+
+	/* Step 6. CopyFolder */
+	retval = CopyFolder(&obj_folder, &obj_src, &obj_dst, MT_DIRNAME_TOP, false, false);
+	mapitest_print_retval(mt, "CopyFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 7. Delete the original and copied folder */
+	retval = EmptyFolder(&obj_folder);
+	mapitest_print_retval(mt, "EmptyFolder");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	
+	retval = DeleteFolder(&obj_src, mapi_object_get_id(&obj_folder),
+			      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapi_object_release(&obj_folder);
+
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_find_folder(mt, &obj_dst, &obj_folder, MT_DIRNAME_TOP);
+	mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_find_folder", (ret == true) ? "true" : "false");
+
+	if (ret == true) {
+		retval = EmptyFolder(&obj_folder);
+		mapitest_print_retval(mt, "EmptyFolder");
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	
+		retval = DeleteFolder(&obj_dst, mapi_object_get_id(&obj_folder),
+				      DEL_MESSAGES|DEL_FOLDERS|DELETE_HARD_DELETE, NULL);
+		mapitest_print_retval(mt, "DeleteFolder");
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	}
+	
+	/* Release */
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_src);
+	mapi_object_release(&obj_dst);
+	mapi_object_release(&obj_store);
+
+
+	return ret;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxcfxics.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcfxics.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcfxics.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,69 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - BULK DATA TRANSFER PROTOCOL operations
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxcfxics.c
+
+   \brief Bulk Data Transfer Protocol test suite
+*/
+
+/**
+   \details Test the GetLocalReplicaIds (0x7f) operation
+
+   This function:
+   -# Log on private message store
+   -# Reserve a range of Ids
+ */
+_PUBLIC_ bool mapitest_oxcfxics_GetLocalReplicaIds(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct GUID		ReplGuid;
+	uint8_t			GlobalCount[6];
+	char			*guid;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Reserve a range of IDs */
+	retval = GetLocalReplicaIds(&obj_store, 0x1000, &ReplGuid, GlobalCount);
+	mapitest_print_retval(mt, "GetLocalReplicaIds");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+	guid = GUID_string(mt->mem_ctx, &ReplGuid);
+	mapitest_print(mt, "* %-35s: %s\n", "ReplGuid", guid);
+	mapitest_print(mt, "* %-35s: %x %x %x %x %x %x\n", "GlobalCount", GlobalCount[0],
+		       GlobalCount[1], GlobalCount[2], GlobalCount[3], GlobalCount[4],
+		       GlobalCount[5]);
+	talloc_free(guid);
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxcmsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcmsg.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,1235 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - E-MAIL OBJECT PROTOCOL operations
+
+   Copyright (C) Julien Kerihuel 2008
+   Copyright (C) Brad Hards <bradh at openchange.org> 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_oxcmsg.c
+
+   \brief Message and Attachment Object Protocol test suite
+*/
+
+
+/**
+   \details Test the CreateMessage (0x6) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the Outbox folder
+	-# Create the message
+	-# Delete the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_CreateMessage(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
+	if (ret == false) return ret;
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Delete the message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+#define	OXCMSG_SETREADFLAGS	"[OXCMSG] SetMessageReadFlag"
+
+/**
+   \details Test the SetMessageReadFlag (0x11) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the Inbox folder
+	-# Create a tmp message
+	-# Play with SetMessageReadFlag
+	-# Delete the message
+	
+   Note: We can test either SetMessageReadFlag was effective by checking its
+   old/new value with GetProps on PR_MESSAGE_FLAGS property.
+
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_SetMessageReadFlag(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+	mapi_id_t		id_msgs[1];
+	uint32_t		status= 0;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Step 2. Open Outbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
+	if (ret == false) return ret;
+
+	/* Step 3. Create the tmp message and save it */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS);
+	if (ret == false) return ret;
+
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Play with SetMessageReadFlag */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS);
+	ret = true;
+
+	/* 1. Retrieve and Save the original PR_MESSAGE_FLAGS value */
+	retval = GetProps(&obj_message, SPropTagArray, &lpProps, &cValues);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	if (cValues > 1) {
+		status = lpProps[1].value.l;
+	}
+	MAPIFreeBuffer(lpProps);
+	
+	/* Set message flags as read */
+	retval = SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_READ);
+	mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_READ");
+
+	/* Check if the operation was successful */
+	retval = GetProps(&obj_message, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	if (cValues > 1 && status != lpProps[1].value.l) {
+		mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag");
+		status = lpProps[1].value.l;
+	} else {
+		mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag");
+		return false;
+	}
+	MAPIFreeBuffer(lpProps);
+		
+	/* Set the message flags as submitted */
+	retval = SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_SUBMIT);
+	mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_SUBMIT");
+	
+	/* Check if the operation was successful */
+	retval = GetProps(&obj_message, SPropTagArray, &lpProps, &cValues);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	if (cValues > 1 && status != lpProps[1].value.l) {
+		mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag");
+		status = lpProps[1].value.l;
+	} else {
+		mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag");
+		return false;
+	}
+
+	/* Step 5. Delete the message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	MAPIFreeBuffer(SPropTagArray);
+
+	return true;
+}
+
+/**
+   \details Test the ModifyRecipients (0xe) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the Outbox folder
+   -# Create the message
+   -# Resolve recipients names
+   -# Call ModifyRecipients operation for MAPI_TO, MAPI_CC, MAPI_BCC
+   -# Delete the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_ModifyRecipients(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	char			**username = NULL;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+
+	/* Step 4. Resolve the recipients and call ModifyRecipients */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	username = talloc_array(mt->mem_ctx, char *, 2);
+	username[0] = mt->info.szDisplayName;
+	username[1] = NULL;
+
+	retval = ResolveNames(mapi_object_get_session(&obj_message), 
+			      (const char **)username, SPropTagArray, 
+			      &SRowSet, &flaglist, 0);
+	mapitest_print_retval(mt, "ResolveNames");
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Delete the message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the RemoveAllRecipients (0xd) operation
+
+   This function:
+   -# Log on the use private mailbox
+   -# Open the Outbox folder
+   -# Create the message, set recipients
+   -# Save the message
+   -# Remove all recipients
+   -# Delete the message
+
+   \param mt point on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_RemoveAllRecipients(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = false;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	char			**username = NULL;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	username = talloc_array(mt->mem_ctx, char *, 2);
+	username[0] = mt->info.szDisplayName;
+	username[1] = NULL;
+
+	retval = ResolveNames(mapi_object_get_session(&obj_message),
+			      (const char **)username, SPropTagArray, 
+			      &SRowSet, &flaglist, 0);
+	mapitest_print_retval(mt, "ResolveNames");
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	ret = true;
+
+	/* Step 5. Remove all recipients */
+	retval = RemoveAllRecipients(&obj_message);
+	mapitest_print_retval(mt, "RemoveAllRecipients");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 4. Save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6. Delete the message */
+	errno = 0;
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the ReadRecipients (0xf) operation
+
+      This function:
+      -# Log on the use private mailbox
+      -# Open the Outbox folder
+      -# Create the message, set recipients
+      -# Save the message
+      -# Read message recipients
+      -# Delete the message
+
+   \param mt point on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_ReadRecipients(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = false;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	char			**username = NULL;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	struct ReadRecipientRow	*RecipientRows;
+	uint8_t			count;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	username = talloc_array(mt->mem_ctx, char *, 2);
+	username[0] = mt->info.szDisplayName;
+	username[1] = NULL;
+
+	retval = ResolveNames(mapi_object_get_session(&obj_message),
+			      (const char **)username, SPropTagArray, 
+			      &SRowSet, &flaglist, 0);
+	mapitest_print_retval(mt, "ResolveNames");
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mt->mem_ctx, SRowSet, SPropValue);
+
+	retval = SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+
+	SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
+	mapitest_print_retval(mt, "SetRecipientType");
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	ret = true;
+
+	/* Step 4. Save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Read recipients */
+	RecipientRows = talloc_zero(mt->mem_ctx, struct ReadRecipientRow);
+	retval = ReadRecipients(&obj_message, 0, &count, &RecipientRows);
+	mapitest_print_retval(mt, "ReadRecipients");
+	MAPIFreeBuffer(RecipientRows);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 6. Delete the message */
+	errno = 0;
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the SaveChangesMessage (0xc) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the Outbox folder
+   -# Create the message
+   -# Save the message
+   -# Delete the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_SaveChangesMessage(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Delete the saved message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetMessageStatus (0x1f) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the outbox folder
+   -# Create the message
+   -# Save the message
+   -# Get outbox contents table
+   -# Get messages status
+   -# Delete the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_GetMessageStatus(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		count;
+	uint32_t		status;
+	uint32_t		i;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Get outbox contents table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
+	mapitest_print_retval(mt, "GetContentsTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
+					  PR_MID, PR_MSG_STATUS);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6. Get Message Status */
+	while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
+	       SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			retval = GetMessageStatus(&obj_folder, SRowSet.aRow[i].lpProps[0].value.d, &status);
+			mapitest_print_retval(mt, "GetMessageStatus");
+			if (GetLastError() != MAPI_E_SUCCESS) {
+				return false;
+			}
+		}
+	}
+
+	/* Step 7. Delete the saved message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+struct msgstatus {
+	uint32_t	status;
+	const char	*name;
+};
+
+static struct msgstatus msgstatus[] = {
+	{MSGSTATUS_HIDDEN,		"MSGSTATUS_HIDDEN"},
+	{MSGSTATUS_HIGHLIGHTED,		"MSGSTATUS_HIGHLIGHTED"},
+	{MSGSTATUS_TAGGED,		"MSGSTATUS_TAGGED"},
+	{MSGSTATUS_REMOTE_DOWNLOAD,	"MSGSTATUS_REMOTE_DOWNLOAD"},
+	{MSGSTATUS_REMOTE_DELETE,	"MSGSTATUS_REMOTE_DELETE"},
+	{MSGSTATUS_DELMARKED,		"MSGSTATUS_DELMARKED"},
+	{0,				NULL}
+};
+
+/**
+   \details Test the GetMessageStatus (0x1f) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the outbox folder
+   -# Create the message
+   -# Save the message
+   -# Get outbox contents table
+   -# Set different messages status, then get them and compare values
+   -# Delete the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_SetMessageStatus(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_ctable;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		count;
+	uint32_t		i;
+	uint32_t		ulOldStatus;
+	uint32_t		ulOldStatus2;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	mapitest_print_retval(mt, "CreateMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Get outbox contents table */
+	mapi_object_init(&obj_ctable);
+	retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
+	mapitest_print_retval(mt, "GetContentsTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
+					  PR_MID, PR_MSG_STATUS);
+	retval = SetColumns(&obj_ctable, SPropTagArray);
+	mapitest_print_retval(mt, "SetColumns");
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Fetch the first email */
+	retval = QueryRows(&obj_ctable, 1, TBL_NOADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6. SetMessageStatus + GetMessageStatus + Comparison */
+	for (i = 0; msgstatus[i].name; i++) {
+		retval = SetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d,
+					  msgstatus[i].status, msgstatus[i].status, &ulOldStatus2);
+		mapitest_print_retval(mt, "SetMessageStatus");
+
+		retval = GetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d, &ulOldStatus);
+		mapitest_print_retval(mt, "GetMessageStatus");
+
+		if ((ulOldStatus != ulOldStatus2) && (ulOldStatus & msgstatus[i].status)) {
+			errno = 0;
+			mapitest_print(mt, "* %-35s: %s 0x%.8x\n", "Comparison", msgstatus[i].name, GetLastError());
+		}
+	}
+
+	/* Step 7. Delete the saved message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_ctable);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+/**
+   \details Test the SetReadFlags (0x66) operation
+
+   This function:
+   -# Opens the Inbox folder and creates some test content
+   -# Checks that the PR_MESSAGE_FLAGS property on each message is 0x0
+   -# Apply SetReadFlags() on every second messages
+   -# Check the results are as expected
+   -# Apply SetReadFlags() again
+   -# Check the results are as expected
+   -# Cleanup
+	
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcmsg_SetReadFlags(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_htable;
+	mapi_object_t		obj_test_folder;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	struct mt_common_tf_ctx	*context;
+	int			i;
+	uint64_t		messageIds[5];
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* Fetch the contents table for the test folder */
+	context = mt->priv;
+	mapi_object_init(&(obj_test_folder));
+	GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, NULL);
+	mapitest_print_retval(mt, "GetContentsTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS);
+	SetColumns(&obj_test_folder, SPropTagArray);
+	mapitest_print_retval(mt, "SetColumns");
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	for (i = 0; i < 10; ++i) {
+		if (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) != 0x0) {
+			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;
+		}
+	}	
+
+	for (i = 0; i < 5; ++i) {
+		messageIds[i] = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[i*2].lpProps[0])));
+	}
+
+	SetReadFlags(&(context->obj_test_folder), 0x0, 5, messageIds);
+	mapitest_print_retval(mt, "SetReadFlags");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	for (i = 0; i < 10; i+=2) {
+		if (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) != MSGFLAG_READ) {
+			mapitest_print(mt, "* %-35s: unexpected flag (0) 0x%x\n", "QueryRows", 
+				       (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1]))));
+			ret = false;
+			goto cleanup;
+		}
+		if (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1])) != 0x0) {
+			mapitest_print(mt, "* %-35s: unexpected flag (1) 0x%x\n", "QueryRows", 
+				       (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1]))));
+			ret = false;
+			goto cleanup;
+		}
+	}	
+
+	SetReadFlags(&(context->obj_test_folder), CLEAR_READ_FLAG, 5, messageIds);
+
+	retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	for (i = 0; i < 10; ++i) {
+		if (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) != 0x0) {
+			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 */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	return ret;
+}
+
+/**
+   \details Test the OpenEmbeddedMessage (0x46) and CreateAttach operations
+
+   This function:
+        -# Logs on the user private mailbox
+        -# Open the Inbox folder         
+        -# Create a test message          
+        -# Embed a message in the test message
+        -# Delete the test message                  
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */                                        
+_PUBLIC_ bool mapitest_oxcmsg_OpenEmbeddedMessage(struct mapitest *mt)
+{                                                                     
+	enum MAPISTATUS		retval;                               
+	bool			ret;                                  
+	mapi_object_t		obj_store;                            
+	mapi_object_t		obj_folder;                           
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_attach;
+	mapi_object_t		obj_embeddedmsg;
+	mapi_id_t		id_msgs[1];                           
+	struct SPropValue	attach[2];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_store);
+		return false;                          
+	}
+
+	/* Step 2. Open Outbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox);
+	if (ret == false) {
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* Step 3. Create the tmp message and save it */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS);
+	if (ret == false) return ret;
+
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* Step 4. Embed another message in the message */
+	mapi_object_init(&obj_attach);
+	retval = CreateAttach(&obj_message, &obj_attach);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateAttach", retval);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* use SetProps() to set the attachment up */
+	attach[0].ulPropTag = PR_ATTACH_METHOD;
+	attach[0].value.l = ATTACH_EMBEDDED_MSG;
+	attach[1].ulPropTag = PR_RENDERING_POSITION;
+	attach[1].value.l = 0;
+	retval = SetProps(&obj_attach, attach, 2);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetProps", retval);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;;
+	}
+
+	mapi_object_init(&obj_embeddedmsg);
+	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_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;;
+	}
+
+	ret = mapitest_common_message_fill(mt, &obj_embeddedmsg, "[MT] EmbeddedMessage");
+	if (ret == false) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	// Save the changes to the embedded message
+	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_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;;
+	}
+	// Save the changes to the attachment and then the message
+	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_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;;
+	}
+
+	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_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;;
+	}
+
+	/* Step 5. Delete the message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "DeleteMessage", GetLastError());
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_attach);
+		mapi_object_release(&obj_message);
+		mapi_object_release(&obj_folder);
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_attach);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcprpt.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,2376 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - PROPERTY AND STREAM OBJECT PROTOCOL operations
+
+   Copyright (C) Julien Kerihuel 2008
+   Copyright (C) Brad Hards 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/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxcprpt.c
+
+   \brief Property and Stream Object Protocol test suite
+*/
+
+/**
+   \details Test the GetProps (0x7) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Retrieve the properties list using GetPropList
+   -# Retrieve their associated values using the GetProps operation
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_GetProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}	
+	
+	/* Step 2. Retrieve the properties list using GetPropList */
+	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	retval = GetPropList(&obj_store, SPropTagArray);
+	mapitest_print_retval(mt, "GetPropList");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Call the GetProps operation */
+	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetPropsAll (0x8) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Retrieve the whole set of properties and values associated to the store object
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_GetPropsAll(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	mapi_object_t			obj_store;
+	struct mapi_SPropValue_array	properties_array;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. GetPropsAll operation */
+	retval = GetPropsAll(&obj_store, &properties_array);
+	mapitest_print_retval(mt, "GetPropsAll");
+	MAPIFreeBuffer(properties_array.lpProps);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetPropList (0x9) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Retrieve the list of properties associated to the store object object
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_GetPropList(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct SPropTagArray	*SPropTagArray;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. GetPropList operation */
+	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	retval = GetPropList(&obj_store, SPropTagArray);
+	mapitest_print_retval(mt, "GetPropList");
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the SetProps (0xa) operation
+
+   This function:
+   -# Logon Private mailbox
+   -# Use GetProps to retrieve the mailbox name
+   -# Change it using SetProps
+   -# Reset the mailbox name to its original value
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_SetProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct SPropValue	*lpProps;
+	struct SPropValue	lpProp[1];
+	struct SPropTagArray	*SPropTagArray;
+	const char		*mailbox = NULL;
+	const char		*new_mailbox = NULL;
+	uint32_t		cValues;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2: GetProps, retrieve mailbox name */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
+	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval_step_fmt(mt, "2.", "GetProps", "(%s)", "Retrieve the mailbox name");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+
+	if (cValues && lpProps[0].value.lpszA) {
+		mailbox = lpProps[0].value.lpszA;
+		mapitest_print(mt, "* Step 2. Mailbox name = %s\n", mailbox);
+	} else {
+		mapitest_print(mt, MT_ERROR, "* Step 2 - GetProps: No mailbox name\n");
+		return false;
+	}
+
+	/* Step 2.1: SetProps with new value */
+	cValues = 1;
+	new_mailbox = talloc_asprintf(mt->mem_ctx, "%s [MAPITEST]", mailbox);
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, 
+			       (const void *) new_mailbox);
+	retval = SetProps(&obj_store, lpProp, cValues);
+	mapitest_print_retval_step_fmt(mt, "2.1.", "SetProps", "(%s)", "NEW mailbox name");
+
+	/* Step 2.2: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
+	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(new_mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name - [SUCCESS] (%s)\n", lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name [FAILURE]\n");
+		}
+	}
+	MAPIFreeBuffer((void *)new_mailbox);
+
+	/* Step 3.1: Reset mailbox to its original value */
+	cValues = 1;
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)mailbox);
+	retval = SetProps(&obj_store, lpProp, cValues);
+	mapitest_print_retval_step_fmt(mt, "3.1.", "SetProps", "(%s)", "OLD mailbox name");
+	
+	/* Step 3.2: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
+	retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name [SUCCESS]\n");
+		} else {
+			mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name, [FAILURE]\n");
+		}
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the DeleteProps (0xb) operation)
+
+   This function:
+   -# Opens the mailbox
+   -# Create a test folder
+   -# Creates a reference email, and sets some properties on it
+   -# Delete properties from this message
+   -# Checks that properties got deleted
+   -# Deletes both email and the test folder
+
+   \todo It would be useful to test the problem return values
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_DeleteProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_top_folder;
+	mapi_id_t		id_top_folder;
+	mapi_object_t		obj_ref_folder;
+	mapi_object_t		obj_ref_message;
+	const char		*name = NULL;
+	const char		*subject = NULL;
+	struct SPropValue	lpProp[3];
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&obj_top_folder);
+	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2: Create reference folder */
+	mapi_object_init(&obj_ref_folder);
+        retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+                              OPEN_IF_EXISTS, &obj_ref_folder);
+	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3: Create reference message */
+	mapi_object_init(&obj_ref_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+        name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
+	subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
+	set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
+	retval = SetProps(&obj_ref_message, lpProp, 2);
+	mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	MAPIFreeBuffer(lpProps);
+
+	/* Step 5. Delete Properties */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
+	retval = DeleteProps(&obj_ref_message, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval_step_fmt(mt, "5.", "DeleteProps", "PR_CONVERSATION_TOPIC");
+
+	/* Step 6. Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (get_SPropValue(lpProps, PR_CONVERSATION_TOPIC) == NULL) {
+		mapitest_print(mt, "* Step 5.1. - GetProps verifier [SUCCESS]\n");
+	} else {
+		mapitest_print(mt, "* Step 5.1. - GetProps verifier [FAILURE]:\n");
+	}
+	MAPIFreeBuffer(lpProps);
+
+	/* Step 7: cleanup folders */
+	retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval_step(mt, "6.", "DeleteFolder");
+
+	/* Release */
+	mapi_object_release(&obj_ref_message);
+	mapi_object_release(&obj_ref_folder);
+	mapi_object_release(&obj_top_folder);
+	mapi_object_release(&obj_store);
+
+
+	return true;
+}
+
+
+/**
+   \details Test the CopyProps (0x67) operation
+
+   This function:
+   -# Opens the mailbox
+   -# Creates a test folder
+   -# Creates a reference email, and sets some properties on it
+   -# Checks those properties are set correctly
+   -# Creates a second email, and sets some (different) properties on it
+   -# Checks those properties on the second folder are set correctly
+   -# Copies properties from the reference email to the second email (no overwrite)
+   -# Checks that properties on both emails are correct
+   -# Copies properties again, but with overwrite
+   -# Checks that properties on both emails are correct
+   -# Moves properties from the original email to the second email (no overwrite)
+   -# Checks that properties on both emails are correct
+   -# Deletes both emails and the test folder
+
+   \todo It would be useful to test the problem return values
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_CopyProps(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_top_folder;
+	mapi_id_t		id_top_folder;
+	mapi_object_t		obj_ref_folder;
+	mapi_object_t		obj_ref_message;
+	const char		*name = NULL;
+	const char		*subject = NULL;
+	struct SPropValue	lpProp[3];
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+	mapi_object_t		obj_target_message;
+	const char		*targ_name = NULL;
+	const char		*targ_dept = NULL;
+	uint16_t		problem_count = 999;
+	struct PropertyProblem *problems = NULL;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&obj_top_folder);
+	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2: Create reference folder */
+	mapi_object_init(&obj_ref_folder);
+        retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+                              OPEN_IF_EXISTS, &obj_ref_folder);
+	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3: Create reference message */
+	mapi_object_init(&obj_ref_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+        name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
+	subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
+	set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
+	retval = SetProps(&obj_ref_message, lpProp, 2);
+	mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+
+	/* Step 5: Create target message */
+	mapi_object_init(&obj_target_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval_step_fmt(mt, "5.1.", "mapitest_common_message_create", "(%s)", "Create target email");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite);
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+        targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name");
+	targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name);
+	set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept);
+	retval = SetProps(&obj_target_message, lpProp, 2);
+	mapitest_print_retval_step_fmt(mt, "5.2.", "SetProps", "(%s)", "set properties on target email");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+
+
+
+	/* Step 7: Copy properties, no overwrite */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite,
+			   &problem_count, &problems);
+	mapitest_print_retval_step_fmt(mt, "7.", "CopyProps", "(%s)", "no overwrite");
+	MAPIFreeBuffer(problems);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+
+	/* Step 8: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	/* this one shouldn't be overwritten */
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	/* this one should be copied */
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	/* this one should be unchanged */
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+		}
+	}
+
+	/* Step 9: Copy properties, with overwrite */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, 0x0,
+			   &problem_count, &problems);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_step_fmt(mt, "9.", "CopyProps", "(%s)", "with overwrite");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 10: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	/* this one should now be overwritten */
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	/* this one should be copied */
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	/* this one should be unchanged */
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+		}
+	}
+
+
+	/* Step 11: Move properties, no overwrite */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite|CopyFlagsMove,
+			   &problem_count, &problems);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_step_fmt(mt, "11.", "CopyProps", "(%s)", "move");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 12: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (cValues == 2) {
+		mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n");
+	} else {
+		mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n");
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+		}
+	}
+
+
+	/* Cleanup reference strings */
+	MAPIFreeBuffer((void *)subject);
+	MAPIFreeBuffer((void *)name);
+	MAPIFreeBuffer((void *)targ_name);
+	MAPIFreeBuffer((void *)targ_dept);
+
+	/* Step 13: cleanup folders */
+	retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval_step(mt, "13.1.", "DeleteFolder");
+
+	/* Release */
+	mapi_object_release(&obj_ref_message);
+	mapi_object_release(&obj_ref_folder);
+	mapi_object_release(&obj_top_folder);
+	mapi_object_release(&obj_store);
+
+
+	return true;
+}
+
+
+
+/**
+   \details Test Stream operations. This test uses all related stream
+   operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream
+   (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e)
+   
+   This function:
+   -# Logon 
+   -# Open Outbox folder
+   -# Create message
+   -# Create attachment and set properties
+   -# Open the stream
+   -# Set the stream size
+   -# Write into the stream
+   -# Commit the stream
+   -# Save the message
+   -# Get stream size and compare values
+   -# Open the stream again with different permissions
+   -# Read the stream and compare buffers
+   -# SeekStream at 0x1000 from the end of the stream
+   -# Read the 0x1000 last bytes and check if it matches
+   -# Delete the message;
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise -1
+ */
+_PUBLIC_ bool mapitest_oxcprpt_Stream(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_attach;
+	mapi_object_t		obj_stream;
+	mapi_id_t		id_folder;
+	DATA_BLOB		data;
+	struct SPropValue	attach[3];
+	char			*stream = NULL;
+	char			*out_stream = NULL;
+	uint32_t		stream_len = 0x32146;
+	unsigned char		buf[MT_STREAM_MAX_SIZE];
+	uint32_t		StreamSize = 0;
+	uint16_t		read_size = 0;
+	uint16_t		write_len = 0;
+	uint32_t		len = 0;
+	uint32_t		offset = 0;
+	mapi_id_t		id_msgs[1];
+	uint32_t		i;
+	uint64_t		NewPosition;
+
+	stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
+	if (stream == NULL) {
+		return false;
+	}
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Inbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+
+	/* Step 4. Create the attachment */
+	mapi_object_init(&obj_attach);
+	retval = CreateAttach(&obj_message, &obj_attach);
+	mapitest_print_retval(mt, "CreateAttach");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	attach[0].ulPropTag = PR_ATTACH_METHOD;
+	attach[0].value.l = ATTACH_BY_VALUE;
+	attach[1].ulPropTag = PR_RENDERING_POSITION;
+	attach[1].value.l = 0;
+	attach[2].ulPropTag = PR_ATTACH_FILENAME;
+	attach[2].value.lpszA = MT_MAIL_ATTACH;
+
+	retval = SetProps(&obj_attach, attach, 3);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 5. Open the stream */
+	mapi_object_init(&obj_stream);
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
+	mapitest_print_retval(mt, "OpenStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 6. Set the stream size */
+	retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
+	mapitest_print_retval(mt, "SetStreamSize");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 7. Write the stream */
+	write_len = 0;
+
+	if (stream_len < MT_STREAM_MAX_SIZE) {
+		data.length = stream_len;
+		data.data = (uint8_t *) stream;
+		retval = WriteStream(&obj_stream, &data, &write_len);
+		mapitest_print_retval_fmt(mt, "WriteStream", "(0x%x bytes written)", write_len);
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	} else {
+		uint32_t	StreamSize = stream_len;
+
+		for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) {
+			data.length = len;
+			data.data = (uint8_t *)stream + offset;
+			retval = WriteStream(&obj_stream, &data, &write_len);
+			mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len);
+			if (retval != MAPI_E_SUCCESS) {
+				ret = false;
+				break;
+			}
+
+			StreamSize -= write_len;
+			if (StreamSize > MT_STREAM_MAX_SIZE) {
+				offset += MT_STREAM_MAX_SIZE;
+			} else {
+				offset += write_len;
+				len = StreamSize;
+			}
+		}
+	}
+
+ 	/* Step 8. Commit the stream */
+	retval = CommitStream(&obj_stream);
+	mapitest_print_retval(mt, "CommitStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 9. Save the attachment */
+	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesAttachment");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 10. Get stream size */
+	retval = GetStreamSize(&obj_stream, &StreamSize);
+	mapitest_print_retval(mt, "GetStreamSize");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison", 
+		       (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]");
+
+	/* Step 11. Read the stream */
+	mapi_object_release(&obj_stream);
+	mapi_object_init(&obj_stream);
+
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+	mapitest_print_retval(mt, "OpenStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	offset = 0;
+	out_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
+	do {
+		retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size);
+		mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
+		memcpy(out_stream + offset, buf, read_size);
+		offset += read_size;
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+			break;
+		}
+	} while (read_size && (offset != StreamSize));
+	out_stream[offset] = '\0';
+
+	if (offset) {
+		if (!strcmp(stream, out_stream)) {
+			mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison");
+		} else {
+			mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison");
+
+		}
+	}
+
+	/* Step 12. SeekStream from the end of the stream */
+	retval = SeekStream(&obj_stream, 0x2, (uint64_t) -0x1000, &NewPosition);
+	mapitest_print_retval(mt, "SeekStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+
+	talloc_free(out_stream);
+	out_stream = talloc_size(mt->mem_ctx, 0x1001);
+	retval = ReadStream(&obj_stream, (uint8_t *)out_stream, 0x1000, &read_size);
+	out_stream[read_size] = '\0';
+	mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	
+	if (read_size && !strcmp(out_stream, stream + StreamSize - read_size)) {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison");
+	} else {
+		mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison");
+	}
+
+	/* Step 14. Delete the message */
+	errno = 0;
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_stream);
+	mapi_object_release(&obj_attach);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	talloc_free(stream);
+	talloc_free(out_stream);
+
+	return ret;
+}
+
+
+/**
+   \details Test the CopyToStream (0x3a) operation
+
+   This function:
+   -# Logon the mailbox
+   -# Open the inbox folder
+   -# Create a sample messages with an attachment
+   -# Create 2 streams
+   -# Fill the first stream with random data
+   -# Seek stream positions to the beginning
+   -# CopyToStream data from first stream to the second stream
+   -# Read dst stream and compare with src stream
+   -# Delete the message
+   
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_CopyToStream(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_attach;
+	mapi_object_t		obj_attach2;
+	mapi_object_t		obj_stream;
+	mapi_object_t		obj_stream2;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+	struct SPropValue	attach[3];
+	DATA_BLOB		data;
+	char			*stream = NULL;
+	char			*dst_stream = NULL;
+	uint32_t		stream_len = 0x32146;
+	unsigned char		buf[MT_STREAM_MAX_SIZE];
+	uint32_t		StreamSize = 0;
+	uint16_t		write_len = 0;
+	uint16_t		read_size = 0;
+	uint32_t		len = 0;
+	uint32_t		offset = 0;
+	uint32_t		i;
+	uint64_t		ReadByteCount = 0;
+	uint64_t		WrittenByteCount = 0;
+	uint64_t		NewPosition = 0;
+
+	stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
+	if (stream == NULL) {
+		return false;
+	}
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Inbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+
+	/* Step 4. Create the first attachment */
+	mapi_object_init(&obj_attach);
+	retval = CreateAttach(&obj_message, &obj_attach);
+	mapitest_print_retval(mt, "CreateAttach");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	attach[0].ulPropTag = PR_ATTACH_METHOD;
+	attach[0].value.l = ATTACH_BY_VALUE;
+	attach[1].ulPropTag = PR_RENDERING_POSITION;
+	attach[1].value.l = 0;
+	attach[2].ulPropTag = PR_ATTACH_FILENAME;
+	attach[2].value.lpszA = MT_MAIL_ATTACH;
+
+	retval = SetProps(&obj_attach, attach, 3);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 5. Open the stream */
+	mapi_object_init(&obj_stream);
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
+	mapitest_print_retval(mt, "OpenStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 6. Set the stream size */
+	retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
+	mapitest_print_retval(mt, "SetStreamSize");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 7. Write the stream */
+	write_len = 0;
+
+	if (stream_len < MT_STREAM_MAX_SIZE) {
+		data.length = stream_len;
+		data.data = (uint8_t *) stream;
+		retval = WriteStream(&obj_stream, &data, &write_len);
+		mapitest_print_retval_fmt(mt, "WriteStream", "(0x%x bytes written)", write_len);
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	} else {
+		uint32_t	StreamSize = stream_len;
+
+		for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) {
+			data.length = len;
+			data.data = (uint8_t *)stream + offset;
+			retval = WriteStream(&obj_stream, &data, &write_len);
+			mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len);
+
+			StreamSize -= write_len;
+			if (StreamSize > MT_STREAM_MAX_SIZE) {
+				offset += MT_STREAM_MAX_SIZE;
+			} else {
+				offset += write_len;
+				len = StreamSize;
+			}
+		}
+	}
+
+ 	/* Step 8. Commit the stream */
+	retval = CommitStream(&obj_stream);
+	mapitest_print_retval(mt, "CommitStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 9. Save the attachment */
+	retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesAttachment");
+
+	/* Step 10. Create the second attachment */
+	mapi_object_init(&obj_attach2);
+	retval = CreateAttach(&obj_message, &obj_attach2);
+	mapitest_print_retval(mt, "CreateAttach");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	attach[0].ulPropTag = PR_ATTACH_METHOD;
+	attach[0].value.l = ATTACH_BY_VALUE;
+	attach[1].ulPropTag = PR_RENDERING_POSITION;
+	attach[1].value.l = 0;
+	attach[2].ulPropTag = PR_ATTACH_FILENAME;
+	attach[2].value.lpszA = MT_MAIL_ATTACH2;
+
+	retval = SetProps(&obj_attach2, attach, 3);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 11. Open the dst stream */
+	mapi_object_init(&obj_stream2);
+	retval = OpenStream(&obj_attach2, PR_ATTACH_DATA_BIN, 2, &obj_stream2);
+	mapitest_print_retval(mt, "OpenStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 12. Get src stream size */
+	retval = GetStreamSize(&obj_stream, &StreamSize);
+	mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Src", StreamSize);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 13. Reset streams positions to the beginning */
+	retval = SeekStream(&obj_stream, 0, 0, &NewPosition);
+	mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Src");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	retval = SeekStream(&obj_stream2, 0, 0, &NewPosition);
+	mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 14. Copy src to dst stream */
+	retval = CopyToStream(&obj_stream, &obj_stream2, StreamSize, &ReadByteCount, &WrittenByteCount);
+	mapitest_print_retval(mt, "CopyToStream");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 14. Save the attachment */
+	retval = SaveChangesAttachment(&obj_message, &obj_attach2, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesAttachment");
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 15. Compare values */
+	mapitest_print(mt, "* %-35s: 0x%llx - 0x%llx %s\n", "Read/Write bytes comparison",
+		       ReadByteCount, WrittenByteCount, 
+		       (ReadByteCount == WrittenByteCount) ? "[SUCCESS]" : "[FAILURE]");
+
+
+	/* Step 16. Get dst stream size */
+	retval = GetStreamSize(&obj_stream2, &StreamSize);
+	mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Dst", StreamSize);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	retval = SeekStream(&obj_stream2, 0, 0, &NewPosition);
+	mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 17. Read the dst stream */
+	offset = 0;
+	dst_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
+	do {
+		retval = ReadStream(&obj_stream2, buf, MT_STREAM_MAX_SIZE, &read_size);
+		mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
+		memcpy(dst_stream + offset, buf, read_size);
+		offset += read_size;
+		if (retval != MAPI_E_SUCCESS) {
+			ret = false;
+			break;
+		}
+	} while (read_size || offset != StreamSize);
+	dst_stream[offset] = '\0';
+
+	/* Step 18. Compare streams */
+	if (!strcmp(stream, dst_stream)) {
+		mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison");
+	} else {
+		mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison");
+	}
+	
+
+	/* Step 19. Delete Message */
+	errno = 0;
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_stream2);
+	mapi_object_release(&obj_stream);
+	mapi_object_release(&obj_attach2);
+	mapi_object_release(&obj_attach);
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	talloc_free(stream);
+	talloc_free(dst_stream);
+
+	return ret;
+}
+
+
+/**
+   \details Test the CopyTo (0x39) operation
+
+   This function:
+   -# Opens the mailbox
+   -# Creates a test folder
+   -# Creates a reference email, and sets some properties on it
+   -# Checks those properties are set correctly
+   -# Creates a second email, and sets some (different) properties on it
+   -# Checks those properties on the second folder are set correctly
+   -# Copies properties from the reference email to the second email (no overwrite)
+   -# Checks that properties on both emails are correct
+   -# Copies properties again, but with overwrite
+   -# Checks that properties on both emails are correct
+   -# Moves properties from the original email to the second email (no overwrite)
+   -# Checks that properties on both emails are correct
+   -# Creates an attachment (with properties) on the reference email
+   -# Creates an attachment (with different properties) on the target email
+   -# Copies the properties on the reference email to the target
+   -# Checks the properties on both attachments are correct
+   -# Creates another folder
+   -# Copies properties from the test folder to the new folder
+   -# Checks that the properties on both folders are correct
+   -# Deletes both emails and the test folders
+
+   \todo It would be useful to test the problem return values
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_CopyTo(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_top_folder;
+	mapi_id_t		id_top_folder;
+	mapi_object_t		obj_ref_folder;
+	mapi_object_t		obj_targ_folder;
+	mapi_object_t		obj_ref_message;
+	mapi_object_t		obj_target_message;
+	mapi_object_t		obj_ref_attach;
+	mapi_object_t		obj_targ_attach;
+	const char		*name = NULL;
+	const char		*subject = NULL;
+	const char		*dept = NULL;
+	struct SPropValue	lpProp[3];
+	struct SPropTagArray	*exclude;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+	const char		*targ_name = NULL;
+	const char		*targ_dept = NULL;
+	uint16_t		problem_count = 999;
+	struct PropertyProblem *problems = NULL;
+	bool			ret = true;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&obj_top_folder);
+	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+
+	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 2: Create reference folder */
+	mapi_object_init(&obj_ref_folder);
+        retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+                              OPEN_IF_EXISTS, &obj_ref_folder);
+	mapitest_print_retval_fmt(mt, "CreateFolder", "(Create test folder)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
+	lpProp[0].value.lpszA = "IPF.Note";
+	SetProps(&obj_ref_folder, lpProp, 1);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3: Create reference message */
+	mapi_object_init(&obj_ref_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval(mt, "mapitest_common_message_create");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+        name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
+	subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
+	dept = talloc_asprintf(mt->mem_ctx, "Reference: %s", "dept");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
+	set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
+	set_SPropValue_proptag(&lpProp[2], PR_DEPARTMENT_NAME, (const void *)dept);
+	retval = SetProps(&obj_ref_message, lpProp, 3);
+	mapitest_print_retval(mt, "SetProps");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 4: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC,
+					  PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 4A - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4A - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 4B - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4B - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 4C - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4C - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	/* Step 5: Create target message */
+	mapi_object_init(&obj_target_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval(mt, "mapitest_common_message_create");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+        targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name");
+	targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name);
+	set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept);
+	retval = SetProps(&obj_target_message, lpProp, 2);
+	mapitest_print_retval(mt, "SetProps");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 6: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+
+		}
+	}
+
+
+	/* Step 7: Copy properties, no overwrite */
+	exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
+	retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsNoOverwrite,
+			   &problem_count, &problems);
+	MAPIFreeBuffer(exclude);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_fmt(mt, "CopyTo", "(no overwrite)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 8: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	/* this one shouldn't be overwritten */
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	/* this one should be copied */
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	/* this one should be unchanged */
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	/* Step 9: Copy properties, with overwrite */
+	exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DEPARTMENT_NAME);
+	retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, 0x0,
+			&problem_count, &problems);
+	MAPIFreeBuffer(exclude);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_fmt(mt, "CopyTo", "(with overwrite)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 10: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	/* this one should now be overwritten */
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	/* this one should be copied */
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	/* this one should be unchanged */
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	/* Step 11: Move properties, no overwrite */
+	exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
+	retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsNoOverwrite|CopyFlagsMove,
+			   &problem_count, &problems);
+	MAPIFreeBuffer(exclude);
+	MAPIFreeBuffer(problems);
+	mapitest_print(mt, "* %-35s: 0x%.8x\n", "Step 11 - CopyTo (move)", GetLastError());
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 12: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (cValues == 2) {
+		mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n");
+	} else {
+		mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n");
+		ret = false;
+		goto cleanup;
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
+	retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	if (lpProps[2].value.lpszA) {
+		if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
+			mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n",
+				       lpProps[2].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n",
+				       lpProps[2].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+
+	/* Step 13: Create attachment on reference email, and set properties */
+	mapi_object_init(&obj_ref_attach);
+	CreateAttach(&obj_ref_message, &obj_ref_attach);
+	mapitest_print_retval(mt, "CreateAttach");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	lpProp[0].ulPropTag = PR_ATTACH_METHOD;
+	lpProp[0].value.l = ATTACH_BY_VALUE;
+	lpProp[1].ulPropTag = PR_RENDERING_POSITION;
+	lpProp[1].value.l = 0;
+	lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
+	lpProp[2].value.lpszA = MT_MAIL_ATTACH;
+	SetProps(&obj_ref_attach, lpProp, 3);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	SaveChangesAttachment(&obj_ref_message, &obj_ref_attach, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesAttachment");
+
+	/* Step 14: Create attachment on target email */
+	mapi_object_init(&obj_targ_attach);
+	CreateAttach(&obj_target_message, &obj_targ_attach);
+	mapitest_print_retval(mt, "CreateAttach");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	lpProp[0].ulPropTag = PR_ATTACH_METHOD;
+	lpProp[0].value.l = ATTACH_BY_VALUE;
+	lpProp[1].ulPropTag = PR_RENDERING_POSITION;
+	lpProp[1].value.l = 0;
+	lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
+	lpProp[2].value.lpszA = MT_MAIL_ATTACH2;
+	SetProps(&obj_targ_attach, lpProp, 3);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	SaveChangesAttachment(&obj_target_message, &obj_targ_attach, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesAttachment");
+
+	/* Step 15: Copy props from reference email attachment to target email attachment */
+	exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
+	CopyTo(&obj_ref_attach, &obj_targ_attach, exclude, 0x0, &problem_count, &problems);
+	MAPIFreeBuffer(exclude);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_fmt(mt, "CopyTo", "(attachments)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 16: Check properties on both attachments are correct */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
+	GetProps(&obj_ref_attach, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 16B - Check: Reference attachment props - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 16B - Check: Reference attachment props [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}	
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
+	GetProps(&obj_targ_attach, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 16D - Check: Target attachment props - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 16D - Check: Target attachment props [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}	
+
+	/* Create another folder */
+	mapi_object_init(&obj_targ_folder);
+        retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, "[MT] Target Folder", NULL,
+                              OPEN_IF_EXISTS, &obj_targ_folder);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
+	lpProp[0].value.lpszA = "IPF.Journal";
+	SetProps(&obj_targ_folder, lpProp, 1);
+	mapitest_print_retval(mt, "SetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Copy properties from the test folder to the new folder */
+	exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
+	CopyTo(&obj_ref_folder, &obj_targ_folder, exclude, 0x0, &problem_count, &problems);
+	MAPIFreeBuffer(exclude);
+	MAPIFreeBuffer(problems);
+	mapitest_print_retval_fmt(mt, "CopyTo", "(folder)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}	
+
+	/* Check that the properties on both folders are correct */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
+	GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(MT_DIRNAME_TOP, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 19B - Check: Reference folder props - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 19B - Check: Reference folder props [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}	
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 19C - Check: Reference folder props - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 19C - Check: Reference folder props [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
+	GetProps(&obj_targ_folder, SPropTagArray, &lpProps, &cValues);
+	mapitest_print_retval(mt, "GetProps");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp("[MT] Target Folder", lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 19E - Check: Target folder props - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 19E - Check: Target folder props [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}	
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 19F - Check: Target folder props - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 19F - Check: Target folder props [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+			ret = false;
+			goto cleanup;
+		}
+	}	
+
+
+ cleanup:
+	/* Cleanup reference strings */
+	MAPIFreeBuffer((void *)subject);
+	MAPIFreeBuffer((void *)name);
+	MAPIFreeBuffer((void *)targ_name);
+	MAPIFreeBuffer((void *)targ_dept);
+
+	/* Cleanup folders */
+	retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_targ_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+	retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+
+	/* Release */
+	mapi_object_release(&obj_targ_attach);
+	mapi_object_release(&obj_ref_attach);
+	mapi_object_release(&obj_ref_message);
+	mapi_object_release(&obj_ref_folder);
+	mapi_object_release(&obj_top_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+#define NAMEDPROP_NAME "mapitest_namedprop"
+#define NAMEDPROP_IDNUM 0xDB
+
+/**
+   \details Test the GetPropertyIdsFromNames (0x56),
+   GetNamesFromPropertyIds (0x55) and QueryNamesFromIDs (0x5f) 
+   operations
+
+   This function:
+   -# Logs into the server
+   -# Create a test folder and test message
+   -# Creates one MNID_ID property
+   -# Creates one MNID_STRING property
+   -# Builds a table of Name, ID pairs using QueryNamesFromIDs()
+   -# Iterates over names, and calls GetIDsFromNames() on each name
+   -# Iterates over IDs, and calls GetNamesFromIDs() on each ID
+   -# Cleans up
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_NameId(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_top_folder;
+	mapi_id_t		id_top_folder;
+	mapi_object_t		obj_ref_folder;
+	mapi_object_t		obj_ref_message;
+	struct mapi_nameid	*nameid;
+	struct mapi_nameid	*nameid2;
+	struct MAPINAMEID	checknameid;
+	struct SPropTagArray	*SPropTagArray;
+	uint32_t		propID;
+	uint16_t		*propIDs;
+	bool 			ret = true;
+	int			i;
+
+	/* Log into the server */
+	mapi_object_init(&obj_store);
+	OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&obj_top_folder);
+	GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	mapitest_print_retval(mt, "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 2: Create test folder */
+	mapi_object_init(&obj_ref_folder);
+        CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+		     OPEN_IF_EXISTS, &obj_ref_folder);
+	mapitest_print_retval(mt, "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	mapi_object_init(&obj_ref_message);
+	mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval(mt, "mapitest_common_message_create");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3: Create and Retrieve one MNID_ID property */
+
+	/* Build the list of named properties we want to create */
+	nameid = mapi_nameid_new(mt->mem_ctx);
+	mapi_nameid_custom_lid_add(nameid, NAMEDPROP_IDNUM, PT_STRING8, PS_MAPI);
+
+	/* GetIDsFromNames and map property types */
+	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+	retval = GetIDsFromNames(&obj_ref_folder, nameid->count, 
+				 nameid->nameid, MAPI_CREATE, &SPropTagArray);
+	mapitest_print_retval(mt, "GetIDsFromNames");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		MAPIFreeBuffer(nameid);
+		goto cleanup;
+	}
+
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+	
+	propID = (SPropTagArray->aulPropTag[0] & 0xFFFF0000) | PT_NULL;
+	MAPIFreeBuffer(SPropTagArray);
+
+	nameid = mapi_nameid_new(mt->mem_ctx);
+	GetNamesFromIDs(&obj_ref_message, propID, &nameid->count, &nameid->nameid);
+	mapitest_print_retval(mt, "GetNamesFromIDs");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(nameid);
+		ret = false;
+		goto cleanup;
+	}
+
+	if ((nameid->nameid[0].ulKind != MNID_ID) || (nameid->nameid[0].kind.lid != NAMEDPROP_IDNUM)) {
+		errno = MAPI_E_RESERVED;
+		mapitest_print_retval_fmt(mt, "GetNamesFromIDs", 
+					  "Unexpected result: ulKind: %x mapped to 0x%.4x", 
+					  nameid->nameid[0].ulKind, nameid->nameid[0].kind.lid);
+		ret = false;
+		goto cleanup;
+	}
+
+	MAPIFreeBuffer(nameid);
+
+	/* Step 4: Create one MNID_STRING property */
+	nameid = mapi_nameid_new(mt->mem_ctx);
+	SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+
+	mapi_nameid_custom_string_add(nameid, NAMEDPROP_NAME, PT_STRING8, PS_MAPI);
+	GetIDsFromNames(&obj_ref_folder, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray);
+	mapitest_print_retval(mt, "GetIDsFromNames");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(nameid);
+		ret = false;
+		goto cleanup;
+	}
+
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+
+	propID = SPropTagArray->aulPropTag[0];
+	MAPIFreeBuffer(SPropTagArray);
+
+	/* Builds an array of Name,ID pairs using QueryNamesFromIDs() */
+	nameid = mapi_nameid_new(mt->mem_ctx);
+	propIDs = talloc_zero(mt->mem_ctx, uint16_t);
+	QueryNamedProperties(&obj_ref_message, 0, NULL, &nameid->count, &propIDs, &nameid->nameid);
+	nameid->nameid = talloc_steal((TALLOC_CTX *)nameid, nameid->nameid);
+	mapitest_print_retval(mt, "QueryNamedProperties");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		MAPIFreeBuffer(nameid);
+		talloc_free(propIDs);
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Iterate over names and call GetIDsFromNames() on each name */
+	for (i = 0; i < nameid->count; i++) {
+		checknameid.lpguid = nameid->nameid[i].lpguid;
+		checknameid.ulKind = nameid->nameid[i].ulKind;
+
+		switch (nameid->nameid[i].ulKind) {
+		case MNID_ID:
+			checknameid.kind.lid = nameid->nameid[i].kind.lid;
+			break;
+		case MNID_STRING:
+			checknameid.kind.lpwstr.Name = nameid->nameid[i].kind.lpwstr.Name;
+			checknameid.kind.lpwstr.NameSize = nameid->nameid[i].kind.lpwstr.NameSize;
+			break;
+		}
+
+		SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
+		GetIDsFromNames(&obj_ref_folder, 1, &checknameid, 0, &SPropTagArray);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			mapitest_print_retval(mt, "GetIDsFromNames");
+			MAPIFreeBuffer(nameid);
+			MAPIFreeBuffer(SPropTagArray);
+			ret = false;
+			goto cleanup;
+		}
+
+		/* check we got the right number of IDs */
+		if (SPropTagArray->cValues != 1) {
+			errno = MAPI_E_RESERVED;
+			mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID count (%i)", SPropTagArray->cValues);
+			MAPIFreeBuffer(nameid);
+			MAPIFreeBuffer(SPropTagArray);
+			ret = false;
+			goto cleanup;
+		}
+
+		/* check if the ID is the one we expected */
+		if (SPropTagArray->aulPropTag[0] != (propIDs[i] << 16)) {
+			errno = MAPI_E_RESERVED;
+			mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID (0x%x, expected 0x%x)",
+						  SPropTagArray->aulPropTag[0], (propIDs[i] << 16));
+			MAPIFreeBuffer(nameid);
+			MAPIFreeBuffer(SPropTagArray);
+			ret = false;
+			goto cleanup;
+		}
+		MAPIFreeBuffer(SPropTagArray);
+	}
+	mapitest_print(mt, "* Step 6: All IDs matched [SUCCESS]\n");
+
+	/* Iterates over IDs, and call GetNamesFromIDs() on each ID */
+        for (i = 0; i < nameid->count; i++) {
+		nameid2 = mapi_nameid_new(mt->mem_ctx);
+		GetNamesFromIDs(&obj_ref_folder, ((propIDs[i] << 16) & 0xFFFF0000) | PT_NULL, &nameid2->count, &nameid2->nameid);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			mapitest_print_retval(mt, "GetNamesFromIDs");
+			MAPIFreeBuffer(nameid2);
+			ret = false;
+			goto cleanup;
+		}
+
+		/* Check we got the right number of names */
+		if (nameid2->count != 1) {
+			mapitest_print_retval_fmt(mt, "GetNamesFromIDs", "Unexpected name count (%i)", nameid2->count);
+			MAPIFreeBuffer(nameid);
+			MAPIFreeBuffer(nameid2);
+			ret = false;
+			goto cleanup;
+		}
+
+		/* Check we got the right kind of name */
+		if (nameid2->nameid[0].ulKind != nameid->nameid[i].ulKind) {
+			mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected kind (0x%x, expected 0x%x)",
+						  nameid2->nameid[0].ulKind, nameid->nameid[i].ulKind);
+			MAPIFreeBuffer(nameid);
+			MAPIFreeBuffer(nameid2);
+			ret = false;
+			goto cleanup;
+		}
+
+		switch (nameid->nameid[i].ulKind) {
+		case MNID_ID:
+			if (nameid2->nameid[0].kind.lid != nameid->nameid[i].kind.lid) {
+				mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected hex name (0x%x, expected 0x%x)",
+							  nameid2->nameid[0].kind.lid, nameid->nameid[i].kind.lid);
+				MAPIFreeBuffer(nameid);
+				MAPIFreeBuffer(nameid2);
+				ret = false;
+				goto cleanup;
+			}
+			break;
+		case MNID_STRING:
+			if (nameid2->nameid[0].kind.lpwstr.NameSize != nameid->nameid[i].kind.lpwstr.NameSize) {
+				mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name length (0x%x, expected 0x%x)",
+							  nameid2->nameid[0].kind.lpwstr.NameSize, 
+							  nameid->nameid[i].kind.lpwstr.NameSize);
+				MAPIFreeBuffer(nameid);
+				MAPIFreeBuffer(nameid2);
+				ret = false;
+				goto cleanup;
+			}
+			if (strncmp(nameid2->nameid[0].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.NameSize) != 0) {
+				mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name (%s, expected %s)",
+							  nameid2->nameid[0].kind.lpwstr.Name, 
+							  nameid->nameid[i].kind.lpwstr.Name);
+				MAPIFreeBuffer(nameid);
+				MAPIFreeBuffer(nameid2);
+				ret = false;
+				goto cleanup;				
+			}
+			break;
+		}
+
+		MAPIFreeBuffer(nameid2);
+	}		
+	
+	MAPIFreeBuffer(nameid);
+	MAPIFreeBuffer(propIDs);
+
+ cleanup:
+	/* Clean up */
+	DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
+		     DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval(mt, "DeleteFolder");
+
+	/* Release */
+	mapi_object_release(&obj_ref_message);
+	mapi_object_release(&obj_ref_folder);
+	mapi_object_release(&obj_top_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the DeletePropertiesNoReplicate (0x7a) operation
+
+   This function:
+   -# Opens the mailbox
+   -# Create a test folder
+   -# Creates a reference email, and sets some properties on it
+   -# Delete properties from this message
+   -# Checks that properties got deleted
+   -# Deletes both email and the test folder
+
+   \todo It would be useful to test the problem return values
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcprpt_DeletePropertiesNoReplicate(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_top_folder;
+	mapi_id_t		id_top_folder;
+	mapi_object_t		obj_ref_folder;
+	mapi_object_t		obj_ref_message;
+	const char		*name = NULL;
+	const char		*subject = NULL;
+	struct SPropValue	lpProp[3];
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_init(&obj_top_folder);
+	retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
+	retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2: Create reference folder */
+	mapi_object_init(&obj_ref_folder);
+        retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
+                              OPEN_IF_EXISTS, &obj_ref_folder);
+	mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3: Create reference message */
+	mapi_object_init(&obj_ref_message);
+	retval = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
+	mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+        name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
+	subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
+	set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
+	set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
+	retval = SetProps(&obj_ref_message, lpProp, 2);
+	mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
+	if (retval != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4: Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (lpProps[0].value.lpszA) {
+		if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[0].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[0].value.lpszA);
+		}
+	}
+	if (lpProps[1].value.lpszA) {
+		if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
+				       lpProps[1].value.lpszA);
+		} else {
+			mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
+				       lpProps[1].value.lpszA);
+		}
+	}
+
+	/* Step 5. Delete Properties */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
+	retval = DeletePropertiesNoReplicate(&obj_ref_message, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval_step_fmt(mt, "5.", "DeletePropertiesNoReplicate", "PR_CONVERSATION_TOPIC");
+
+	/* Step 6. Double check with GetProps */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
+	retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	if (get_SPropValue(lpProps, PR_CONVERSATION_TOPIC) == NULL) {
+		mapitest_print(mt, "* Step 5.1. - GetProps verifier [SUCCESS]\n");
+	} else {
+		mapitest_print(mt, "* Step 5.1. - GetProps verifier [FAILURE]:\n");
+	}
+
+	/* Step 7: cleanup folders */
+	retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval_step(mt, "6.", "DeleteFolder");
+
+	/* Release */
+	mapi_object_release(&obj_ref_message);
+	mapi_object_release(&obj_ref_folder);
+	mapi_object_release(&obj_top_folder);
+	mapi_object_release(&obj_store);
+
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxcstor.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcstor.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxcstor.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,501 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - STORE OBJECT PROTOCOL operations
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxcstor.c
+
+   \brief Store Object Protocol test suite
+*/
+
+
+/**
+   \details Test the Logon (0xFE) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Log on the public folder store
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_Logon(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_release(&obj_store);
+
+	/* Step 2. Logon Public Folder store */
+	mapi_object_init(&obj_store);
+	retval = OpenPublicFolder(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenPublicFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetReceiveFolder (0x27) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Call the GetReceiveFolder operation
+   
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_GetReceiveFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_id_t		id_inbox;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Step 2. Call the GetReceiveFolder operation */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, "IPF.Post");
+	mapitest_print_retval(mt, "GetReceiveFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the SetReceiveFolder (0x26) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Call the SetReceiveFolder operation
+
+   \param mt the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_SetReceiveFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_id_t		id_inbox;
+	mapi_id_t		id_tis;
+	mapi_object_t		obj_tis;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_folder;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval_step(mt, "1.", "Logon");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Get the original ReceiveFolder */
+	retval = GetReceiveFolder(&obj_store, &id_inbox, NULL);
+	mapitest_print_retval_step(mt, "2.", "GetReceiveFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Open the ReceiveFolder */
+	mapi_object_init(&obj_inbox);
+	retval = OpenFolder(&obj_store, id_inbox, &obj_inbox);
+	mapitest_print_retval_step(mt, "3.", "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 4. Open the Top Information Store folder */
+	retval = GetDefaultFolder(&obj_store, &id_tis, olFolderTopInformationStore);
+	mapitest_print_retval_step(mt, "4.", "GetDefaultFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_tis);
+	retval = OpenFolder(&obj_store, id_tis, &obj_tis);
+	mapitest_print_retval_step(mt, "4.1.", "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Create the New Inbox folder under Top Information Store */
+	mapi_object_init(&obj_folder);
+	retval = CreateFolder(&obj_tis, FOLDER_GENERIC, "New Inbox", NULL,
+			      OPEN_IF_EXISTS, &obj_folder);
+	mapitest_print_retval_step(mt, "5.", "CreateFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Set IPM.Note receive folder to New Inbox */
+	retval = SetReceiveFolder(&obj_store, &obj_folder, "IPM.Note");
+	mapitest_print_retval_step_fmt(mt, "6.", "SetReceiveFolder", "%s", "(New Inbox)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Reset receive folder to Inbox */
+	retval = SetReceiveFolder(&obj_store, &obj_inbox, "IPM.Note");
+	mapitest_print_retval_step(mt, "6.1.", "SetReceiveFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	/* Delete New Inbox folder */
+	retval = EmptyFolder(&obj_folder);
+	mapitest_print_retval_step(mt, "7.", "EmptyFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = DeleteFolder(&obj_tis, mapi_object_get_id(&obj_folder),
+			      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
+	mapitest_print_retval_step(mt, "8.", "DeleteFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_tis);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the GetOwningServers (0x42) operation
+
+   This function:
+   -# Log on the public folders store
+   -# Open a public folder
+   -# Call the GetOwningServers operation
+
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_oxcstor_GetOwningServers(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	uint64_t		folderId;
+	uint16_t		OwningServersCount;
+	uint16_t		CheapServersCount;
+	char			*OwningServers;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenPublicFolder(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenPublicFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Step 2. Open IPM Subtree folder */
+	retval = GetDefaultPublicFolder(&obj_store, &folderId, olFolderPublicIPMSubtree);
+	mapitest_print_retval(mt, "GetDefaultPublicFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, folderId, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3. Call GetOwningServers */
+	retval = GetOwningServers(&obj_store, &obj_folder, &OwningServersCount, &CheapServersCount, &OwningServers);
+	mapitest_print_retval(mt, "GetOwningServers");
+	if (GetLastError() != MAPI_E_SUCCESS && GetLastError() != ecNoReplicaAvailable) {
+		ret = false;
+	} else if (GetLastError() == ecNoReplicaAvailable) {
+		mapitest_print(mt, "* %-35s: No active replica for the folder\n", "GetOwningServers");
+	} else {
+		mapitest_print(mt, "* %-35s: OwningServersCount: %d\n", "PublicFolderIsGhosted", OwningServersCount);
+		if (OwningServersCount) {
+			uint16_t	i;
+			
+			for (i = 0; i < OwningServersCount; i++) {
+				mapitest_print(mt, "* %-35s: OwningServers: %s\n", "GetOwningServers", &OwningServers[i]);
+			}
+			talloc_free(&OwningServers);
+		}
+	}
+
+	/* cleanup objects */
+	mapi_object_release(&obj_folder);
+
+cleanup:
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+/**
+   \details Test the PublicFolderIsGhosted (0x45) operation
+
+   This function:
+   -# Log on the public folders store
+   -# Open a public folder
+   -# Call the PublicFolderIsGhosted operation
+
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+*/
+_PUBLIC_ bool mapitest_oxcstor_PublicFolderIsGhosted(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	uint64_t		folderId;
+	bool			IsGhosted;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenPublicFolder(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenPublicFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	/* Step 2. Open IPM Subtree folder */
+	retval = GetDefaultPublicFolder(&obj_store, &folderId, olFolderPublicIPMSubtree);
+	mapitest_print_retval(mt, "GetDefaultPublicFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, folderId, &obj_folder);
+	mapitest_print_retval(mt, "OpenFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3. Call PublicFolderIsGhosted */
+	retval = PublicFolderIsGhosted(&obj_store, &obj_folder, &IsGhosted);
+	mapitest_print_retval(mt, "PublicFolderIsGhosted");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+	mapitest_print(mt, "* %-35s: IsGhosted is set to %s\n", "PublicFolderIsGhosted", ((IsGhosted) ? "true" : "false"));
+
+	/* cleanup objects */
+	mapi_object_release(&obj_folder);
+
+cleanup:
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the GetReceiveFolderTable (0x68) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Call the GetReceiveFolderTable operation
+   
+   \param mt the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_GetReceiveFolderTable(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct SRowSet		SRowSet;
+	
+ 	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Call the GetReceiveFolderTable operation */
+	retval = GetReceiveFolderTable(&obj_store, &SRowSet);
+	mapitest_print_retval(mt, "GetReceiveFolderTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapidump_SRowSet(&SRowSet, "\t\t[*]");
+	MAPIFreeBuffer(SRowSet.aRow);
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+/**
+   \details Test the LongTermIdFromId (0x43) and IdFromLongTermId (0x44)
+   operations
+
+   This function:
+   -# Logs into the user private mailbox
+   -# Open the Receive Folder
+   -# Looks up the long term id for the receive folder FID
+   -# Looks up the short term id for the long term id
+   -# Checks the id matches the original FID
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_LongTermId(struct mapitest *mt)
+{
+	mapi_object_t		obj_store;
+	mapi_id_t		id_inbox;
+	struct LongTermId	long_term_id;
+	mapi_id_t		id_check;
+	bool			ret = true;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 2. Call the GetReceiveFolder operation */
+	GetReceiveFolder(&obj_store, &id_inbox, "IPF.Post");
+	mapitest_print_retval(mt, "GetReceiveFolder");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3. Call GetLongTermIdFromId on Folder ID */
+	GetLongTermIdFromId(&obj_store, id_inbox, &long_term_id);
+	mapitest_print_retval(mt, "GetLongTermIdFromId");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 4. Call GetIdFromLongTermId on LongTermId from previous step*/
+	GetIdFromLongTermId(&obj_store, long_term_id, &id_check);
+	mapitest_print_retval(mt, "GetIdFromLongTermId");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 5. Check whether ids are the same */
+	if ( id_check == id_inbox ) {
+		mapitest_print(mt, "* Check: IDs match - [SUCCESS]\n" );
+	} else {
+		mapitest_print(mt, "* Check: IDs do not match - [SUCCESS] (0x%x, expected 0x%x)\n",
+			       id_check, id_inbox);
+		ret=false;
+		goto cleanup;
+	}
+
+ cleanup:
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the GetStoreState (0x7b) operation 
+
+   This function:
+   -# Logs into the user private mailbox
+   -# Retrieve the store state
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcstor_GetStoreState(struct mapitest *mt)
+{
+	mapi_object_t  	obj_store;
+	uint32_t       	StoreState = 0;
+	bool	       	ret = true;
+
+	/* Step 1. Logon Private Mailbox */
+	mapi_object_init(&obj_store);
+	OpenMsgStore(mt->session, &obj_store);
+	mapitest_print_retval(mt, "OpenMsgStore");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Get the store state */
+	GetStoreState(&obj_store, &StoreState);
+	mapitest_print_retval(mt, "GetStoreState");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	mapi_object_release(&obj_store);
+	return ret;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxctable.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxctable.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxctable.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,909 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - TABLE OBJECT PROTOCOL operations
+
+   Copyright (C) Julien Kerihuel 2008
+   Copyright (C) Brad Hards 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/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxctable.c
+
+   \brief Table Object Protocol test suite
+*/
+
+/**
+   \details Test the SetColumns (0x12) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# Calls the SetColumns operation
+   -# Cleans up
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_SetColumns(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* Step 2. SetColumns */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval(mt, "SetColumns");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	return true;
+}
+
+
+/**
+   \details Test the QueryColumns (0x37) operation
+
+   This function:
+   	-# Opens the Inbox folder and gets the hierarchy table
+	-# Calls the QueryColumn operation
+	-# Calls SetColumns on the test folder
+	-# Checks that QueryColumns on the test folder is correct
+	-# Cleans up
+
+   \param mt pointer to the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_QueryColumns(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	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;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* Step 2. QueryColumns */
+	retval = QueryColumns(&obj_htable, &columns);
+	mapitest_print_retval(mt, "QueryColumns");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Get the test folder */
+	context = mt->priv;
+	mapi_object_init(&(obj_test_folder));
+	GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count);
+	mapitest_print_retval(mt, "GetContentsTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	if (count != 10) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count);
+		/* This isn't a hard error for this test though, because it might be from a 
+		   previous test failure. Clean up and try again */
+	}
+
+
+	/* 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 */
+	retval = QueryColumns(&(obj_test_folder), &columns);
+	mapitest_print_retval(mt, "QueryColumns");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	/* TODO: check the return count against something */
+	mapitest_print(mt, "column count: %i\n", columns.cValues);
+
+	/* Step 6. Release */
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&(obj_test_folder));
+	mapitest_common_cleanup(mt);
+
+	return true;
+}
+
+/**
+   \details Test the Restrict (0x14) operation
+
+   This function:
+   -# Opens the Inbox folder and creates some test content
+   -# Checks that the content is OK
+   -# Applies a filter
+   -# Checks the results are as expected.
+   -# Resets the table
+   -# Checks the results are as expected.
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_Restrict(struct mapitest *mt)
+{
+	mapi_object_t		obj_htable;
+	mapi_object_t		obj_test_folder;
+	struct mt_common_tf_ctx	*context;
+	uint32_t		count = 0;
+	uint32_t		origcount = 0;
+	uint32_t		Numerator = 0;
+	uint32_t		Denominator = 0;
+	struct mapi_SRestriction res;
+	bool			ret = true;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
+		return false;
+	}
+
+	/* Step 2. Get the test folder */
+	context = mt->priv;
+	mapi_object_init(&(obj_test_folder));
+	GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "GetContentsTable");
+		ret = false;
+		goto cleanup;
+	}
+	if (origcount != 10) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count);
+		/* This isn't a hard error for this test though, because it might be from a 
+		   previous test failure. Clean up and try again */
+	}
+
+	/* Apply a filter */
+	res.rt = RES_PROPERTY;
+	res.res.resProperty.relop = RES_PROPERTY;
+	res.res.resProperty.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT;
+	res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT;
+
+	Restrict(&(obj_test_folder), &res, NULL);
+	mapitest_print_retval(mt, "Restrict");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	context = mt->priv;
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "QueryPosition");
+		ret = false;
+		goto cleanup;
+	}
+	if (Denominator != origcount/2) {
+		mapitest_print(mt, "* %-35s: unexpected filtered count (%i)\n", "QueryPosition", Denominator);
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Resets the table */
+	Reset(&(obj_test_folder));
+	mapitest_print_retval(mt, "Reset");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	context = mt->priv;
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "QueryPosition");
+		ret = false;
+		goto cleanup;
+	}
+	if (Denominator != origcount) {
+		mapitest_print(mt, "* %-35s: unexpected reset count (%i)\n", "QueryPosition", Denominator);
+		ret = false;
+		goto cleanup;
+	}
+
+ cleanup:
+	/* Release */
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&(obj_test_folder));
+	mapitest_common_cleanup(mt);
+
+	return ret;
+}
+
+/**
+   \details Test the QueryRows (0x15) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# Set the required columns
+   -# Calls QueryRows until the end of the table
+   -# Open the test folder, and get its contents
+   -# Calls QueryRows until the end of the test folder
+   -# Checks the results are as expected.
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_QueryRows(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	mapi_object_t		obj_test_folder;
+	struct SRowSet		SRowSet;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	lpProp;
+	struct mt_common_tf_ctx	*context;
+	uint32_t		idx = 0;
+	uint32_t		count = 0;
+	const char*		data;
+	int			i;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
+		return false;
+	}
+
+	/* Step 2. Set Table Columns */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "SetColumns");
+		return false;
+	}
+
+	/* Step 3. QueryRows */
+	do {
+		retval = QueryRows(&obj_htable, 0x2, TBL_ADVANCE, &SRowSet);
+		if (SRowSet.cRows > 0) {
+			idx += SRowSet.cRows;
+			if (retval == MAPI_E_SUCCESS) {
+				mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", 
+					       "QueryRows", idx, count);
+			} else {
+				mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", 
+					       "QueryRows", idx, count);
+			}
+		}
+	} while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0);
+
+
+	/* Step 4. Get the test folder */
+	context = mt->priv;
+	mapi_object_init(&(obj_test_folder));
+	GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &count);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "GetContentsTable");
+		return false;
+	}
+	if (count != 10) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count);
+		/* This isn't a hard error for this test though, because it might be from a 
+		   previous test failure. Clean up and try again */
+	}
+
+	/* Step 5. Set Table Columns on the test folder */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_BODY, PR_BODY_HTML);
+	retval = SetColumns(&obj_test_folder, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "SetColumns");
+		return false;
+	}
+
+	/* Step 6. QueryRows on test folder contents */
+	idx = 0;
+	do {
+		retval = QueryRows(&(obj_test_folder), 0x2, TBL_ADVANCE, &SRowSet);
+		if (SRowSet.cRows > 0) {
+			idx += SRowSet.cRows;
+			if (retval == MAPI_E_SUCCESS) {
+				mapitest_print(mt, "* %-35s: %.2d/%.2d [PASSED]\n", 
+					       "QueryRows", idx, count);
+				for (i = 0; i < SRowSet.cRows; ++i) {
+					lpProp = SRowSet.aRow[i].lpProps[0];
+					if (lpProp.ulPropTag != PR_BODY) {
+						mapitest_print(mt, "* %-35s: Bad proptag0 (0x%x)\n", 
+							       "QueryRows", lpProp.ulPropTag);
+						return false;
+					}
+					data = get_SPropValue_data(&lpProp);
+					if (0 != strncmp(data, "Body of message", 15)) {
+						mapitest_print(mt, "* %-35s: Bad propval0 (%s)\n", 
+							       "QueryRows", data);
+						return false;
+					}
+					lpProp = SRowSet.aRow[i].lpProps[1];
+					if (lpProp.ulPropTag != PR_BODY_HTML) {
+						mapitest_print(mt, "* %-35s: Bad proptag1 (0x%x)\n", 
+							       "QueryRows", lpProp.ulPropTag);
+						return false;
+					}
+					data = get_SPropValue_data(&lpProp);
+					if (0 != strncmp(data, "<!DOCTYPE HTML PUBLIC", 21)) {
+						mapitest_print(mt, "* %-35s: Bad propval1 (%s)\n", 
+							       "QueryRows", data);
+						return false;
+					}
+				}
+			} else {
+				mapitest_print(mt, "* %-35s: %.2d/%.2d [FAILED]\n", 
+					       "QueryRows", idx, count);
+			}
+		}
+	} while (retval == MAPI_E_SUCCESS && SRowSet.cRows > 0);
+
+	/* Release */
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&(obj_test_folder));
+	mapitest_common_cleanup(mt);
+
+	return true;
+}
+
+/**
+   \details Test the GetStatus (0x16) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# Call GetStatus
+   -# Cleans up
+ */
+_PUBLIC_ bool mapitest_oxctable_GetStatus(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_htable;
+	uint8_t			TableStatus;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* 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;
+	}
+
+	/* Step 3. Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	return ret;
+}
+
+
+/**
+   \details Test the SeekRow (0x18) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# SeekRow with BOOKMARK_BEGINNING
+   -# SeekRow with BOOKMARK_END
+   -# SeekRow with BOOKMARK_CURRENT
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_SeekRow(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	uint32_t		count;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* Step 2. SeekRow */
+	retval = SeekRow(&obj_htable, BOOKMARK_BEGINNING, 0, &count);
+	mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_BEGINNING)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = SeekRow(&obj_htable, BOOKMARK_END, 0, &count);
+	mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_END)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = SeekRow(&obj_htable, BOOKMARK_CURRENT, 0, &count);
+	mapitest_print_retval_fmt(mt, "SeekRow", "(BOOKMARK_CURRENT)");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	return true;
+}
+
+
+/**
+   \details Test the SeekRowApprox (0x1a) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# SeekRowApprox with 0/1, 1/1 and 1/2 fractional values
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_SeekRowApprox(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+		return false;
+	}
+
+	/* Step 2. SeekRowApprox */
+	retval = SeekRowApprox(&obj_htable, 0, 1);
+	mapitest_print_retval_fmt(mt, "SeekRowApprox", "0/1");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = SeekRowApprox(&obj_htable, 1, 1);
+	mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/1");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	retval = SeekRowApprox(&obj_htable, 1, 2);
+	mapitest_print_retval_fmt(mt, "SeekRowApprox", "1/2");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	return true;
+}
+
+
+
+/**
+   \details Test the CreateBookmark (0x1b) operation
+
+   This function:
+   -# Opens the Inbox folder and gets the hierarchy table
+   -# Customize the MAPI table view
+   -# CreateBookmark for each table's row
+   -# Free Bookmark for each created bookmark
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_CreateBookmark(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	uint32_t		*bkPosition;
+	uint32_t		count;
+	uint32_t		i;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
+		return false;
+	}
+
+	/* Step 2. Customize the table view */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create Bookmarks */
+	bkPosition = talloc_array(mt->mem_ctx, uint32_t, 1);
+	while (((retval = QueryRows(&obj_htable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
+	       SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			bkPosition = talloc_realloc(mt->mem_ctx, bkPosition, uint32_t, i + 2);
+			retval = CreateBookmark(&obj_htable, &(bkPosition[i]));
+			mapitest_print_retval_fmt(mt, "CreateBookmark", "(%.2d)", i);
+			if (GetLastError() != MAPI_E_SUCCESS) {
+				return false;
+			}
+		}
+	}
+
+	retval = mapi_object_bookmark_get_count(&obj_htable, &count);
+
+	/* Step 4. Free Bookmarks */
+	for (i = 0; i < count; i++) {
+		retval = FreeBookmark(&obj_htable, bkPosition[i]);
+		mapitest_print_retval_fmt(mt, "FreeBookmark", "(%.2d)", i);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			return false;
+		}
+	}
+
+	/* Step 5. Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+	talloc_free(bkPosition);
+
+	return true;
+}
+
+
+
+/**
+   \details Test the SeekRowBookmark (0x19) operation
+
+   This function:
+   -# Open the Inbox folder and retrieve the hierarchy table
+   -# Customize the MAPI table view
+   -# SeekBookmark for each table's row
+   -# Free Bookmark for each created bookmark
+
+   \param mt pointer on the top-level mapitest structure
+   
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_SeekRowBookmark(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	uint32_t		*bkPosition;
+	uint32_t		count;
+	uint32_t		row;
+	uint32_t		i;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
+		return false;
+	}
+
+	/* Step 2. Customize the table view */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create Bookmarks */
+	bkPosition = talloc_array(mt->mem_ctx, uint32_t, 1);
+	while (((retval = QueryRows(&obj_htable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
+	       SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			bkPosition = talloc_realloc(mt->mem_ctx, bkPosition, uint32_t, i + 2);
+			retval = CreateBookmark(&obj_htable, &(bkPosition[i]));
+			if (GetLastError() != MAPI_E_SUCCESS) {
+				return false;
+			}
+		}
+	}
+	mapitest_print_retval(mt, "CreateBookmark");
+
+	retval = mapi_object_bookmark_get_count(&obj_htable, &count);
+
+	/* Step 4. SeekRowBookmark */
+	for (i = 0; i < count; i++) {
+		retval = SeekRowBookmark(&obj_htable, bkPosition[i], 0, &row);
+		mapitest_print_retval_fmt(mt, "SeekRowBookmark", "(%.2d)", i);
+	}
+
+
+	/* Step 5. Free Bookmarks */
+	for (i = 0; i < count; i++) {
+		retval = FreeBookmark(&obj_htable, bkPosition[i]);
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			return false;
+		}
+	}
+	mapitest_print_retval(mt, "FreeBookmark");
+
+	/* Step 6. Release */
+	mapi_object_release(&obj_htable);
+	mapitest_common_cleanup(mt);
+
+	talloc_free(bkPosition);
+
+	return true;
+}
+
+/**
+   \details Test the SortTable (0x13), ExpandRow (0x59), CollapseRow(0x5a),
+   GetCollapseState(0x6b) and SetCollapseState (0x6c) operations
+
+   This function:
+   -# Opens the Inbox folder and creates some test content
+   -# Checks that the content is OK
+   -# Applies a sort and categorisation
+   -# Checks the results are as expected.
+   -# Save away the Row ID and Insatnce Number for the first header
+   -# Collapse the first category
+   -# Checks the results are as expected.
+   -# Save the "collapse state"
+   -# Expand the first category again
+   -# Checks the results are as expected
+   -# Restore the saved "collapse state"
+   -# Checks the results are as expected
+   -# Cleans up
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxctable_Category(struct mapitest *mt)
+{
+	mapi_object_t		obj_htable;
+	mapi_object_t		obj_test_folder;
+	struct mt_common_tf_ctx	*context;
+	uint32_t		count = 0;
+	uint32_t		origcount = 0;
+	bool			ret = true;
+	struct SSortOrderSet	criteria;
+	uint64_t		inst_id = 0;
+	uint64_t		inst_num = 0;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t                rowcount = 0;
+	uint32_t		Numerator = 0;
+	uint32_t		Denominator = 0;
+	struct SBinary_short	collapseState;
+	uint32_t		bookmark;
+
+
+	/* Step 1. Logon */
+	if (! mapitest_common_setup(mt, &obj_htable, &count)) {
+		return false;
+	}
+
+	/* Step 2. Get the test folder */
+	context = mt->priv;
+	mapi_object_init(&(obj_test_folder));
+	GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, &origcount);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		mapitest_print_retval(mt, "GetContentsTable");
+		ret = false;
+		goto cleanup;
+	}
+	if (origcount != 10) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "GetContentsTable", count);
+		/* This isn't a hard error for this test though, because it might be from a 
+		   previous test failure. Clean up and try again */
+	}
+
+	/* We need the header row InstanceId to fold/unfold the headers */
+	SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x6,
+					  PR_SENDER_NAME,
+					  PR_BODY,
+					  PR_LAST_MODIFICATION_TIME,
+					  PR_SUBJECT,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM);
+	SetColumns(&(obj_test_folder), SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	mapitest_print_retval(mt, "SetColumns");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Apply a categorised sort */
+	memset(&criteria, 0x0, sizeof (struct SSortOrderSet));
+	criteria.cSorts = 1;
+	criteria.cCategories = 1;
+	criteria.cExpanded = 1;
+	criteria.aSort = talloc_array(mt->mem_ctx, struct SSortOrder, criteria.cSorts);
+	criteria.aSort[0].ulPropTag = PR_SENDER_NAME;
+	criteria.aSort[0].ulOrder = TABLE_SORT_ASCEND;
+	SortTable(&(obj_test_folder), &criteria);
+	mapitest_print_retval(mt, "SortTable");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	rowcount =  2 * origcount;
+	QueryRows(&(obj_test_folder), rowcount, TBL_ADVANCE, &SRowSet);
+	mapitest_print_retval(mt, "QueryRows");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	mapitest_print_retval(mt, "QueryPosition");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	/* the categories are expanded, and there are six unique senders, so there are six
+	   extra rows - one for each header row */
+	if (Denominator != origcount + 6) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Numerator);
+		ret = false;
+		goto cleanup;
+	}
+
+	/* save away ID/instance values for first row header */
+	inst_id = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[4])));
+	inst_num = (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[0].lpProps[5])));
+
+	/* Collapse a row header */
+	CollapseRow(&(obj_test_folder), inst_id, &rowcount);
+	mapitest_print_retval(mt, "CollapseRow");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	mapitest_print_retval(mt, "QueryPosition");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	/* there are still six unique headers, but half of the real entries are under the first
+	   header (usually 10, unless we have some other rubbish hanging around), and when we
+	   collapse the first header row, that half disappear */
+	if (Denominator != origcount/2 + 6) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator);
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Save the table collapse state */
+	GetCollapseState(&(obj_test_folder), inst_id, inst_num, &collapseState);
+	mapitest_print_retval(mt, "GetCollapseState");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+
+	/* Expand a category */
+	ExpandRow(&(obj_test_folder), inst_id, 20, &SRowSet, &rowcount);
+	mapitest_print_retval(mt, "ExpandRow");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	mapitest_print_retval(mt, "QueryPosition");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	/* we've expanded the first header row, so we now get all the entries plus the 6 headers */
+	if (Denominator != origcount + 6) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator);
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Restore the collapse state  */
+	SetCollapseState(&(obj_test_folder), &collapseState, &bookmark);
+	mapitest_print_retval(mt, "SetCollapseState");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Checks the results are as expected */
+	QueryPosition(&(obj_test_folder), &Numerator, &Denominator);
+	mapitest_print_retval(mt, "QueryPosition");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+	/* back to the situation with the first heading collapsed */
+	if (Denominator != origcount/2 + 6) {
+		mapitest_print(mt, "* %-35s: unexpected count (%i)\n", "QueryPosition", Denominator);
+		ret = false;
+		goto cleanup;
+	}
+
+ cleanup:
+	if (bookmark) {
+		FreeBookmark(&(obj_test_folder), bookmark);
+		mapitest_print_retval(mt, "FreeBookmark");
+		if (GetLastError() != MAPI_E_SUCCESS) {
+			ret = false;
+		}
+	}
+
+	/* Release */
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&(obj_test_folder));
+	mapitest_common_cleanup(mt);
+
+	return ret;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxomsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxomsg.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxomsg.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,507 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - E-MAIL OBJECT PROTOCOL operations
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxomsg.c
+
+   \brief E-Mail Object Protocol test suite
+*/
+
+
+/**
+   \details Test the AddressTypes (0x49) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Call the AddressTypes operation
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_AddressTypes(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	uint16_t		cValues;
+	struct mapi_LPSTR	*transport = NULL;
+	uint32_t		i;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step2. AddressTypes operation */
+	retval = AddressTypes(&obj_store, &cValues, &transport);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+	
+	for (i = 0; i < cValues; i++) {
+		mapitest_print(mt, "* Recipient Type: %s\n", transport[i].lppszA);
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the SubmitMessage (0x32) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the Outbox folder
+   -# Create a sample message
+   -# Submit the message
+   -# Delete the message
+   -# Clean up folders
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_SubmitMessage(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+	bool			ret;
+	
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Create the sample message */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+	if (ret == false) {
+		return ret;
+	}
+
+	/* Step 4. Submit Message */
+	retval = SubmitMessage(&obj_message);
+	mapitest_print_retval(mt, "SubmitMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 5. Delete Message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 6. Clean up anything else */
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+	GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the AbortSubmit (0x34) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Open the Outbox folder
+   -# Create a sample message
+   -# Submit the message
+   -# Abort the submit operation
+   -# Delete the message
+   -# Clean up folders
+	
+   Note: This operation may fail since it depends on how busy the
+   server is when we submit the message. It is possible the message
+   gets already processed before we have time to abort the message.
+
+   From preliminary tests, AbortSubmit returns MAPI_E_SUCCESS when we
+   call SubmitMessage with SubmitFlags set to 0x2.
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_AbortSubmit(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_folder;
+	mapi_id_t		id_msgs[1];
+	bool			ret = true;
+	
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 2. Open Outbox folder */
+	retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 3. Create the sample message */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+	if (ret == false) {
+		goto cleanup;
+	}
+
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 4. Submit Message */
+	retval = SubmitMessage(&obj_message);
+	retval = AbortSubmit(&obj_store, &obj_folder, &obj_message);
+	mapitest_print_retval(mt, "AbortSubmit");
+	if ((GetLastError() != MAPI_E_SUCCESS) && 
+	    (GetLastError() != MAPI_E_UNABLE_TO_ABORT) &&
+	    (GetLastError() != MAPI_E_NOT_IN_QUEUE)) {
+		ret = false;
+	}
+
+	/* Step 5. Delete Message */
+cleanup:
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+	if ((retval != MAPI_E_SUCCESS) && (GetLastError() != ecNoDelSubmitMsg)) {
+		ret = false;
+	}
+	/* Step 6. Clean up anything else */
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+	GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the SetSpooler (0x47) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Informs the server it will acts as an email spooler
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_SetSpooler(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. SetSpooler */
+	retval = SetSpooler(&obj_store);
+	mapitest_print_retval(mt, "SetSpooler");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Release */
+	mapi_object_release(&obj_store);
+
+	return true;
+}
+
+
+/**
+   \details Test the SpoolerLockMessage (0x48) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Informs the server it will acts as an email spooler
+   -# Create a message in the outbox folder
+   -# Save message changes and Submit the message
+   -# Lock the message
+   -# Unlock-Finish the message
+   -# Deletes the message
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_SpoolerLockMessage(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_msgs[1];
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. SetSpooler */
+	retval = SetSpooler(&obj_store);
+	mapitest_print_retval(mt, "SetSpooler");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 3. Open the outbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
+	if (ret == false) return ret;
+
+	/* Step 4. Create the message */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+	mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_message_create", 
+		       ret == true ? "TRUE" : "FALSE");
+	if (ret == false) return ret;
+
+	/* Step 5. Save changes on message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 6. Submit the message */
+	retval = SubmitMessage(&obj_message);
+	mapitest_print_retval(mt, "SubmitMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 7. Lock the message */
+	retval = SpoolerLockMessage(&obj_store, &obj_message, LockState_1stLock);
+	mapitest_print_retval_fmt(mt, "SpoolerLockMessage", "1stLock");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 8. finish locking the message */
+	retval = SpoolerLockMessage(&obj_store, &obj_message, LockState_1stFinished);
+	mapitest_print_retval_fmt(mt, "SpoolerLockMessage", "1stFinished");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 9. Delete Message */
+	id_msgs[0] = mapi_object_get_id(&obj_message);
+	retval = DeleteMessage(&obj_folder, id_msgs, 1);
+	mapitest_print_retval(mt, "DeleteMessage");
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the TransportSend (0x4a) operation
+
+   This function:
+   -# Logs on to the user private mailbox
+   -# Opens the outbox folder
+   -# Create the test message
+   -# Save changes to the message
+   -# Perform the TransportSend operation
+   -# Dump the properties
+   -# Clean up folders
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_TransportSend(struct mapitest *mt)
+{
+	enum MAPISTATUS			retval;
+	bool				ret = true;
+	mapi_object_t			obj_store;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_message;
+	struct mapi_SPropValue_array	lpProps;
+	mapi_id_t			id_folder;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	/* Step 2. Open the outbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
+	if (ret == false) return ret;
+
+	/* Step 3. Create the message */
+	mapi_object_init(&obj_message);
+	ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+	mapitest_print(mt, "* %-35s: %s\n", "mapitest_common_message_create", 
+		       ret == true ? "TRUE" : "FALSE");
+	if (ret == false) return ret;
+
+	/* Step 4. Save changes on message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
+	mapitest_print_retval(mt, "SaveChangesMessage");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 5. TransportSend */
+	retval = TransportSend(&obj_message, &lpProps);
+	mapitest_print_retval(mt, "TransportSend");
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		ret = false;
+	}
+
+	/* Step 6. Dump the properties */
+	if (&lpProps != NULL) {
+		uint32_t		i;
+		struct SPropValue	lpProp;
+
+		for (i = 0; i < lpProps.cValues; i++) {
+			cast_SPropValue(&lpProps.lpProps[i], &lpProp);
+			mapidump_SPropValue(lpProp, "\t* ");
+		}
+		MAPIFreeBuffer(lpProps.lpProps);
+	}
+
+	/* Step 6. Clean up anything else */
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+	GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+	OpenFolder(&obj_store, id_folder, &obj_folder);
+	mapitest_common_message_delete_by_subject(mt, &obj_folder, MT_MAIL_SUBJECT);
+
+	/* Release */
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}
+
+
+/**
+   \details Test the GetTransportFolder (0x6d) operation
+
+   This function:
+   -# Log on the user private mailbox
+   -# Retrieves the folder ID of temporary transport folder
+
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_GetTransportFolder(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	mapi_id_t		folder_id;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_object_release(&obj_store);
+		return false;
+	}
+
+	/* Step 2. Get the transport folder */
+	retval = GetTransportFolder(&obj_store, &folder_id);
+	mapitest_print_retval_fmt(mt, "GetTransportFolder", "(0x%llx)", folder_id);
+	if (GetLastError() != MAPI_E_SUCCESS) {
+		return false;
+	}
+
+	return true;
+}

Added: trunk/openchange/utils/mapitest/modules/module_oxorule.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxorule.c	                        (rev 0)
+++ trunk/openchange/utils/mapitest/modules/module_oxorule.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,84 @@
+/*
+   Stand-alone MAPI testsuite
+
+   OpenChange Project - E-MAIL RULES PROTOCOL operations
+
+   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 <libmapi/libmapi.h>
+#include "utils/mapitest/mapitest.h"
+#include "utils/mapitest/proto.h"
+
+/**
+   \file module_oxorule.c
+
+   \brief E-Mail Rules Protocol test suite
+ */
+
+
+/**
+   \details Test the GetRulesTable (0x3f) operation
+
+   This function:
+	-# Log on the user private mailbox
+	-# Open the inbox folder
+	-# Retrieve the rules table
+   
+   \param mt pointer on the top-level mapitest structure
+
+   \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxorule_GetRulesTable(struct mapitest *mt)
+{
+	enum MAPISTATUS		retval;
+	bool			ret = true;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_rtable;
+
+	/* Step 1. Logon */
+	mapi_object_init(&obj_store);
+	retval = OpenMsgStore(mt->session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+	/* Step 2. Open the Inbox folder */
+	mapi_object_init(&obj_folder);
+	ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox);
+	if (ret == false) {
+		goto cleanup;
+	}
+
+	/* Step 3. Retrieve the rules table */
+	mapi_object_init(&obj_rtable);
+	retval = GetRulesTable(&obj_folder, &obj_rtable, RulesTableFlags_Unicode);
+	mapitest_print_retval(mt, "GetRulesTable");
+	if (retval != MAPI_E_SUCCESS) {
+		ret = false;
+		goto cleanup;
+	}
+
+ cleanup:
+	/* Release */
+	mapi_object_release(&obj_rtable);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_store);
+
+	return ret;
+}

Added: trunk/openchange/utils/mapitrace/Makefile.PL
===================================================================
--- trunk/openchange/utils/mapitrace/Makefile.PL	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/Makefile.PL	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,6 @@
+use ExtUtils::MakeMaker;
+WriteMakefile(
+	      'NAME' => 'MAPI::Mapitrace',
+	      'VERSION_FROM' => 'lib/MAPI/EcDoRpc.pm',
+	      'EXE_FILES' => [ 'mapitrace' ],
+	      );

Added: trunk/openchange/utils/mapitrace/lib/MAPI/Dump_EcDoRpc.pm
===================================================================
--- trunk/openchange/utils/mapitrace/lib/MAPI/Dump_EcDoRpc.pm	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/lib/MAPI/Dump_EcDoRpc.pm	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,201 @@
+#############################################
+# EcDoRpc Dump utility for mapitrace tool
+# Copyright Julien Kerihuel 2007
+# <j.kerihuel at openchange.org>
+#
+# released under the GNU GPL v3 or later
+#
+package MAPI::Dump_EcDoRpc;
+
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw();
+use vars qw($AUTOLOAD $VERSION);
+$VERSION = '0.01';
+
+use strict;
+use Data::Dumper;
+
+#######################################################
+# convenient sort functions                           #
+#######################################################
+sub pkt_number 
+{
+    my ($aa) = $a =~ /(\d+)/;
+    my($bb) = $b =~ /(\d+)/;
+    ($aa) <=> ($bb);
+}
+
+sub asc_num {
+   hex($a) <=> hex($b);
+}
+#######################################################
+# BRACE DUMPING FUNCTIONS
+#######################################################
+
+sub dump_error_brace
+{
+    my $_self = shift;
+    my $self = shift;
+
+    foreach my $key (sort asc_num (keys(%{$self->{BRACES_ERROR}}))) {
+	my $inout = $self->{BRACES_ERROR}->{$key}->{error};
+	if ($inout) {
+	    print "[mapitrace] error in [$inout]: ";
+	    print $self->{BRACES_ERROR}->{$key}->{$inout}->{filename} . "\n";
+	}
+    }
+}
+
+sub dump_brace_start
+{
+    my $_self = shift;
+    my $in = shift;
+    my $out = shift;
+
+    print MAPI::EcDoRpc->get_filename($in->{filename});
+    print " / ";
+    print MAPI::EcDoRpc->get_filename($out->{filename});
+    print "\n";
+    print "----------------------------------------------\n";
+}
+
+sub dump_brace_end
+{
+    print "\n\n";
+}
+
+#######################################################
+# DUMP FUNCTIONS FOR THE ANALYZE PART
+#######################################################
+
+#
+# Dump the handles array from a request or response
+#
+sub dump_handles
+{
+    my $_self = shift;
+    my $self = shift;
+    my @handles = @_;
+
+    print $self->{filename} . " :\n";
+    print "handles array (" . ($#handles + 1) . "):\n";
+    print "\t$_\n" foreach (@handles);
+    print "\n";
+}
+
+#
+# Provides a dual dump view for the handle array
+# both in request and response
+#
+# MAPI Semantic tells that request and response have the same
+# number of handles elements
+#
+sub dump_brace_handles
+{
+    my $_self = shift;
+    my $mapi_call = shift;
+
+    my @handles_in = @{$mapi_call->{handles_in}};
+    my @handles_out = @{$mapi_call->{handles_out}};
+
+    print "handles array (" . ($#handles_in + 1) . "):\n";
+    for (my $i = 0; $handles_in[$i]; $i++) {
+	printf "\t[%.2x] %s -> %s\n", $i, $handles_in[$i], $handles_out[$i];
+    }
+}
+
+#
+# Print a call
+#
+#
+sub dump_call
+{
+    my $mapi_call = shift;
+    my $key = shift;
+    my $call_idx = shift;
+    my $space = shift;
+
+    my $in  = $mapi_call->{calls}->{REQ};
+    my $out = $mapi_call->{calls}->{REPL};
+
+    my $new_idx;
+    
+    if ($call_idx) {
+	$new_idx = MAPI::EcDoRpc->get_call_index($mapi_call, $call_idx);
+	printf "\t%s+-- [0x%.2x] [%s] (opnum = %s) %15s (handle_idx = %s) (child of %s)\n", 
+	$space, hex($call_idx), 
+	(exists $out->{$new_idx}->{retval}) ? $out->{$new_idx}->{retval}:'',
+	$in->{$call_idx}->{opnum}, $in->{$call_idx}->{opname}, 
+	$in->{$call_idx}->{handle_idx}, $in->{$key}->{opname};
+    } else {
+	$new_idx = MAPI::EcDoRpc->get_call_index($mapi_call, $key);
+	printf "\t[0x%.2x] [%s] (opnum = %s) %25s (handle_idx = %s) (self_handle_idx = %s)\n", 
+	hex($key), 
+	(exists $out->{$new_idx}->{retval}) ? $out->{$new_idx}->{retval} : '', 
+	$in->{$key}->{opnum}, $in->{$key}->{opname}, 
+	$in->{$key}->{handle_idx},
+	$in->{$key}->{self_handle_idx};
+    }
+}
+
+#
+# Dump mapi calls
+#
+# Since calls with self_handles have a smaller index than other calls relying on them
+# When a parent value is > than the current idx, we can skip display the call.
+# It should have normally been printing earlier when checking for call children
+# Return -1 if we have an error
+#
+
+sub dump_mapi_calls
+{
+    my $_self = shift;
+    my $mapi_call = shift;
+
+    my $in  = $mapi_call->{calls}->{REQ};
+    my $out = $mapi_call->{calls}->{REPL};
+
+    my $in_call_count = MAPI::EcDoRpc->get_mapi_calls_request_count($in);
+
+    if ($in_call_count != keys(%{$out})) {
+	print "[mapitrace] error: Oops seems like we have some trouble ...\n";
+	print "[mapitrace] error: Mismatch call count between request ($in_call_count) and response (". keys(%{$out})  .")\n";
+	return -1;
+    }
+    
+    printf "serialized mapi calls (count = %.2d):\n", $in_call_count;
+    foreach my $key (sort asc_num (keys(%{$in}))) {
+	if ($in->{$key}->{self_handle_idx}) {
+	    # If this self_handle call has a child ;p
+	    my $space = "  ";
+	    if (exists $in->{$key}->{parent}) {
+		$space .= "       ";
+	    } else {
+		dump_call($mapi_call, $key, 0, 0);
+	    }
+	    # Check if the call with self_handle_idx has children
+	    # The dump will fail if we have Release call.
+	    # In order to avoid this problem we use out instead
+	    
+	    if ($in->{$key}->{children}) {
+		foreach my $call_idx (sort asc_num @{$in->{$key}->{children}}) {
+		    dump_call($mapi_call, $key, $call_idx, $space);
+		}
+	    }
+	}
+	else {
+	    if (exists $in->{$key}->{parent} && hex($in->{$key}->{parent}) < hex($key)) {
+	    } else {
+		printf "\t[0x%.2x] [%s] (opnum = %s) %25s (handle_idx = %s)\n", 
+		hex($key),
+		(exists $out->{$key}->{retval}) ? $out->{$key}->{retval}: '', 
+		$in->{$key}->{opnum}, $in->{$key}->{opname}, $in->{$key}->{handle_idx};	    
+	    }
+	}
+    }
+    print "\n";
+    return 0;
+}
+
+1;

Added: trunk/openchange/utils/mapitrace/lib/MAPI/EcDoRpc.pm
===================================================================
--- trunk/openchange/utils/mapitrace/lib/MAPI/EcDoRpc.pm	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/lib/MAPI/EcDoRpc.pm	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,797 @@
+#############################################
+# EcDoRpc package for mapitrace tool
+# Copyright Julien Kerihuel 2007
+# <j.kerihuel at openchange.org>
+#
+# released under the GNU GPL v3 or later
+#
+package MAPI::EcDoRpc;
+
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw();
+use vars qw($AUTOLOAD $VERSION);
+$VERSION = '0.03';
+
+use strict;
+use File::Basename;
+use MAPI::Dump_EcDoRpc;
+use MAPI::Graph;
+use MAPI::Regression;
+use MAPI::Statistic;
+
+use Data::Dumper;
+
+#######################################################
+# CONVENIENT SORT FUNCTIONS
+#######################################################
+sub pkt_number 
+{
+    my ($aa) = $a =~ /(\d+)/;
+    my($bb) = $b =~ /(\d+)/;
+    ($aa) <=> ($bb);
+}
+
+sub asc_num {
+   hex($a) <=> hex($b);
+}
+
+sub sort_packets
+{
+    my $garbage = 0;
+
+    my @file1 = split(/\_/, get_filename($garbage, $a));
+    my @file2 = split(/\_/, get_filename($garbage, $b));
+
+    hex($file1[0]) <=> hex($file2[0]);
+}
+
+#######################################################
+# CONVENIENT GET FUNCTIONS
+#######################################################
+
+#
+# Dump the filename from a pathname
+#
+sub get_filename
+{
+    my $_self = shift;
+    my $pathname = shift;
+
+    my @parts = split(/\//, $pathname);
+    return $parts[$#parts];
+}
+
+
+
+#######################################################
+# INIT PART
+#######################################################
+
+#
+# index packets by ascending numeric order
+# brace packets {in,out}
+# ndrdump files in the output field
+#
+
+sub new
+{
+    my $_self = shift;
+    my $path = shift;
+    my $outputdir = shift;
+    my $verbose = shift;
+    my $counter = -1;
+
+    my $self = {};
+    $self->{CONF} = {};
+    $self->{CONF}->{stdout} = 1;
+    $self->{CONF}->{outputdir} = $outputdir;
+    $self->{CONF}->{path} = $path;
+    $self->{CONF}->{verbose} = $verbose;
+    $self->{CONF}->{name} = $_self->get_filename($path);
+
+    $self->{ECDORPC} = {};
+    $self->{ECDORPC}->{braces_count} = 0;
+    $self->{ECDORPC}->{braces} = {};
+    
+    $self->{ECDORPC_ERROR} = {};
+    $self->{ECDORPC_ERROR}->{in} = {};
+    $self->{ECDORPC_ERROR}->{out} = {};
+
+    ############# Should disappear ################
+    $self->{BRACES_ERROR} = {};
+    $self->{SKIPPED_FILES} = {};
+
+    $self->{SKIPPED_FILES}->{REQ} = {};
+    $self->{SKIPPED_FILES}->{REQ}->{count} = 0;
+    $self->{SKIPPED_FILES}->{REQ}->{files} = {};
+
+    $self->{SKIPPED_FILES}->{REPL} = {};
+    $self->{SKIPPED_FILES}->{REPL}->{count} = 0;
+    $self->{SKIPPED_FILES}->{REPL}->{files} = {};
+    ############# /Should disappear ################
+
+    my @files =  <$path/*_Mapi_EcDoRpc>;
+    my @ndrdump_files = sort sort_packets @files;
+
+    $self->{STATISTIC} = MAPI::Statistic->new($_self->get_filename($path), @ndrdump_files);
+
+    my $in_filename = 0;
+    my $out_filename = 0;
+    foreach(@ndrdump_files) {
+	chomp($_);
+	if ($_ =~ /in/) {
+	    if ($in_filename) {
+		print "[1] Skipping $in_filename\n" if $self->{CONF}->{verbose};
+		$in_filename = $_;
+		add_skipped_file($self, $in_filename, "REQ");
+	    } else {
+		$in_filename = $_ if (!$in_filename);
+	    }
+	}
+	if ($_ =~ /out/) {
+	    if (!$in_filename) {
+		print "[2] Skipping $_\n" if $self->{CONF}->{verbose};
+		add_skipped_file($self, $_, "REPL");
+	    } else {
+		$out_filename = $_;
+		$counter++;
+		add_brace($self, $counter, $in_filename, $out_filename);
+		$out_filename = $in_filename = 0;
+	    }
+	}
+	$self->{ECDORPC}->{braces_count} = $counter;
+    }
+
+    bless($self);
+
+    return $self;
+}
+
+#######################################################
+# ERROR RELATED FUNCTIONS
+#######################################################
+sub add_bad_packet
+{
+    my $self = shift;
+    my $inout = shift;
+    my $filename = shift;
+    my $output = shift;
+
+    $self->{STATISTIC}->failure_request_counter() if ($inout eq "in");
+    $self->{STATISTIC}->failure_response_counter() if ($inout eq "out");
+
+    $self->{ECDORPC_ERROR}->{$inout}->{$filename} = {};
+    my $packet = $self->{ECDORPC_ERROR}->{$inout}->{$filename};
+
+    $packet->{output} = $output;
+}
+
+sub error_report
+{
+    my $self = shift;
+    my $inout = shift;
+
+    if ($inout ne "in" && $inout ne "out") {
+	print "[mapitrace]: Wrong parameter, must be in or out\n";
+	return -1;
+    }
+
+    
+    print "\n[$inout" . "put error_report]:\n\n";
+    foreach my $key (sort sort_packets keys (%{$self->{ECDORPC_ERROR}->{$inout}})) {
+	print $key . "\n";
+    }
+}
+
+#######################################################
+# NDRDUMP + BRACES + STORAGE OPERATIONS
+#######################################################
+
+#
+# Initialize and add a brace to the hash
+#
+sub add_brace
+{
+    my $self = shift;
+    my $idx = shift;
+    my $in_filename = shift;
+    my $out_filename = shift;
+
+    $self->{ECDORPC}->{braces}->{$idx} = {};
+    $self->{ECDORPC}->{braces}->{$idx}->{in} = {};
+    $self->{ECDORPC}->{braces}->{$idx}->{out} = {};
+    
+    $self->{ECDORPC}->{braces}->{$idx}->{in}->{filename} = $in_filename;
+    $self->{ECDORPC}->{braces}->{$idx}->{in}->{output} = '';
+    
+    $self->{ECDORPC}->{braces}->{$idx}->{out}->{filename} = $out_filename;
+    $self->{ECDORPC}->{braces}->{$idx}->{out}->{output} = '';
+
+    $self->{STATISTIC}->increment_brace_counter();
+}
+
+#
+# Store the error brace in the BRACES_ERROR hash and
+# Delete the brace from the ECDORPC hash
+#
+sub delete_brace
+{
+    my $self = shift;
+    my $idx = shift;
+
+    $self->{BRACES_ERROR}->{$idx} = {};
+    $self->{BRACES_ERROR}->{$idx} = $self->{ECDORPC}->{braces}->{$idx};
+
+    $self->{ECDORPC}->{braces_count}--;
+    delete($self->{ECDORPC}->{braces}->{$idx});
+
+    $self->{STATISTIC}->increment_brace_error_counter();
+}
+
+#
+# ndrdump a brace and check in the output
+# if we have an error (segfault)
+#
+sub ndrdump_brace
+{
+    my $self = shift;
+    my $idx = shift;
+    my $inout = shift;
+
+    my $filename = $self->{ECDORPC}->{braces}->{$idx}->{$inout}->{filename};
+    my $output = `ndrdump -l libmapi.so exchange_emsmdb 0x2 $inout $filename`;
+
+    $self->{ECDORPC}->{braces}->{$idx}->{$inout}->{output} = $output;    
+    if ($output =~ /INTERNAL ERROR:/) {
+	$self->add_bad_packet($inout, $filename, $output);
+	$self->{ECDORPC}->{braces}->{$idx}->{error} = $inout;
+	return $idx;
+    }
+
+    $self->{STATISTIC}->success_request_counter() if ($inout eq "in");
+    $self->{STATISTIC}->success_response_counter() if ($inout eq "out");
+
+    return 0;
+}
+
+#
+# ndrdump the files in the list and clean the hash
+# if incorrect braces are found
+#
+sub ndrdump
+{
+    my $self = shift;
+    my @invalid_braces = ();
+    my $idx;
+
+    foreach my $key (sort asc_num (keys(%{$self->{ECDORPC}->{braces}}))) {
+	push(@invalid_braces, $idx) if ($idx = ndrdump_brace($self, $key, "in"));
+	push(@invalid_braces, $idx) if ($idx = ndrdump_brace($self, $key, "out"));
+    }
+
+#    $self->{STATISTIC}->{}
+
+    foreach(@invalid_braces) {
+	delete_brace($self, $_);
+    } 
+
+#    MAPI::Dump_EcDoRpc->dump_error_brace($self);
+}
+
+############################################################
+# ANALYZE PART
+############################################################
+
+#
+# Retrieve the handles array (in,out) from a given packet
+#
+sub get_pkt_handles
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $inout = shift;
+    my $output = shift;
+    my @lines = split(/\n/, $output);
+    my $count_marker = 0;
+
+    foreach(@lines) {
+	if ($count_marker) {
+	    $_ =~ /: (\w+) \(/i;
+	    push(@{$mapi_call->{handles_in}},  $1) if ($inout eq "REQ");
+	    push(@{$mapi_call->{handles_out}}, $1) if ($inout eq "REPL");
+	    $count_marker--;
+	}
+	
+	if (!$count_marker && $_ =~ /\(handles\)/) {
+	    $_ =~/number=(\d+)/i;
+	    $count_marker = $1;
+	}
+    }
+}
+
+#
+# Reset mapi_call markers
+#
+sub mapi_call_reset_markers
+{
+    my $mapi_call = shift;
+
+    $mapi_call->{marker}->{opnum} = 0;
+    $mapi_call->{marker}->{opname} = 0;
+    $mapi_call->{marker}->{handle_idx} = 0;
+    $mapi_call->{marker}->{sub_handles} = 0;
+    $mapi_call->{marker}->{store} = 0;
+}
+
+#
+# Initialize the mapi call parsing structure
+#
+
+sub init_mapi_call
+{
+    my $mapi_call = {};
+
+    # Initialize markers
+    $mapi_call->{marker} = {};
+    mapi_call_reset_markers($mapi_call);
+    $mapi_call->{marker}->{call_idx} = -1;
+
+    # Initialize the call serialization hash
+    $mapi_call->{calls} = {};
+
+    # Initialize handles
+    $mapi_call->{handles_in} = ();
+    $mapi_call->{handles_out} = ();
+
+    bless($mapi_call);
+    return ($mapi_call);
+}
+
+#
+# Get the start of a mapi call
+#
+
+sub get_mapi_call_start
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($line =~ /EcDoRpc_MAPI_$inout$/) {
+	mapi_call_reset_markers($mapi_call);
+	$mapi_call->{marker}->{opnum} = 1;
+	$mapi_call->{marker}->{call_idx}++;
+    }
+}
+
+#
+# Get mapi call opnum
+#
+sub get_mapi_call_opnum
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($mapi_call->{marker}->{opnum} && $line =~ /opnum\s+:/) {
+	$line =~ /(0x\w{2})/i;
+	
+	my $idx = $mapi_call->{marker}->{call_idx};
+	$mapi_call->{calls}->{$inout}->{$idx}->{opnum} = $1;
+
+	$mapi_call->{marker}->{opnum} = 0;
+	$mapi_call->{marker}->{handle_idx} = 1;
+	$mapi_call->{marker}->{retval} = 1;
+    }
+}
+
+#
+# Get mapi call opname
+#
+sub get_mapi_call_opname
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($mapi_call->{marker}->{opname} && $line =~ /mapi_\w+: struct/) {
+	$line =~ /mapi_(\w+):/i;
+
+	my $idx = $mapi_call->{marker}->{call_idx};
+	$mapi_call->{calls}->{$inout}->{$idx}->{opname} = $1;
+
+	$mapi_call->{marker}->{opname} = 0;
+	$mapi_call->{marker}->{sub_handles} = 1;
+    }
+}
+
+#
+# Get mapi call error code
+#
+sub get_mapi_call_retval
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($mapi_call->{marker}->{retval} && $line =~ /error_code/) {
+	$line =~ /error_code\s+:\s+(\w+)/i;
+	my $idx = $mapi_call->{marker}->{call_idx};
+	$mapi_call->{calls}->{$inout}->{$idx}->{retval} = $1;
+	$mapi_call->{marker}->{retval} = 0;
+    }
+}
+
+#
+# Get mapi call handle idx
+#
+sub get_mapi_call_handle_idx
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($mapi_call->{marker}->{handle_idx} && $line =~ /handle_idx\s+:/) {
+	$line =~ /(0x\w{2})/i;
+	
+	my $idx = $mapi_call->{marker}->{call_idx};
+	$mapi_call->{calls}->{$inout}->{$idx}->{handle_idx} = $1;
+
+	$mapi_call->{marker}->{handle_idx} = 0;
+	$mapi_call->{marker}->{opname} = 1;
+    }
+}
+
+#
+# Get sub handles idx within mapi_call specific dump
+#
+sub get_mapi_call_sub_handle_idx
+{
+    my $mapi_call = shift;
+    my $line = shift;
+    my $inout = shift;
+
+    if ($mapi_call->{marker}->{sub_handles} && $line =~ /handle_idx/) {
+	$line =~ /(0x\w{2})/i;
+	
+	my $idx = $mapi_call->{marker}->{call_idx};
+	$mapi_call->{calls}->{$inout}->{$idx}->{self_handle_idx} = $1;
+    }
+}
+
+#
+# Retrieve MAPI calls for a given packet:
+# - opnum
+# - handle_idx
+# - opname
+# - sub handles
+#
+sub get_mapi_calls
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $inout = shift;
+
+    # Reset the mapi call counter
+    $mapi_call->{marker}->{call_idx} = -1;
+
+    my @lines = split(/\n/, $self->{output});
+    foreach my $line (@lines) {
+	chomp($line);
+
+	get_mapi_call_start($mapi_call, $line, $inout);
+	get_mapi_call_opnum($mapi_call, $line, $inout);
+	get_mapi_call_handle_idx($mapi_call, $line, $inout);
+	get_mapi_call_retval($mapi_call, $line, $inout);
+	get_mapi_call_opname($mapi_call, $line, $inout);
+	get_mapi_call_sub_handle_idx($mapi_call, $line, $inout);
+    }    
+
+    # We do not need anymore the markers
+    delete($mapi_call->{marker});
+}
+
+#
+# When checking mapi calls number consistency between in and out,
+# we have to remove Release calls count from request cause Release
+# doesn't produce any call in out (until now).
+#
+sub get_mapi_calls_request_count
+{
+    my $_self = shift;
+    my $in = shift;
+
+    my $counter = keys(%{$in});
+
+    foreach my $key (keys(%{$in})) {
+	if (hex($in->{$key}->{opnum}) == 0x1) {
+	    $counter--;
+	}
+    }
+    return $counter;
+}
+
+#
+# Get the call index for a given call in the response
+# This hack fixes the Release issue
+# Note: MAPI serialize calls in such way we can predict 
+# the response call index with reasonable confidence
+#
+sub get_call_index
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $call_idx = shift;
+
+    my $in = $mapi_call->{calls}->{REQ};
+    
+    return $call_idx if (keys(%{$in}) == $self->get_mapi_calls_request_count($in));
+
+    # If count mismatches case
+
+    return $call_idx if ($call_idx == 0);
+
+    for (my $idx = 0; $idx <= $call_idx; $idx++) {
+	$call_idx-- if (hex($in->{$idx}->{opnum}) == 0x1);
+    }
+    return $call_idx;
+}
+
+#
+# Analyze EcDoRpc braces output and extract the information
+# we need to create the object hierarchy
+#
+
+sub analyze
+{
+    my $self = shift;
+    my $trace_opt = shift;
+
+    foreach my $key (sort asc_num (keys(%{$self->{ECDORPC}->{braces}}))) {
+	my $in = $self->{ECDORPC}->{braces}->{$key}->{in};
+	my $out = $self->{ECDORPC}->{braces}->{$key}->{out};
+
+	MAPI::Dump_EcDoRpc->dump_brace_start($in, $out) if ($trace_opt);
+
+	$self->{ECDORPC}->{braces}->{$key}->{mapi_calls} = init_mapi_call();
+	my $mapi_call = $self->{ECDORPC}->{braces}->{$key}->{mapi_calls};
+
+	get_mapi_calls($in,  $mapi_call, "REQ");
+	get_mapi_calls($out, $mapi_call, "REPL");
+
+	# Add the request/response handle array in the element hash
+	$self->get_pkt_handles($mapi_call, "REQ", $in->{output});
+	$self->get_pkt_handles($mapi_call, "REPL", $out->{output});
+
+	$self->get_mapi_call_hierarchy($in, $out, $mapi_call, $key);
+	if ($trace_opt) {
+	    if (MAPI::Dump_EcDoRpc->dump_mapi_calls($mapi_call)) {
+		$self->delete_brace($key);
+	    } else {
+		MAPI::Dump_EcDoRpc->dump_brace_handles($mapi_call);
+		MAPI::Dump_EcDoRpc->dump_brace_end();
+	      }
+	}
+    }
+}
+
+############################################################
+# ANALYZE PART FOR HANDLES
+############################################################
+
+#
+# Get mapi_call hierarchy within a serialized request
+# 
+# Explanations:
+# * If the call has a handle_idx set to 0xffffffff but this handle_idx is
+#   already referenced by a previous call in its self_handle_idx field, then
+#   the call is a child of the one with the set_handle_idx
+#
+# * In MAPI Semantic, a self handle is unique and can't be set twice
+#
+sub get_mapi_call_hierarchy
+{
+    my $self = shift;
+    my $request = shift;
+    my $response = shift;
+    my $mapi_call = shift;
+    my $key = shift;
+
+    ## WARNING: This is the nasty hack that should be removed 
+    if (!defined $mapi_call->{handles_in} || !defined $mapi_call->{handles_out}) {
+	$self->delete_brace($key);
+	return ;
+    }
+    
+    my @handles_in = @{$mapi_call->{handles_in}};
+    my @handles_out = @{$mapi_call->{handles_out}};
+
+    my $self_handles = {};
+    my $in = $mapi_call->{calls}->{REQ};
+
+     # If we don't have multi calls, no need to go further
+    return if (keys(%{$in}) == 1);
+
+    # Retrieve calls with self_handle
+    foreach my $key (sort pkt_number keys(%{$in})) {
+	if ($in->{$key}->{self_handle_idx}) {
+	    my $self_handle_idx = $in->{$key}->{self_handle_idx};
+	    $self_handles->{$self_handle_idx} = $key;
+	    $in->{$key}->{children} = ();
+	}
+    }
+
+    # If we don't have any self handles, no need to go further
+    return if (keys(%{$in}) == 0);
+
+    # We now retrieve calls again
+    # check for handle_idx referring handles value 0xffffffff
+    # and check if their handle idx is already indexed in %self_handles
+    # which means it is a child of this call
+    foreach my $key (sort pkt_number keys(%{$in})) {
+	if ($handles_in[hex($in->{$key}->{handle_idx})] &&
+	    $handles_in[hex($in->{$key}->{handle_idx})] eq "0xffffffff") {
+	    my $call_handle_idx = $in->{$key}->{handle_idx};
+	    if (exists $self_handles->{$call_handle_idx}) {
+		my $parent_call_idx = $self_handles->{$call_handle_idx};
+		$in->{$key}->{parent} = $self_handles->{$call_handle_idx};
+		push(@{$in->{$parent_call_idx}->{children}}, $key);
+	    }
+	}
+    }
+}
+
+############################################################
+# WRAPPER FUNCTIONS ON THE GRAPHVIZ MODULE
+############################################################
+
+#
+# process the call hierarchy and prepare the nodes for graph output
+#
+sub graph_calls
+{
+    my $self = shift;
+    my $g = shift;
+    my $brace_key = shift;
+
+    my $brace = $self->{ECDORPC}->{braces}->{$brace_key};
+    my $mapi_call = $brace->{mapi_calls};
+
+    return if (!exists $mapi_call->{handles_out});
+
+    # Get the request and response handles
+    my @handles_out = @{$mapi_call->{handles_out}};
+
+    # Get the request mapi_call serialization hash
+    my $in = $mapi_call->{calls}->{REQ};
+
+    # Check if we are in a serialized call
+    #    if (@handles_out == 1) {
+    #	$g->add_node($mapi_call, 0);
+    #	return ;
+    #    }
+ 
+
+    # Process the serialized
+    # We first check for self_handle packets only
+    # Next we process self_handle packets with children
+    # Finally we check normal calls
+    foreach my $key (sort asc_num (keys(%{$in}))) {
+	if ($in->{$key}->{self_handle_idx}) {
+	    $g->add_node($mapi_call, $key);
+	    if (exists $in->{$key}->{children}) {
+		foreach my $call_idx (@{$in->{$key}->{children}}) {
+		    $g->add_node($mapi_call, $call_idx);
+		}
+	    }
+	} else {
+	    $g->add_node($mapi_call, $key);
+	}
+    }
+}
+
+sub graph
+{
+    my $self = shift;
+    my $dir = shift;
+    my $highlight = shift;
+    my $png  = $dir . "/" . $self->get_filename($self->{CONF}->{path}) . ".png";
+
+    # mkdir output directory if it doesn't exist
+    mkdir $dir;
+
+#    my $g = MAPI::Graph_EcDoRpc->new($png);
+    my $g = MAPI::Graph->new($png, $highlight);
+
+    # Dump the hierarchy
+    $self->graph_calls($g, $_) foreach (sort asc_num 
+					(keys(%{$self->{ECDORPC}->{braces}})));
+
+    $g->render();
+}
+
+############################################################
+# WRAPPER FUNCTIONS ON THE STATS MODULE
+############################################################
+
+#
+# Add skipped files
+#
+sub add_skipped_file
+{
+    my $self = shift;
+    my $filename = shift;
+    my $inout = shift;
+
+    my $count = $self->{SKIPPED_FILES}->{$inout}->{count};
+    my $files = $self->{SKIPPED_FILES}->{$inout}->{files};
+
+    # Initiate and add the new entry
+    $files->{$count} = {};
+    $files->{$count}->{filename} = $filename;
+
+    # Increment the counter
+    $self->{SKIPPED_FILES}->{$inout}->{count}++;
+}
+
+#
+#
+#
+sub stats
+{
+    my $self = shift;
+
+    $self->{STATISTIC}->scenario();
+
+#    print Dumper($self->{SKIPPED_FILES});
+}
+
+############################################################
+# SEARCH FUNCTIONS PART
+############################################################
+
+#
+# Trace a call through the scenario
+#
+sub search_call
+{
+    my $self = shift;
+    my $callname = shift;
+    my $dump_opt = shift;
+    my $inout = shift;
+
+    my $search = {};
+    my $count = 0;
+    my @results = ();
+
+    my $find_marker = 0;
+
+    # We loop through mapi calls REQ calls and search for the given call
+    foreach my $brace_key (sort pkt_number keys(%{$self->{ECDORPC}->{braces}})) {
+	my $brace = $self->{ECDORPC}->{braces}->{$brace_key};
+
+	foreach my $call_key (sort pkt_number keys(%{$brace->{mapi_calls}->{calls}->{REQ}})) {
+	    my $call = $brace->{mapi_calls}->{calls}->{REQ}->{$call_key};
+
+	    if ($call->{opname} && $call->{opname} eq $callname) {
+		$find_marker = 1;
+		$search->{$count}->{brace_key} = $brace_key;
+		$count++;
+		print $brace->{$inout}->{output} if ($dump_opt && $inout);
+		push(@results, $call->{opname} . ": " . $self->get_filename($brace->{in}->{filename}) . " / " . $self->get_filename($brace->{out}->{filename}) . "\n");
+	    }
+	}
+    }
+
+    if ($#results >= 0) {
+	print "[X] Call found in [ " . $self->{CONF}->{name} . " ]:\n";
+	print "\t$_" foreach (@results);
+    } else {
+	print "[O] No call found in [ " . $self->{CONF}->{name} . " ]\n";
+    }
+    # We are now looking for the call in problematic packets
+    
+}
+
+1;

Added: trunk/openchange/utils/mapitrace/lib/MAPI/Graph.pm
===================================================================
--- trunk/openchange/utils/mapitrace/lib/MAPI/Graph.pm	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/lib/MAPI/Graph.pm	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,313 @@
+##################################################
+# EcDoRpc GraphViz Dump package for mapitrace tool
+# Copyright Julien Kerihuel 2007
+# <j.kerihuel at openchange.org>
+#
+# released under the GNU GPL
+#
+
+package MAPI::Graph;
+
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw();
+use vars qw($AUTOLOAD $VERSION);
+$VERSION = '0.01';
+
+use strict;
+use GraphViz;
+use Data::Dumper;
+
+#
+# Init the MAPI::Graph object
+#
+sub new
+{
+    my $_self = shift;
+    my $output_file = shift;
+    my $highlight = shift;
+
+    my $self = {};
+
+    $self->{graph} = GraphViz->new(node => {shape => 'box'});
+    $self->{nodelist} = {};
+    $self->{output_file} = $output_file;
+    $self->{highlight} = $highlight;
+
+    bless($self);
+    return $self;
+}
+
+#
+# Render the graph
+#
+sub render
+{
+    my $self = shift;
+
+    print "Dumping graph in ." . $self->{output_file} . "\n";
+    $self->{graph}->as_png($self->{output_file});
+}
+
+#
+# Init a new node in the general nodelist hash
+# A node is a set of queue each of them composed of children
+#
+sub node_init
+{
+    my $self = shift;
+    my $node_id = shift;
+
+    my $nodelist = $self->{nodelist};
+
+    print "[node_init]: Adding node: $node_id\n";
+    $nodelist->{$node_id} = {};
+    $nodelist->{$node_id}->{children} = {};
+    $nodelist->{$node_id}->{count} = 1;
+    @{$nodelist->{$node_id}->{children}->{1}} = ();
+}
+
+#
+# If a release occur on a node we need to increment
+# the depth so we can start a new hierarchy
+#
+sub add_depth
+{
+    my $self = shift;
+    my $node_id = shift;
+
+    my $node = $self->{nodelist}->{$node_id};
+
+    $node->{count} += 1;
+    my $count =  $node->{count};
+
+    $node->{children}->{$count} = ();
+    
+}
+
+#
+# Get the last child id for the given node_id
+#
+sub get_last_nodelist_child
+{
+    my $self = shift;
+    my $node_id = shift;
+
+    my $node = $self->{nodelist}->{$node_id};
+
+    return 0 if (!$node);
+
+    my $count = $node->{count};
+    my $child_id = @{$node->{children}->{$count}};
+
+    # If the node doesn't have children return the parent one
+    return $node_id if (!$child_id);
+
+    # Otherwise return the last child
+    my @hierarchy = @{$node->{children}->{$count}};
+    $child_id -= 1;
+    my $last_child = $hierarchy[$child_id];
+    return $last_child;
+}
+
+#
+# add a child to an existing node in the nodelist hash
+#
+sub nodelist_add_child
+{
+    my $self = shift;
+    my $node_id = shift;
+
+    # get the node in the hash
+    my $node = $self->{nodelist}->{$node_id};
+    # get the number of hierarchy array
+    my $count = $node->{count};
+    # get the number of children for the given hierarchy
+    my $child_count = @{$node->{children}->{$count}};
+    # we increment the child counter
+    $child_count += 1;
+    my $child_name = "$node_id:$count:$child_count";
+
+    print "Adding node: $child_name\n";
+    push(@{$node->{children}->{$count}}, $child_name);
+
+    return $child_name;
+}
+
+#
+# add a node in the general nodelist hash
+# it can be a node or the child of an existing node
+#
+sub nodelist_add
+{
+    my $self = shift;
+    my $node_id = shift;
+
+    my $nodelist = $self->{nodelist};
+
+    # Add the node directly if not referenced in the nodelist hash
+    if (!exists $nodelist->{$node_id}) {
+	$self->node_init($node_id);
+	return $node_id;
+    }
+
+    # If the node already exists, add a child for the correct one
+    my $last_child = $self->nodelist_add_child($node_id);
+    return $last_child;
+}
+
+#
+# Add edge between two nodes
+#
+sub add_edge
+{
+    my $self = shift;
+    my $parent_handle = shift;
+    my $self_handle = shift;
+
+    my $g = $self->{graph};
+
+    # If self_handle exists add an edge between 
+    # the last parent's child and the self_handle
+    my $last_child = $self->get_last_nodelist_child($parent_handle);
+
+    if ($self_handle) {
+	print "[add_edge] $last_child -> $self_handle\n";
+	$g->add_edge($last_child, $self_handle);
+    } else {
+	# if this is a root element we shouldn't add edge
+	if ($parent_handle ne $last_child) {
+	    print "[add_edge] $parent_handle -> $last_child\n";
+	    $g->add_edge($parent_handle, $last_child);
+	} else {
+	    print "[add_edge]: no edge for $parent_handle\n";
+	}
+    }
+}
+
+#
+# Add a node to the graph
+#
+
+sub add_node
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $key = shift;
+
+    my $g = $self->{graph};
+
+    my $parent_handle = $self->get_parent_handle($mapi_call, $key);
+    my $self_handle = $self->get_self_handle($mapi_call, $key);
+
+    # If we do not have a self handle
+    if (!$self_handle) {
+	my $last_child = $self->get_last_nodelist_child($parent_handle);
+	my $node_id = $self->nodelist_add($parent_handle);
+	my $label = $self->get_node_label($mapi_call, $key);
+	
+	if ($self->{highlight} && !$self->node_highlight($label)) {
+	    print "############ HERE ##############\n";
+	    $g->add_node($node_id, label => $label,
+			 style => "filled",
+			 color => "green");	    
+	} else {
+	    $g->add_node($node_id, label => $label);
+	}
+
+	# If there is already a child, link against it
+	if ($last_child && $last_child ne $parent_handle) {
+	    $g->add_edge($last_child => $node_id);
+	    
+	} else {
+	    # Otherwise, just link it to the parent node
+	    $self->add_edge($parent_handle);
+	}
+
+    }
+
+    # If we do have a self handle
+    if ($self_handle) {
+	my $node_id = $self->nodelist_add($self_handle);
+	my $label = $self->get_node_label($mapi_call, $key);
+
+	if ($self->{highlight} && !$self->node_highlight($label)) {
+	    print "############ HERE ##############\n";
+	    $g->add_node($node_id, label => $label,
+			 style => "filled",
+			 color => "green");	    
+	} else {
+	    $g->add_node($node_id, label => $label);
+	}
+	$self->add_edge($parent_handle, $node_id);
+    }
+}
+
+sub get_node_label
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $key = shift;
+
+    my $in = $mapi_call->{calls}->{REQ}->{$key};
+    my $label = '';
+
+    $label = sprintf "%s (%s)", $in->{opname}, $in->{opnum};
+
+    return $label;
+}
+
+sub node_highlight
+{
+    my $self = shift;
+    my $label = shift;
+
+    return -1 if !$self->{highlight};
+
+    my $label2 = substr($label, 0, length($self->{highlight}));
+
+    if ($self->{highlight} eq $label2) {
+	print "WE CAN HIGHLIGHT THE CALL\n";
+	return 0;
+    }
+    return -1;
+}
+
+#########################################
+# HANDLE CONVENIENT FUNCTIONS
+#########################################
+
+#
+# get the parent handle (handle_idx field)
+#
+sub get_parent_handle
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $key = shift;
+
+    my $in = $mapi_call->{calls}->{REQ}->{$key};
+    my @handles = @{$mapi_call->{handles_out}};
+
+    my $parent_handle = $in->{handle_idx};
+    return $handles[hex($parent_handle)];
+}
+
+#
+# get the self handle (self_handle_idx field)
+#
+sub get_self_handle
+{
+    my $self = shift;
+    my $mapi_call = shift;
+    my $key = shift;
+
+    my $in = $mapi_call->{calls}->{REQ}->{$key};
+    my @handles = @{$mapi_call->{handles_out}};
+
+    return 0 if (!exists $in->{self_handle_idx});
+
+    my $self_handle = $in->{self_handle_idx};
+
+    return $handles[hex($self_handle)];
+}

Added: trunk/openchange/utils/mapitrace/lib/MAPI/Regression.pm
===================================================================
--- trunk/openchange/utils/mapitrace/lib/MAPI/Regression.pm	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/lib/MAPI/Regression.pm	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,18 @@
+#############################################
+# EcDoRpc package for mapitrace tool
+# Copyright Julien Kerihuel 2007
+# <j.kerihuel at openchange.org>
+#
+# released under the GNU GPL v3 or later
+#
+package MAPI::Regression;
+
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw();
+use vars qw($AUTOLOAD $VERSION);
+$VERSION = '0.01';
+
+use strict;
+
+1;

Added: trunk/openchange/utils/mapitrace/lib/MAPI/Statistic.pm
===================================================================
--- trunk/openchange/utils/mapitrace/lib/MAPI/Statistic.pm	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/lib/MAPI/Statistic.pm	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,191 @@
+##############################################
+# EcDoRpc Statistic package for mapitrace tool
+# Copyright Julien Kerihuel 2007
+# <j.kerihuel at openchange.org>
+#
+# released under the GNU GPL v3 or later
+#
+package MAPI::Statistic;
+
+require Exporter;
+ at ISA = qw(Exporter);
+ at EXPORT = qw();
+use vars qw($AUTOLOAD $VERSION);
+$VERSION = '0.01';
+
+use strict;
+use Data::Dumper;
+
+#######################################################
+# INIT PART
+#######################################################
+
+#
+# Initiate the statistic object
+#
+sub new
+{
+    my $_self = shift;
+    my ($scenario) = shift;
+    my (@files) = @_;
+
+    my $self = {};
+
+    $self->{SCENARIO} = {};
+    $self->{SCENARIO}->{name} = $scenario;
+    $self->{SCENARIO}->{total} = $#files + 1;
+
+    $self->{SCENARIO}->{BRACES}->{total} = 0;
+    $self->{SCENARIO}->{BRACES}->{failure} = 0;
+
+    $self->{SCENARIO}->{REQUEST}->{total} = 0;
+    $self->{SCENARIO}->{REQUEST}->{success} = 0;
+    $self->{SCENARIO}->{REQUEST}->{failure} = 0;
+
+    $self->{SCENARIO}->{RESPONSE}->{total} = 0;
+    $self->{SCENARIO}->{RESPONSE}->{success} = 0;
+    $self->{SCENARIO}->{RESPONSE}->{failure} = 0;
+
+    count_total_packets_type($self, @files);
+
+    $self->{SCENARIO}->{CALLS} = {};
+
+    bless($self);
+
+    return $self;
+}
+
+#######################################################
+# COUNT FUNCTION PART
+#######################################################
+
+#
+# Count the full number of requests and replies
+#
+sub count_total_packets_type
+{
+    my $self = shift;
+    my (@files) = @_;
+
+    foreach (@files) {
+	$self->{SCENARIO}->{REQUEST}->{total}++ if ($_ =~ /in/);
+	$self->{SCENARIO}->{RESPONSE}->{total}++ if ($_ =~ /out/);
+    }
+}
+
+#
+#
+#
+sub increment_brace_counter
+{
+    my $self = shift;
+
+    $self->{SCENARIO}->{BRACES}->{total}++;
+}
+
+sub increment_brace_error_counter
+{
+    my $self = shift;
+
+    $self->{SCENARIO}->{BRACES}->{failure}++;
+}
+
+#
+# 
+#
+sub count_packet_inc
+{
+    my $self = shift;
+    my $inout = shift;
+    my $state = shift;
+
+    return -1 if (!$state || !$inout);
+    $self->{SCENARIO}->{REQUEST}->{$state}++ if ($inout eq "in");
+    $self->{SCENARIO}->{RESPONSE}->{$state}++ if ($inout eq "out");
+}
+
+#
+# Accessors
+#
+sub success_request_counter
+{
+    my $self = shift;
+    $self->increment_counter("REQUEST", "success");
+}
+
+sub failure_request_counter
+{
+    my $self = shift;
+    $self->increment_counter("REQUEST", "failure");
+}
+
+sub success_response_counter
+{
+    my $self = shift;
+    $self->increment_counter("RESPONSE", "success");
+}
+
+sub failure_response_counter
+{
+    my $self = shift;
+    $self->increment_counter("RESPONSE", "failure");
+}
+
+sub increment_counter
+{
+    my $self = shift;
+    my $type = shift;
+    my $case = shift;
+
+    $self->{SCENARIO}->{$type}->{$case}++;
+}
+
+#######################################################
+# DUMP PART
+#######################################################
+
+sub percent
+{
+    my $obj = shift;
+    my $type = shift;
+
+    return ($obj->{$type}->{total} / $obj->{total}) * 100;
+}
+
+sub scenario
+{
+    my $self = shift;
+
+    my $request_percent = percent($self->{SCENARIO}, "REQUEST");
+    my $response_percent = percent($self->{SCENARIO}, "RESPONSE");
+
+    print "+-----[ Scenario: " . $self->{SCENARIO}->{name} . " ]-----+\n";
+    print "[statistic]: We have " . $self->{SCENARIO}->{total} . " packets ";
+    print "(request: " . $request_percent . "%, ";
+    print "response: " . $response_percent . "%)\n";
+
+    my $success_req_rate = ($self->{SCENARIO}->{REQUEST}->{success} / $self->{SCENARIO}->{REQUEST}->{total}) * 100;
+    my $success_repl_rate = ($self->{SCENARIO}->{RESPONSE}->{success} / $self->{SCENARIO}->{RESPONSE}->{total}) * 100;
+    print "[statistic]: request success rate: " . $success_req_rate . "\n";
+    print "[statistic]: response success rate: " . $success_repl_rate . "\n";
+
+    my $braces_count = $self->{SCENARIO}->{BRACES}->{total};
+    my $braces_failure = $self->{SCENARIO}->{BRACES}->{failure};
+    if ($braces_failure) {
+	print "[statistic]: success brace analysis rate: " . ((1 - ($braces_failure/$braces_count)) * 100) . "\n";
+	print "[statistic]: braces skipped: " . $braces_failure . "/" . $braces_count . "\n";
+    } else {
+	print "[statistic]: success brace analysis rate: 100%\n";	
+	print "[statistic]: no braces skipped\n";
+    }
+    print "+--------------------------------------------------------------+\n";
+    
+}
+
+sub dump
+{
+    my $self = shift;
+}
+
+
+1;

Added: trunk/openchange/utils/mapitrace/mapitrace
===================================================================
--- trunk/openchange/utils/mapitrace/mapitrace	                        (rev 0)
+++ trunk/openchange/utils/mapitrace/mapitrace	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,118 @@
+#!/usr/bin/perl -w
+
+##############################################
+# package to dump the mapi call hierarchy and
+# add IDL regression support
+#
+# Copyright Julien Kerihuel 2007.
+# <j.kerihuel at openchange.org>
+#
+# released under GNU GPL v3 or later
+
+use strict;
+
+use FindBin qw($RealBin $Script);
+use lib "$RealBin";
+use lib "$RealBin/lib";
+#use lib "lib";
+use MAPI::EcDoRpc;
+use Getopt::Long;
+
+my ($opt_help) = 0;
+my ($opt_outputdir) = '.';
+my ($opt_graph) = 0;
+my ($opt_highlight) = 0;
+my ($opt_trace) = 0;
+my ($opt_search_call) = 0;
+my ($opt_dump_call) = 0;
+my ($opt_inout) = 0;
+my ($opt_error) = 0;
+my ($opt_stats) = 0;
+my ($opt_verbose) = 0;
+############################################
+# display help text
+sub ShowHelp()
+{
+    print "mapi call hierarchy tracing tool and IDL regression support
+Copyright (C) Julien Kerihuel <j.kerihuel\@openchange.org>
+
+Usage: $Script [options]
+
+Generic Options:
+--help                 this help page
+--outputdir=OUTDIR     put output in OUTDIR/ []
+--graph                create a png graph
+--trace                dump the mapi call hierarchy on command line
+--verbose	       verbose output
+
+Tracing Options:
+--search-call=CALL     trace a single call through a scenario
+--dump-call            dump all the packets containing the call specified
+--highlight=CALL       highlight a call in the generated graph
+--inout=INOUT	       filter either requests (in) or response (out)
+
+Regression Options:
+--error_report=in,out  Investigate invalid packets
+--stats                Display statistics for a given scenario
+
+\n";
+    exit (0);
+}
+
+# main program
+my $result = GetOptions (
+			 'help|h|?' => \$opt_help,
+			 'outputdir=s' => \$opt_outputdir,
+			 'graph|g' => \$opt_graph,
+			 'highlight=s'=> \$opt_highlight,
+			 'trace|t' => \$opt_trace,
+			 'search-call=s' => \$opt_search_call,
+			 'dump-call|d' => \$opt_dump_call,
+			 'inout=s' => \$opt_inout,
+			 'error_report=s' => \$opt_error,
+			 'stats|s' => \$opt_stats,
+			 'verbose|v' => \$opt_verbose
+			 );
+
+if (not $result) {
+    exit (1);
+}
+
+if ($opt_help) {
+    ShowHelp();
+    exit (0);
+}
+
+sub process_tracing($)
+{
+    my $directory = shift;
+    my $outputdir = $opt_outputdir;
+    
+
+    opendir(DIR,$directory) or die "Unable to process $directory";
+    closedir(DIR);
+
+    my $EcDoRpc = MAPI::EcDoRpc->new($directory, $outputdir, $opt_verbose);
+
+    $EcDoRpc->ndrdump();
+    $EcDoRpc->analyze($opt_trace);
+
+    if ($opt_error) {
+	my @inout = split(/,/, $opt_error);
+
+	foreach (sort @inout) {
+	    $EcDoRpc->error_report($_);
+	}
+    }
+    
+    $EcDoRpc->stats() if ($opt_stats);
+    $EcDoRpc->search_call($opt_search_call, $opt_dump_call, $opt_inout) if ($opt_search_call);
+    $EcDoRpc->graph($outputdir, $opt_highlight) if ($opt_graph);
+}
+
+if (scalar(@ARGV) == 0) {
+    print "$Script: no input directory\n";
+    exit (1);
+}
+
+process_tracing($_) foreach (@ARGV);


Property changes on: trunk/openchange/utils/mapitrace/mapitrace
___________________________________________________________________
Added: svn:executable
   + *

Added: trunk/openchange/utils/openchange-tools.c
===================================================================
--- trunk/openchange/utils/openchange-tools.c	                        (rev 0)
+++ trunk/openchange/utils/openchange-tools.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,334 @@
+/*
+   Convenient functions for openchange tools
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include "openchange-tools.h"
+
+static void popt_openchange_version_callback(poptContext con,
+					     enum poptCallbackReason reason,
+					     const struct poptOption *opt,
+					     const char *arg,
+					     const void *data)
+{
+	switch (opt->val) {
+	case 'V':
+		printf("Version %s\n", OPENCHANGE_VERSION_STRING);
+		exit (0);
+	}
+}
+
+struct poptOption popt_openchange_version[] = {
+	{ NULL, 0, POPT_ARG_CALLBACK, (void *)popt_openchange_version_callback	},
+	{ "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version "		},
+	{ NULL }
+};
+
+
+/*
+ * Retrieve the property value for a given SRow and property tag.  
+ *
+ * If the property type is a string: fetch PT_STRING8 then PT_UNICODE
+ * in case the desired property is not available in first choice.
+ *
+ * Fetch property normally for any others properties
+ */
+_PUBLIC_ void *octool_get_propval(struct SRow *aRow, uint32_t proptag)
+{
+	const char	*str;
+
+	if (((proptag & 0xFFFF) == PT_STRING8) ||
+	    ((proptag & 0xFFFF) == PT_UNICODE)) {
+		proptag = (proptag & 0xFFFF0000) | PT_STRING8;
+		str = (const char *) find_SPropValue_data(aRow, proptag);
+		if (str) return (void *)str;
+
+		proptag = (proptag & 0xFFFF0000) | PT_UNICODE;
+		str = (const char *) find_SPropValue_data(aRow, proptag);
+		return (void *)str;
+	} 
+
+	return (void *)find_SPropValue_data(aRow, proptag);
+}
+
+
+/*
+ * Read a stream and store it in a DATA_BLOB
+ */
+static enum MAPISTATUS octool_get_stream(TALLOC_CTX *mem_ctx,
+					 mapi_object_t *obj_stream, 
+					 DATA_BLOB *body)
+{
+	enum MAPISTATUS	retval;
+	uint16_t	read_size;
+	uint8_t		buf[0x1000];
+
+	body->length = 0;
+	body->data = talloc_zero(mem_ctx, uint8_t);
+
+	do {
+		retval = ReadStream(obj_stream, buf, 0x1000, &read_size);
+		MAPI_RETVAL_IF(retval, GetLastError(), body->data);
+		if (read_size) {
+			body->data = talloc_realloc(mem_ctx, body->data, uint8_t,
+						    body->length + read_size);
+			memcpy(&(body->data[body->length]), buf, read_size);
+			body->length += read_size;
+		}
+	} while (read_size);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * Fetch the body given PR_MSG_EDITOR_FORMAT property value
+ */
+_PUBLIC_ enum MAPISTATUS octool_get_body(TALLOC_CTX *mem_ctx,
+				       mapi_object_t *obj_message,
+				       struct SRow *aRow,
+				       DATA_BLOB *body)
+{
+	enum MAPISTATUS			retval;
+	const struct SBinary_short	*bin;
+	mapi_object_t			obj_stream;
+	char				*data;
+	uint8_t				format;
+
+	/* Sanity checks */
+	MAPI_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
+
+	/* initialize body DATA_BLOB */
+	body->data = NULL;
+	body->length = 0;
+
+	retval = GetBestBody(obj_message, &format);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	switch (format) {
+	case olEditorText:
+		data = octool_get_propval(aRow, PR_BODY);
+		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);
+			MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+			
+			retval = octool_get_stream(mem_ctx, &obj_stream, body);
+			MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+			
+			mapi_object_release(&obj_stream);
+		}
+		break;
+	case olEditorHTML:
+		bin = (const struct SBinary_short *) octool_get_propval(aRow, PR_HTML);
+		if (bin) {
+			body->data = talloc_memdup(mem_ctx, bin->lpb, bin->cb);
+			body->length = bin->cb;
+		} else {
+			mapi_object_init(&obj_stream);
+			retval = OpenStream(obj_message, PR_HTML, 0, &obj_stream);
+			MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+			retval = octool_get_stream(mem_ctx, &obj_stream, body);
+			MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+			mapi_object_release(&obj_stream);
+		}			
+		break;
+	case olEditorRTF:
+		mapi_object_init(&obj_stream);
+
+		retval = OpenStream(obj_message, PR_RTF_COMPRESSED, 0, &obj_stream);
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+		retval = WrapCompressedRTFStream(&obj_stream, body);
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+		mapi_object_release(&obj_stream);
+		break;
+	default:
+		DEBUG(0, ("Undefined Body\n"));
+		break;
+	}
+
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * Optimized dump message routine (use GetProps rather than GetPropsAll)
+ */
+_PUBLIC_ enum MAPISTATUS octool_message(TALLOC_CTX *mem_ctx,
+					mapi_object_t *obj_message)
+{
+	enum MAPISTATUS			retval;
+	struct SPropTagArray		*SPropTagArray;
+	struct SPropValue		*lpProps;
+	struct SRow			aRow;
+	uint32_t			count;
+	ssize_t				len;
+	/* common email fields */
+	const char			*msgid;
+	const char			*from, *to, *cc, *bcc;
+	const char			*subject;
+	DATA_BLOB			body;
+	const uint8_t			*has_attach;
+	const uint32_t			*cp;
+	const char			*codepage;
+
+	/* Build the array of properties we want to fetch */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x13,
+					  PR_INTERNET_MESSAGE_ID,
+					  PR_INTERNET_MESSAGE_ID_UNICODE,
+					  PR_CONVERSATION_TOPIC,
+					  PR_CONVERSATION_TOPIC_UNICODE,
+					  PR_MSG_EDITOR_FORMAT,
+					  PR_BODY,
+					  PR_BODY_UNICODE,
+					  PR_HTML,
+					  PR_RTF_COMPRESSED,
+					  PR_SENT_REPRESENTING_NAME,
+					  PR_SENT_REPRESENTING_NAME_UNICODE,
+					  PR_DISPLAY_TO,
+					  PR_DISPLAY_TO_UNICODE,
+					  PR_DISPLAY_CC,
+					  PR_DISPLAY_CC_UNICODE,
+					  PR_DISPLAY_BCC,
+					  PR_DISPLAY_BCC_UNICODE,
+					  PR_HASATTACH,
+					  PR_MESSAGE_CODEPAGE);
+	lpProps = talloc_zero(mem_ctx, struct SPropValue);
+	retval = GetProps(obj_message, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	/* Build a SRow structure */
+	aRow.ulAdrEntryPad = 0;
+	aRow.cValues = count;
+	aRow.lpProps = lpProps;
+
+	msgid =	(const char *) octool_get_propval(&aRow, PR_INTERNET_MESSAGE_ID);
+	subject = (const char *) octool_get_propval(&aRow, PR_CONVERSATION_TOPIC);
+
+	retval = octool_get_body(mem_ctx, obj_message, &aRow, &body);
+
+	if (retval != MAPI_E_SUCCESS) {
+		printf("Invalid Message: %s\n", msgid ? msgid : "");
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+	}
+	
+	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);
+
+	has_attach = (const uint8_t *) octool_get_propval(&aRow, PR_HASATTACH);
+	cp = (const uint32_t *) octool_get_propval(&aRow, PR_MESSAGE_CODEPAGE);
+	switch (cp ? *cp : 0) {
+	case CP_USASCII:
+		codepage = "CP_USASCII";
+		break;
+	case CP_UNICODE:
+		codepage = "CP_UNICODE";
+		break;
+	case CP_JAUTODETECT:
+		codepage = "CP_JAUTODETECT";
+		break;
+	case CP_KAUTODETECT:
+		codepage = "CP_KAUTODETECT";
+		break;
+	case CP_ISO2022JPESC:
+		codepage = "CP_ISO2022JPESC";
+		break;
+	case CP_ISO2022JPSIO:
+		codepage = "CP_ISO2022JPSIO";
+		break;
+	default:
+		codepage = "";
+		break;
+	}
+
+	printf("+-------------------------------------+\n");
+	printf("message id: %s\n", msgid ? msgid : "");
+	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");
+	}
+	printf("Codepage: %s\n", codepage);
+	printf("Body:\n");
+	fflush(0);
+	if (body.length) {
+		len = write(1, body.data, body.length);
+		len = write(1, "\n", 1);
+		fflush(0);
+		talloc_free(body.data);
+	} 
+	return MAPI_E_SUCCESS;
+}
+
+
+/*
+ * OpenChange MAPI programs initialization routine
+ */
+_PUBLIC_ struct mapi_session *octool_init_mapi(const char *opt_profname,
+					       const char *opt_password,
+					       uint32_t provider)
+{
+	enum MAPISTATUS		retval;
+	char			*profname = NULL;
+	struct mapi_session	*session = NULL;
+	TALLOC_CTX		*mem_ctx = NULL;
+
+	mem_ctx = talloc_named(NULL, 0, "octool_init_mapi");
+	if (opt_profname) {
+		profname = talloc_strdup(mem_ctx, (char *)opt_profname);
+	} else {
+		retval = GetDefaultProfile(&profname);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			talloc_free(mem_ctx);
+			return NULL;
+		}
+	}
+
+	if (!provider) {
+		retval = MapiLogonEx(&session, profname, opt_password);
+	} else {
+		retval = MapiLogonProvider(&session, profname, opt_password, provider);
+	}
+	MAPIFreeBuffer((char *)profname);
+
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	talloc_free(mem_ctx);
+	return session;
+}

Added: trunk/openchange/utils/openchange-tools.h
===================================================================
--- trunk/openchange/utils/openchange-tools.h	                        (rev 0)
+++ trunk/openchange/utils/openchange-tools.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,61 @@
+/*
+   OpenChange Tools includes
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#ifndef	__OPENCHANGETOOLS_H__
+#define	__OPENCHANGETOOLS_H__
+
+#include <popt.h>
+
+#define	DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
+#define	DEFAULT_TDB	"%s/.openchange/index.tdb"
+#define	DEFAULT_MBOX	"%s/.openchange/mbox"
+#define	DEFAULT_ICAL	"%s/.openchange/ical"
+#define	DEFAULT_VCF	"%s/.openchange/vcf"
+#define	DEFAULT_DIR	"%s/.openchange"
+
+#ifndef __BEGIN_DECLS
+#ifdef __cplusplus
+#define __BEGIN_DECLS		extern "C" {
+#define __END_DECLS		}
+#else
+#define __BEGIN_DECLS
+#define __END_DECLS
+#endif
+#endif
+
+/* Common popt structures for tool */
+extern struct poptOption popt_openchange_version[];
+
+#define	POPT_OPENCHANGE_VERSION { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_openchange_version, 0, "Common openchange options:", NULL },
+
+#ifndef _PUBLIC_
+#define _PUBLIC_
+#endif
+
+__BEGIN_DECLS
+_PUBLIC_ enum MAPISTATUS octool_message(TALLOC_CTX *, mapi_object_t *);
+_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_ struct mapi_session *octool_init_mapi(const char *, const char *, uint32_t);
+__END_DECLS
+
+#endif /*!__OPENCHANGETOOLS_H__ */

Added: trunk/openchange/utils/openchangeclient.c
===================================================================
--- trunk/openchange/utils/openchangeclient.c	                        (rev 0)
+++ trunk/openchange/utils/openchangeclient.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,3366 @@
+/*
+   Stand-alone MAPI application
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2007-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/libmapi.h>
+#include <libmapi/defs_private.h>
+#include <libocpf/ocpf.h>
+#include <samba/popt.h>
+#include <param.h>
+
+#include "openchangeclient.h"
+#include "openchange-tools.h"
+
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <time.h>
+#include <ctype.h>
+
+/**
+ * init sendmail struct
+ */
+
+static void init_oclient(struct oclient *oclient)
+{
+	/* update and delete parameter */
+	oclient->update = NULL;
+	oclient->delete = NULL;
+
+	/* properties list */
+	oclient->props = NULL;
+	
+	/* email related parameter */
+	oclient->subject = NULL;
+	oclient->pr_body = NULL;
+	oclient->pr_html_inline = NULL;
+	oclient->attach = NULL;
+	oclient->attach_num = 0;
+	oclient->store_folder = NULL;
+	
+	/* appointment related parameters */
+	oclient->location = NULL;
+	oclient->dtstart = NULL;
+	oclient->dtend = NULL;
+	oclient->busystatus = -1;
+	oclient->label = -1;
+	oclient->private = false;
+	oclient->freebusy = NULL;
+	oclient->force = false;
+
+	/* contact related parameters */
+	oclient->email = NULL;
+	oclient->full_name = NULL;
+	oclient->card_name = NULL;
+
+	/* task related parameters */
+	oclient->importance = -1;
+	oclient->taskstatus = -1;
+
+	/* note related parameters */
+	oclient->color = -1;
+	oclient->width = -1;
+	oclient->height = -1;
+
+	/* pf related parameters */
+	oclient->pf = false;
+
+	/* folder related parameters */
+	oclient->folder = NULL;
+	oclient->folder_name = NULL;
+	oclient->folder_comment = NULL;
+
+	/* ocpf related parameters */
+	oclient->ocpf_files = NULL;
+	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,
+					       const char *path)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray = NULL;
+	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;
+	const uint32_t		*child;
+	bool			found = false;
+	uint32_t		index;
+	uint32_t		i;
+
+	/* Step 1. Extract the folder list from full path */
+	folder = str_list_make(mem_ctx, path, "/");
+	mapi_object_copy(&obj_folder, obj_container);
+
+	for (i = 0; folder[i]; i++) {
+		found = false;
+
+		mapi_object_init(&obj_htable);
+		retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+		MAPI_RETVAL_IF(retval, GetLastError(), folder);
+
+		SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+						  PR_DISPLAY_NAME,
+						  PR_FID,
+						  PR_FOLDER_CHILD_COUNT);
+		retval = SetColumns(&obj_htable, SPropTagArray);
+		MAPIFreeBuffer(SPropTagArray);
+		MAPI_RETVAL_IF(retval, retval, folder);
+
+		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);
+				child = (const uint32_t *)find_SPropValue_data(&SRowSet.aRow[index], PR_FOLDER_CHILD_COUNT);
+
+				newname = utf8tolinux(mem_ctx, name);
+				if (newname && fid && !strcmp(newname, 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);
+			}
+		}
+
+		mapi_object_release(&obj_htable);
+	}
+
+	talloc_free(folder);
+	MAPI_RETVAL_IF(found == false, MAPI_E_NOT_FOUND, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+static enum MAPISTATUS openchangeclient_getpfdir(TALLOC_CTX *mem_ctx, 
+						 mapi_object_t *obj_store,
+						 mapi_object_t *obj_child,
+						 const char *name)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_pf;
+	mapi_id_t		id_pf;
+
+	retval = GetDefaultPublicFolder(obj_store, &id_pf, olFolderPublicIPMSubtree);
+	if (retval != MAPI_E_SUCCESS) return retval;
+	
+	mapi_object_init(&obj_pf);
+	retval = OpenFolder(obj_store, id_pf, &obj_pf);
+	if (retval != MAPI_E_SUCCESS) return retval;
+	
+	retval = openchangeclient_getdir(mem_ctx, &obj_pf, obj_child, name);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * read a file and store it in the appropriate structure element
+ */
+
+static bool oclient_read_file(TALLOC_CTX *mem_ctx, const char *filename, 
+			      struct oclient *oclient, uint32_t mapitag)
+{
+	struct stat	sb;
+	int		fd;
+
+	/* stat the file */
+	if (stat(filename, &sb) != 0) return false;
+	if ((fd = open(filename, O_RDONLY)) == -1) {
+		printf("Error while opening %s\n", filename);
+		return false;
+	}
+
+	switch (mapitag) {
+	case PR_HTML:
+		oclient->pr_html.lpb = talloc_size(mem_ctx, sb.st_size);
+		oclient->pr_html.cb = read(fd, oclient->pr_html.lpb, sb.st_size);
+		close(fd);
+		break;
+	case PR_ATTACH_DATA_BIN:
+		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) {
+			perror("mmap");
+			close(fd);
+			return false;
+		}
+		oclient->attach[oclient->attach_num].fd = fd;
+		printf("filename = %s (size = %u / %u)\n", filename, oclient->attach[oclient->attach_num].bin.cb, (uint32_t)sb.st_size);
+		close(fd);
+		break;
+	default:
+		printf("unsupported MAPITAG: %s\n", get_proptag_name(mapitag));
+		close(fd);
+		return false;
+		break;
+	}
+
+	return true;
+}
+
+/**
+ * Parse attachments and load their content
+ */
+static bool oclient_parse_attachments(TALLOC_CTX *mem_ctx, const char *filename,
+				      struct oclient *oclient)
+{
+	char		**filenames;
+	char		*tmp = NULL;
+	uint32_t	j;
+
+	if ((tmp = strtok((char *)filename, ";")) == NULL) {
+		printf("Invalid string format [;]\n");
+		return false;
+	}
+
+	filenames = talloc_array(mem_ctx, char *, 2);
+	filenames[0] = strdup(tmp);
+
+	for (j = 1; (tmp = strtok(NULL, ";")) != NULL; j++) {
+		filenames = talloc_realloc(mem_ctx, filenames, char *, j+2);
+		filenames[j] = strdup(tmp);
+	}
+	filenames[j] = 0;
+	oclient->attach = talloc_array(mem_ctx, struct attach, j);
+
+	for (j = 0; filenames[j]; j++) {
+		oclient->attach_num = j;
+		if (oclient_read_file(mem_ctx, filenames[j], oclient, PR_ATTACH_DATA_BIN) == false) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+
+static const char *get_filename(const char *filename)
+{
+	const char *substr;
+
+	if (!filename) return NULL;
+
+	substr = rindex(filename, '/');
+	if (substr) return substr;
+
+	return filename;
+}
+
+
+/**
+ * build unique ID from folder and message
+ */
+static char *build_uniqueID(TALLOC_CTX *mem_ctx, mapi_object_t *obj_folder,
+			    mapi_object_t *obj_message)
+{
+	enum MAPISTATUS		retval;
+	char			*id;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		count;
+	const uint64_t		*mid;
+	const uint64_t		*fid;
+
+	/* retrieve the folder ID */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID);
+	retval = GetProps(obj_folder, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) return NULL;
+	fid = (const uint64_t *)get_SPropValue_data(lpProps);
+
+	/* retrieve the message ID */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_MID);
+	retval = GetProps(obj_message, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	if (GetLastError() != MAPI_E_SUCCESS) return NULL;
+	mid = (const uint64_t *)get_SPropValue_data(lpProps);
+
+	if (!fid || !mid) return NULL;
+
+	id = talloc_asprintf(mem_ctx, "%"PRIX64"/%"PRIX64, *fid, *mid);
+	return id;
+}
+
+
+/**
+ * fetch the user INBOX
+ */
+
+#define	MAX_READ_SIZE	0x1000
+
+static bool store_attachment(mapi_object_t obj_attach, const char *filename, uint32_t size, struct oclient *oclient)
+{
+	TALLOC_CTX	*mem_ctx;
+	enum MAPISTATUS	retval;
+	ssize_t		len;
+	char		*path;
+	mapi_object_t	obj_stream;
+	uint16_t	read_size;
+	int		fd;
+	DIR		*dir;
+	unsigned char  	buf[MAX_READ_SIZE];
+
+	if (!filename || !size) return false;
+
+	mem_ctx = talloc_named(NULL, 0, "store_attachment");
+	mapi_object_init(&obj_stream);
+
+	if (!(dir = opendir(oclient->store_folder))) {
+		if (mkdir(oclient->store_folder, 0700) == -1) return false;
+	} else {
+		closedir(dir);
+	}
+
+	path = talloc_asprintf(mem_ctx, "%s/%s", oclient->store_folder, filename);
+	if ((fd = open(path, O_CREAT|O_WRONLY, S_IWUSR|S_IRUSR)) == -1) return false;
+	talloc_free(path);
+
+	retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	read_size = 0;
+	do {
+		retval = ReadStream(&obj_stream, buf, MAX_READ_SIZE, &read_size);
+		if (retval != MAPI_E_SUCCESS) goto error;
+		len = write(fd, buf, read_size);
+	} while (read_size);
+	
+	close(fd);
+
+	mapi_object_release(&obj_stream);
+	close(fd);
+	talloc_free(mem_ctx);
+	return true;
+
+error:
+	mapi_object_release(&obj_stream);
+	close(fd);
+	talloc_free(mem_ctx);
+	return false;
+}
+
+static enum MAPISTATUS openchangeclient_fetchmail(mapi_object_t *obj_store, 
+						  struct oclient *oclient)
+{
+	enum MAPISTATUS			retval;
+	bool				status;
+	TALLOC_CTX			*mem_ctx;
+	mapi_object_t			obj_tis;
+	mapi_object_t			obj_inbox;
+	mapi_object_t			obj_message;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_tb_attach;
+	mapi_object_t			obj_attach;
+	uint64_t			id_inbox;
+	struct SPropTagArray		*SPropTagArray;
+	struct SRowSet			rowset;
+	struct SRowSet			rowset_attach;
+	uint32_t			i, j;
+	uint32_t			count;
+	const uint8_t			*has_attach;
+	const uint32_t			*attach_num;
+	const char			*attach_filename;
+	const uint32_t			*attach_size;
+	
+	mem_ctx = talloc_named(NULL, 0, "openchangeclient_fetchmail");
+
+	mapi_object_init(&obj_tis);
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_table);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder);
+		MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
+	} else {
+		if (oclient->folder) {
+			retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+			retval = OpenFolder(obj_store, id_inbox, &obj_tis);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+			retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_inbox, oclient->folder);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+		} else {
+			retval = GetReceiveFolder(obj_store, &id_inbox, NULL);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+			retval = OpenFolder(obj_store, id_inbox, &obj_inbox);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+		}
+	}
+
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	printf("MAILBOX (%u messages)\n", count);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+	while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+		count -= rowset.cRows;
+		for (i = 0; i < rowset.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(obj_store,
+					     rowset.aRow[i].lpProps[0].value.d,
+					     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, 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);
+							}
+						}
+						errno = 0;
+					}
+					MAPIFreeBuffer(lpProps);
+				}
+			}
+			mapi_object_release(&obj_message);
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+	mapi_object_release(&obj_tis);
+
+	talloc_free(mem_ctx);
+
+	errno = 0;
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * send a mail to a user whom belongs to the Exchange organization
+ */
+
+static char **get_cmdline_recipients(TALLOC_CTX *mem_ctx, const char *recipients)
+{
+	char		**usernames;
+	char		*tmp = NULL;
+	uint32_t	j = 0;
+
+	/* no recipients */
+	if (!recipients) {
+		return NULL;
+	}
+
+	if ((tmp = strtok((char *)recipients, ",")) == NULL) {
+		DEBUG(2, ("Invalid recipient string format\n"));
+		return NULL;
+	}
+	
+	usernames = talloc_array(mem_ctx, char *, 2);
+	usernames[0] = strdup(tmp);
+	
+	for (j = 1; (tmp = strtok(NULL, ",")) != NULL; j++) {
+		usernames = talloc_realloc(mem_ctx, usernames, char *, j+2);
+		usernames[j] = strdup(tmp);
+	}
+	usernames[j] = 0;
+
+	return (usernames);
+}
+
+/**
+ * We set external recipients at the end of aRow
+ */
+static bool set_external_recipients(TALLOC_CTX *mem_ctx, struct SRowSet *SRowSet, const char *username, enum ulRecipClass RecipClass)
+{
+	uint32_t		last;
+	struct SPropValue	SPropValue;
+
+	SRowSet->aRow = talloc_realloc(mem_ctx, SRowSet->aRow, struct SRow, SRowSet->cRows + 2);
+	last = SRowSet->cRows;
+	SRowSet->aRow[last].cValues = 0;
+	SRowSet->aRow[last].lpProps = talloc_zero(mem_ctx, struct SPropValue);
+	
+	/* PR_OBJECT_TYPE */
+	SPropValue.ulPropTag = PR_OBJECT_TYPE;
+	SPropValue.value.l = MAPI_MAILUSER;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_TYPE */
+	SPropValue.ulPropTag = PR_DISPLAY_TYPE;
+	SPropValue.value.l = 0;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_GIVEN_NAME */
+	SPropValue.ulPropTag = PR_GIVEN_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_7BIT_DISPLAY_NAME */
+	SPropValue.ulPropTag = PR_7BIT_DISPLAY_NAME;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_SMTP_ADDRESS */
+	SPropValue.ulPropTag = PR_SMTP_ADDRESS;
+	SPropValue.value.lpszA = username;
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	/* PR_ADDRTYPE */
+	SPropValue.ulPropTag = PR_ADDRTYPE;
+	SPropValue.value.lpszA = "SMTP";
+	SRow_addprop(&(SRowSet->aRow[last]), SPropValue);
+
+	SetRecipientType(&(SRowSet->aRow[last]), RecipClass);
+
+	SRowSet->cRows += 1;
+	return true;
+}
+
+static bool set_usernames_RecipientType(TALLOC_CTX *mem_ctx, uint32_t *index, struct SRowSet *rowset, 
+					char **usernames, struct SPropTagArray *flaglist,
+					enum ulRecipClass RecipClass)
+{
+	uint32_t	i;
+	uint32_t	count = *index;
+	static uint32_t	counter = 0;
+
+	if (count == 0) counter = 0;
+	if (!usernames) return false;
+
+	for (i = 0; usernames[i]; i++) {
+		if (flaglist->aulPropTag[count] == MAPI_UNRESOLVED) {
+			set_external_recipients(mem_ctx, rowset, usernames[i], RecipClass);
+		}
+		if (flaglist->aulPropTag[count] == MAPI_RESOLVED) {
+			SetRecipientType(&(rowset->aRow[counter]), RecipClass);
+			counter++;
+		}
+		count++;
+	}
+	
+	*index = count;
+	
+	return true;
+}
+
+static char **collapse_recipients(TALLOC_CTX *mem_ctx, struct oclient *oclient)
+{
+	uint32_t	count;
+	uint32_t       	i;
+	char		**usernames;
+
+	if (!oclient->mapi_to && !oclient->mapi_cc && !oclient->mapi_bcc) return NULL;
+
+	count = 0;
+	for (i = 0; oclient->mapi_to && oclient->mapi_to[i]; i++,  count++);
+	for (i = 0; oclient->mapi_cc && oclient->mapi_cc[i]; i++,  count++);
+	for (i = 0; oclient->mapi_bcc && oclient->mapi_bcc[i]; i++, count++);
+
+	usernames = talloc_array(mem_ctx, char *, count + 1);
+	count = 0;
+
+	for (i = 0; oclient->mapi_to && oclient->mapi_to[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_to[i]);
+	}
+
+	for (i = 0; oclient->mapi_cc && oclient->mapi_cc[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_cc[i]);
+	}
+
+	for (i = 0; oclient->mapi_bcc && oclient->mapi_bcc[i]; i++, count++) {
+		usernames[count] = talloc_strdup(mem_ctx, oclient->mapi_bcc[i]);
+	}
+
+	usernames[count++] = 0;
+
+	return usernames;
+}
+
+/**
+ * Write a stream with MAX_READ_SIZE chunks
+ */
+
+#define	MAX_READ_SIZE	0x1000
+
+static bool openchangeclient_stream(TALLOC_CTX *mem_ctx, mapi_object_t obj_parent, 
+				    mapi_object_t obj_stream, uint32_t mapitag, 
+				    uint32_t access_flags, struct Binary_r bin)
+{
+	enum MAPISTATUS	retval;
+	DATA_BLOB	stream;
+	uint32_t	size;
+	uint32_t	offset;
+	uint16_t	read_size;
+
+	/* Open a stream on the parent for the given property */
+	retval = OpenStream(&obj_parent, mapitag, access_flags, &obj_stream);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* WriteStream operation */
+	printf("We are about to write %u bytes in the stream\n", bin.cb);
+	size = MAX_READ_SIZE;
+	offset = 0;
+	while (offset <= bin.cb) {
+		stream.length = size;
+		stream.data = talloc_size(mem_ctx, size);
+		memcpy(stream.data, bin.lpb + offset, size);
+		
+		retval = WriteStream(&obj_stream, &stream, &read_size);
+		talloc_free(stream.data);
+		if (retval != MAPI_E_SUCCESS) return false;
+		printf(".");
+		fflush(0);
+
+		/* Exit when there is nothing left to write */
+		if (!read_size) return true;
+		
+		offset += read_size;
+
+		if ((offset + size) > bin.cb) {
+			size = bin.cb - offset;
+		}
+	}
+
+	return true;
+}
+
+
+#define SETPROPS_COUNT	4
+
+/**
+ * Send a mail
+ */
+
+static enum MAPISTATUS openchangeclient_sendmail(TALLOC_CTX *mem_ctx, 
+						 mapi_object_t *obj_store, 
+						 struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	SPropValue;
+	struct SRowSet		*SRowSet = NULL;
+	struct SPropTagArray   	*flaglist = NULL;
+	mapi_id_t		id_outbox;
+	mapi_object_t		obj_outbox;
+	mapi_object_t		obj_message;
+	mapi_object_t		obj_stream;
+	uint32_t		index = 0;
+	uint32_t		msgflag;
+	struct SPropValue	props[SETPROPS_COUNT];
+	uint32_t		prop_count = 0;
+	uint32_t		editor = 0;
+
+	mapi_object_init(&obj_outbox);
+	mapi_object_init(&obj_message);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_outbox, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		/* Get Sent Items folder but should be using olFolderOutbox */
+		retval = GetDefaultFolder(obj_store, &id_outbox, olFolderSentMail);
+		if (retval != MAPI_E_SUCCESS) return retval;
+
+		/* Open outbox folder */
+		retval = OpenFolder(obj_store, id_outbox, &obj_outbox);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	}
+
+	/* Create the message */
+	retval = CreateMessage(&obj_outbox, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	/* Recipients operations */
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_OBJECT_TYPE,
+					  PR_DISPLAY_TYPE,
+					  PR_7BIT_DISPLAY_NAME,
+					  PR_DISPLAY_NAME,
+					  PR_SMTP_ADDRESS,
+					  PR_GIVEN_NAME);
+
+	oclient->usernames = collapse_recipients(mem_ctx, oclient);
+
+	/* ResolveNames */
+	retval = ResolveNames(mapi_object_get_session(&obj_message), (const char **)oclient->usernames, 
+			      SPropTagArray, &SRowSet, &flaglist, 0);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	if (!SRowSet) {
+		SRowSet = talloc_zero(mem_ctx, struct SRowSet);
+	}
+
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_to, flaglist, MAPI_TO);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_cc, flaglist, MAPI_CC);
+	set_usernames_RecipientType(mem_ctx, &index, SRowSet, oclient->mapi_bcc, flaglist, MAPI_BCC);
+
+	SPropValue.ulPropTag = PR_SEND_INTERNET_ENCODING;
+	SPropValue.value.l = 0;
+	SRowSet_propcpy(mem_ctx, SRowSet, SPropValue);
+
+	/* ModifyRecipients operation */
+	retval = ModifyRecipients(&obj_message, SRowSet);
+	MAPIFreeBuffer(SRowSet);
+	MAPIFreeBuffer(flaglist);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	/* set message properties */
+	msgflag = MSGFLAG_UNSENT;
+	oclient->subject = (!oclient->subject) ? "" : oclient->subject;
+	set_SPropValue_proptag(&props[0], PR_SUBJECT, 
+			       (const void *)oclient->subject);
+	set_SPropValue_proptag(&props[1], PR_MESSAGE_FLAGS, 
+			       (const void *)&msgflag);
+	prop_count = 2;
+
+	/* Set PR_BODY or PR_HTML or inline PR_HTML */
+	if (oclient->pr_body) {
+		editor = EDITOR_FORMAT_PLAINTEXT;
+		set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor);
+
+		if (strlen(oclient->pr_body) > MAX_READ_SIZE) {
+			struct Binary_r	bin;
+
+			bin.lpb = (uint8_t *)oclient->pr_body;
+			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, 
+								   (const void *)oclient->pr_body);
+			prop_count++;
+		}
+	} else if (oclient->pr_html_inline) {
+		editor = EDITOR_FORMAT_HTML;
+		set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor);
+
+		if (strlen(oclient->pr_html_inline) > MAX_READ_SIZE) {
+			struct Binary_r	bin;
+			
+			bin.lpb = (uint8_t *)oclient->pr_html_inline;
+			bin.cb = strlen(oclient->pr_html_inline);
+			openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_HTML, 2, bin);
+		} else {
+			struct SBinary_short bin;
+			
+			bin.cb = strlen(oclient->pr_html_inline);
+			bin.lpb = (uint8_t *)oclient->pr_html_inline;
+			set_SPropValue_proptag(&props[2], PR_HTML, (void *)&bin);
+			prop_count++;
+		}
+		
+	} else if (&oclient->pr_html) {
+		editor = EDITOR_FORMAT_HTML;
+		set_SPropValue_proptag(&props[3], PR_MSG_EDITOR_FORMAT, (const void *)&editor);
+
+		if (oclient->pr_html.cb <= MAX_READ_SIZE) {
+			struct SBinary_short bin;
+
+			bin.cb = oclient->pr_html.cb;
+			bin.lpb = oclient->pr_html.lpb;
+
+			set_SPropValue_proptag(&props[2], PR_HTML, (void *)&bin);
+			prop_count++;
+		} else {
+			mapi_object_init(&obj_stream);
+			openchangeclient_stream(mem_ctx, obj_message, obj_stream, PR_HTML, 2, oclient->pr_html);
+			mapi_object_release(&obj_stream);
+		}
+	}
+
+	retval = SetProps(&obj_message, props, prop_count);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	/* attachment related code */
+	if (oclient->attach) {
+		uint32_t	i;
+
+		for (i = 0; oclient->attach[i].filename; i++) {
+			mapi_object_t		obj_attach;
+			mapi_object_t		obj_stream;
+			struct SPropValue	props_attach[3];
+			uint32_t		count_props_attach;
+
+			mapi_object_init(&obj_attach);
+
+			retval = CreateAttach(&obj_message, &obj_attach);
+			if (retval != MAPI_E_SUCCESS) return retval;
+		
+			props_attach[0].ulPropTag = PR_ATTACH_METHOD;
+			props_attach[0].value.l = ATTACH_BY_VALUE;
+			props_attach[1].ulPropTag = PR_RENDERING_POSITION;
+			props_attach[1].value.l = 0;
+			props_attach[2].ulPropTag = PR_ATTACH_FILENAME;
+			printf("Sending %s:\n", oclient->attach[i].filename);
+			props_attach[2].value.lpszA = get_filename(oclient->attach[i].filename);
+			count_props_attach = 3;
+
+			/* SetProps */
+			retval = SetProps(&obj_attach, props_attach, count_props_attach);
+			if (retval != MAPI_E_SUCCESS) return retval;
+
+			/* Stream operations */
+			openchangeclient_stream(mem_ctx, obj_attach, obj_stream, PR_ATTACH_DATA_BIN, 2, oclient->attach[i].bin);
+
+			/* Save changes on attachment */
+			retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadWrite);
+			if (retval != MAPI_E_SUCCESS) return retval;
+
+			mapi_object_release(&obj_attach);
+		}
+	}
+
+	if (oclient->pf) {
+		retval = SaveChangesMessage(&obj_outbox, &obj_message, KeepOpenReadOnly);
+		if (retval != MAPI_E_SUCCESS) return retval;
+
+	} else {
+		/* Submit the message */
+		retval = SubmitMessage(&obj_message);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	}
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_outbox);
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * delete a mail from user INBOX
+ */
+static bool openchangeclient_deletemail(TALLOC_CTX *mem_ctx,
+					mapi_object_t *obj_store, 
+					struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	mapi_id_t		id_inbox;
+	mapi_id_t		*id_messages;
+	uint32_t		count_messages;
+	uint32_t		count_rows;
+	mapi_object_t		obj_inbox;
+	mapi_object_t		obj_table;
+	uint32_t		len;
+	uint32_t		i;
+
+	if (!oclient->subject) {
+		printf("You need to specify at least a message subject pattern\n");
+		MAPI_RETVAL_IF(!oclient->subject, MAPI_E_INVALID_PARAMETER, NULL);
+	}
+
+	mapi_object_init(&obj_inbox);
+	mapi_object_init(&obj_table);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		retval = GetReceiveFolder(obj_store, &id_inbox, NULL);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_inbox, &obj_inbox);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	while ((retval = QueryRows(&obj_table, 0x10, TBL_ADVANCE, &SRowSet)) == MAPI_E_SUCCESS) {
+		count_rows = SRowSet.cRows;
+		if (!count_rows) break;
+		id_messages = talloc_array(mem_ctx, uint64_t, count_rows);
+		count_messages = 0;
+		
+		len = strlen(oclient->subject);
+
+		for (i = 0; i < count_rows; i++) {
+			if (!strncmp(SRowSet.aRow[i].lpProps[4].value.lpszA, oclient->subject, len)) {
+				id_messages[count_messages] = SRowSet.aRow[i].lpProps[1].value.d;
+				count_messages++;
+			}
+		}
+		if (count_messages) {
+			retval = DeleteMessage(&obj_inbox, id_messages, count_messages);
+			if (retval != MAPI_E_SUCCESS) return false;
+		}
+	}
+
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+
+	return true;
+}
+
+
+static enum MAPISTATUS check_conflict_date(mapi_object_t *obj,
+					   struct FILETIME *ft)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_store;
+	struct mapi_session	*session;
+	struct mapi_session	*session2;
+	bool			conflict;
+			
+	session = mapi_object_get_session(obj);
+	retval = MapiLogonEx(&session2, session->profile->profname, session->profile->password);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	mapi_object_init(&obj_store);
+	retval = OpenPublicFolder(session2, &obj_store);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	retval = IsFreeBusyConflict(&obj_store, ft, &conflict);
+	Logoff(&obj_store);
+
+	if (conflict == true) {
+		printf("[WARNING]: This start date conflicts with another appointment\n");
+		return MAPI_E_INVALID_PARAMETER;
+	}	
+
+	return MAPI_E_SUCCESS;
+}
+
+/**
+ * Send appointment
+ */
+
+static enum MAPISTATUS appointment_SetProps(TALLOC_CTX *mem_ctx, 
+					    mapi_object_t *obj_folder,
+					    mapi_object_t *obj_message, 
+					    struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	*lpProps;
+	struct FILETIME		*start_date;
+	struct FILETIME		*end_date;
+	uint32_t		cValues = 0;
+	NTTIME			nt;
+	struct tm		tm;
+	uint32_t		flag;
+	uint8_t			flag2;
+
+	cValues = 0;
+	lpProps = talloc_array(mem_ctx, struct SPropValue, 2);
+
+	if (oclient->subject) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_CONVERSATION_TOPIC, 
+			       (const void *) oclient->subject);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_NORMALIZED_SUBJECT,
+			       (const void *) oclient->subject);
+	}
+	if (oclient->pr_body) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY, (const void *)oclient->pr_body);
+	}
+	if (oclient->location) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidLocation, (const void *)oclient->location);
+	}
+	if (oclient->dtstart) {
+		if (!strptime(oclient->dtstart, DATE_FORMAT, &tm)) {
+			printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.: 2007-09-17 10:00:00)\n");
+			return MAPI_E_INVALID_PARAMETER;
+		}
+		unix_to_nt_time(&nt, mktime(&tm));
+		start_date = talloc(mem_ctx, struct FILETIME);
+		start_date->dwLowDateTime = (nt << 32) >> 32;
+		start_date->dwHighDateTime = (nt >> 32);
+
+		retval = check_conflict_date(obj_folder, start_date);
+		if (oclient->force == false) {
+			MAPI_RETVAL_IF(retval, retval, NULL);
+		}
+
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_START_DATE, (const void *)start_date);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidCommonStart, (const void *)start_date);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentStartWhole, (const void *) start_date);
+	}
+	if (oclient->dtend) {
+		if (!strptime(oclient->dtend, DATE_FORMAT, &tm)) {
+			printf("Invalid date format: yyyy-mm-dd hh:mm:ss (e.g.:2007-09-17 18:30:00)\n");
+			return MAPI_E_INVALID_PARAMETER;
+		}
+		unix_to_nt_time(&nt, mktime(&tm));
+		end_date = talloc(mem_ctx, struct FILETIME);
+		end_date->dwLowDateTime = (nt << 32) >> 32;
+		end_date->dwHighDateTime = (nt >> 32);
+
+		retval = check_conflict_date(obj_folder, end_date);
+		if (oclient->force == false) {
+			MAPI_RETVAL_IF(retval, retval, NULL);
+		}
+
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_END_DATE, (const void *) end_date);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidCommonEnd, (const void *) end_date);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentEndWhole, (const void *) end_date);
+	}
+
+	if (!oclient->update) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS, (const void *)"IPM.Appointment");
+
+		flag = 1;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_FLAGS, (const void *)&flag);
+
+		flag= MEETING_STATUS_NONMEETING;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentStateFlags, (const void *) &flag);
+
+		flag = 30;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidReminderDelta, (const void *)&flag);
+		
+		/* WARNING needs to replace private */
+		flag2 = oclient->private;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidPrivate, (const void *)&flag2);
+
+		oclient->label = (oclient->label == -1) ? 0 : oclient->label;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentColor, (const void *) &oclient->label);
+
+		oclient->busystatus = (oclient->busystatus == -1) ? 0 : oclient->busystatus;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidBusyStatus, (const void *) &oclient->busystatus);
+	} else {
+		if (oclient->busystatus != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidBusyStatus, (const void *) &oclient->busystatus);
+		}
+		if (oclient->label != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidAppointmentColor, (const void *) &oclient->label);
+		}
+	}
+
+	flag = (oclient->private == true) ? 2 : 0;
+	lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_SENSITIVITY, (const void *)&flag);
+	
+	retval = SetProps(obj_message, lpProps, cValues);
+	MAPIFreeBuffer(lpProps);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+
+static bool openchangeclient_sendappointment(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_calendar;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_calendar;
+	char			*uniq_id;
+
+	mapi_object_init(&obj_calendar);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_calendar, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return false;
+	} else {
+		/* Open Calendar default folder */
+		retval = GetDefaultFolder(obj_store, &id_calendar, olFolderCalendar);
+		if (retval != MAPI_E_SUCCESS) return false;
+		
+		retval = OpenFolder(obj_store, id_calendar, &obj_calendar);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* Create calendar message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_calendar, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set calendar message properties */
+	retval = appointment_SetProps(mem_ctx, &obj_calendar, &obj_message, oclient);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = SaveChangesMessage(&obj_calendar, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch and Display the message unique ID */
+	uniq_id = build_uniqueID(mem_ctx, &obj_calendar, &obj_message);
+	printf("    %-25s: %s\n", "Unique ID", uniq_id);
+	fflush(0);
+	talloc_free(uniq_id);
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_calendar);
+	
+	return true;
+}
+
+/**
+ * Create a contact
+ */
+static enum MAPISTATUS contact_SetProps(TALLOC_CTX *mem_ctx,
+					mapi_object_t *obj_folder,
+					mapi_object_t *obj_message,
+					struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	*lpProps;
+	struct mapi_nameid	*nameid;
+	struct SPropTagArray	*SPropTagArray;
+	uint32_t		cValues = 0;
+
+	/* Build the list of named properties we want to set */
+	nameid = mapi_nameid_new(mem_ctx);
+	mapi_nameid_string_add(nameid, "urn:schemas:contacts:fileas", PS_PUBLIC_STRINGS);
+
+	/* GetIDsFromNames and map property types */
+	SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+	retval = GetIDsFromNames(obj_folder, nameid->count,
+				 nameid->nameid, 0, &SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return retval;
+	mapi_nameid_SPropTagArray(nameid, SPropTagArray);
+	MAPIFreeBuffer(nameid);
+
+	cValues = 0;
+	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, 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);
+	}
+	if (oclient->email) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidEmail1OriginalDisplayName, (const void *)oclient->email);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidEmail1EmailAddress, (const void *)oclient->email);
+	}
+	if (!oclient->update) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS, (const void *)"IPM.Contact");
+	}
+	retval = SetProps(obj_message, lpProps, cValues);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPIFreeBuffer(lpProps);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+	
+	return MAPI_E_SUCCESS;
+}
+
+static bool openchangeclient_sendcontact(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_contact;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_contact;	
+	char			*uniq_id;
+
+	mapi_object_init(&obj_contact);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_contact, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		/* Open Contact default folder */
+		retval = GetDefaultFolder(obj_store, &id_contact, olFolderContacts);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_contact, &obj_contact);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* Create contact mesage */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_contact, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set contact message properties */
+	retval = contact_SetProps(mem_ctx, &obj_contact, &obj_message, oclient);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = SaveChangesMessage(&obj_contact, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch and Display the message unique ID */
+	uniq_id = build_uniqueID(mem_ctx, &obj_contact, &obj_message);
+	printf("    %-25s: %s\n", "Unique ID", uniq_id);
+	fflush(0);
+	talloc_free(uniq_id);
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_contact);
+
+	return true;
+}
+
+/**
+ * Create task
+ */
+static enum MAPISTATUS task_SetProps(TALLOC_CTX *mem_ctx,
+					mapi_object_t *obj_message,
+					struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	*lpProps;
+	struct FILETIME		*start_date;
+	struct FILETIME		*end_date;
+	uint32_t		cValues = 0;
+	NTTIME			nt;
+	struct tm		tm;
+
+	cValues = 0;
+	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);
+	}
+
+	if (oclient->dtstart) {
+		if (!strptime(oclient->dtstart, DATE_FORMAT, &tm)) {
+			printf("Invalid date format (e.g.: 2007-06-01 22:30:00)\n");
+			return MAPI_E_INVALID_PARAMETER;
+		}
+		unix_to_nt_time(&nt, mktime(&tm));
+		start_date = talloc(mem_ctx, struct FILETIME);
+		start_date->dwLowDateTime = (nt << 32) >> 32;
+		start_date->dwHighDateTime = (nt >> 32);		
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStartDate, (const void *)start_date);
+	}
+
+	if (oclient->dtend) {
+		if (!strptime(oclient->dtend, DATE_FORMAT, &tm)) {
+			printf("Invalid date format (e.g.: 2007-06-01 22:30:00)\n");
+			return MAPI_E_INVALID_PARAMETER;
+		}
+		unix_to_nt_time(&nt, mktime(&tm));
+		end_date = talloc(mem_ctx, struct FILETIME);
+		end_date->dwLowDateTime = (nt << 32) >> 32;
+		end_date->dwHighDateTime = (nt >> 32);
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskDueDate, (const void *)end_date);
+	}
+
+	if (oclient->pr_body) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_BODY, (const void *)oclient->pr_body);
+	}
+
+	if (!oclient->update) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS, (const void *)"IPM.Task");
+		oclient->importance = (oclient->importance == -1) ? 1 : oclient->importance;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_IMPORTANCE, (const void *)&oclient->importance);
+		oclient->taskstatus = (oclient->taskstatus == -1) ? 0 : oclient->taskstatus;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStatus, (const void *)&oclient->taskstatus);
+	} else {
+		if (oclient->importance != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_IMPORTANCE, (const void *)&oclient->importance);
+		}
+		if (oclient->taskstatus != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidTaskStatus, (const void *)&oclient->taskstatus);
+		}
+	}
+
+	retval = SetProps(obj_message, lpProps, cValues);
+	MAPIFreeBuffer(lpProps);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+
+	return MAPI_E_SUCCESS;
+}
+
+static bool openchangeclient_sendtask(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_task;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_task;	
+	char			*uniq_id;
+
+	mapi_object_init(&obj_task);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_task, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		/* Open Contact default folder */
+		retval = GetDefaultFolder(obj_store, &id_task, olFolderTasks);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_task, &obj_task);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* Create contact mesage */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_task, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set contact properties */
+	retval = task_SetProps(mem_ctx, &obj_message, oclient);
+
+	retval = SaveChangesMessage(&obj_task, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch and Display the message unique ID */
+	uniq_id = build_uniqueID(mem_ctx, &obj_task, &obj_message);
+	printf("    %-25s: %s\n", "Unique ID", uniq_id);
+	fflush(0);
+	talloc_free(uniq_id);
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_task);
+
+	return true;
+}
+
+
+/**
+ * Send notes
+ */
+static enum MAPISTATUS note_SetProps(TALLOC_CTX *mem_ctx,
+					mapi_object_t *obj_message,
+					struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	struct SPropValue	*lpProps;
+	uint32_t		cValues = 0;
+	uint32_t		value;
+
+	cValues = 0;
+	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);
+	}
+
+	if (!oclient->update) {
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_CLASS, (const void *)"IPM.StickyNote");
+
+		value = 1;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_MESSAGE_FLAGS, (const void *)&value);
+
+		value = 768;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PR_ICON_INDEX, (const void *)&value);
+		
+		value = 272;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidSideEffects, (const void *)&value);
+
+		oclient->color = (oclient->color == -1) ? olYellow : oclient->color;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteColor, (const void *)&oclient->color);
+
+		oclient->width = (oclient->width == -1) ? 166 : oclient->width;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteWidth, (const void *)&oclient->width);
+
+		oclient->height = (oclient->height == -1) ? 200 : oclient->height;
+		lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteHeight, (const void *)&oclient->height);
+
+	} else {
+		if (oclient->color != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteColor, (const void *)&oclient->color);
+		}
+		if (oclient->width != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteWidth, (const void *)&oclient->width);
+		}
+		if (oclient->height != -1) {
+			lpProps = add_SPropValue(mem_ctx, lpProps, &cValues, PidLidNoteHeight, (const void *)&oclient->height);
+		}
+	}
+
+	
+	retval = SetProps(obj_message, lpProps, cValues);
+	MAPIFreeBuffer(lpProps);
+	MAPI_RETVAL_IF(retval, retval, NULL);
+	
+	return MAPI_E_SUCCESS;
+}
+
+static bool openchangeclient_sendnote(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_note;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_note;	
+	char			*uniq_id;
+
+	mapi_object_init(&obj_note);
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_note, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		/* Open Contact default folder */
+		retval = GetDefaultFolder(obj_store, &id_note, olFolderNotes);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_note, &obj_note);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* Create contact mesage */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_note, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Set Note message properties */
+	retval = note_SetProps(mem_ctx, &obj_message, oclient);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = SaveChangesMessage(&obj_note, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Fetch and Display the message unique ID */
+	uniq_id = build_uniqueID(mem_ctx, &obj_note, &obj_message);
+	printf("    %-25s: %s\n", "Unique ID", uniq_id);
+	fflush(0);
+	talloc_free(uniq_id);
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_note);
+
+	return true;
+}
+
+
+static const char *get_container_class(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	struct SPropTagArray	*SPropTagArray;
+	struct SPropValue	*lpProps;
+	uint32_t		count;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_CONTAINER_CLASS);
+	retval = GetProps(&obj_folder, SPropTagArray, &lpProps, &count);
+	MAPIFreeBuffer(SPropTagArray);
+	if ((lpProps[0].ulPropTag != PR_CONTAINER_CLASS) || (retval != MAPI_E_SUCCESS)) {
+		errno = 0;
+		return IPF_NOTE;
+	}
+	return lpProps[0].value.lpszA;
+}
+
+static bool get_child_folders(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count)
+{
+	enum MAPISTATUS		retval;
+	bool			ret;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		rowset;
+	const char	       	*name;
+	char			*newname;
+	const char		*comment;
+	const uint32_t		*total;
+	const uint32_t		*unread;
+	const uint32_t		*child;
+	uint32_t		index;
+	const uint64_t		*fid;
+	int			i;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x6,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_COMMENT,
+					  PR_CONTENT_UNREAD,
+					  PR_CONTENT_COUNT,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	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);
+			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);
+
+			for (i = 0; i < count; i++) {
+				printf("|   ");
+			}
+			newname = utf8tolinux(mem_ctx, name);
+			printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%"PRIx64"]\n", newname, comment, *total, *unread,
+			       get_container_class(mem_ctx, parent, *fid), *fid);
+			MAPIFreeBuffer(newname);
+			if (*child) {
+				ret = get_child_folders(mem_ctx, &obj_folder, *fid, count + 1);
+				if (ret == false) return ret;
+			}
+			
+		}
+	}
+	return true;
+}
+
+static bool get_child_folders_pf(TALLOC_CTX *mem_ctx, mapi_object_t *parent, mapi_id_t folder_id, int count)
+{
+	enum MAPISTATUS		retval;
+	bool			ret;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		rowset;
+	const char	       	*name;
+	char			*newname;
+	const uint32_t		*child;
+	uint32_t		index;
+	const uint64_t		*fid;
+	int			i;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	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);
+			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%"PRIx64"]\n", newname, *fid);
+			MAPIFreeBuffer(newname);
+			if (*child) {
+				ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
+				if (ret == false) return ret;
+			}
+			
+		}
+	}
+	return true;
+}
+
+
+static bool openchangeclient_pf(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store)
+{
+	enum MAPISTATUS			retval;
+	mapi_id_t			id_pubroot;
+
+	retval = GetDefaultPublicFolder(obj_store, &id_pubroot, olFolderPublicRoot);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	return get_child_folders_pf(mem_ctx, obj_store, id_pubroot, 0);
+}
+
+
+static bool openchangeclient_mailbox(TALLOC_CTX *mem_ctx, 
+				     mapi_object_t *obj_store)
+{
+	enum MAPISTATUS			retval;
+	mapi_id_t			id_mailbox;
+	struct SPropTagArray		*SPropTagArray;
+	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);
+	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;
+	} else {
+		return false;
+	}
+
+	/* Prepare the directory listing */
+	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);
+	return get_child_folders(mem_ctx, obj_store, id_mailbox, 0);
+}
+
+static bool openchangeclient_fetchitems(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, const char *item,
+					struct oclient *oclient)
+{
+	enum MAPISTATUS			retval;
+	mapi_object_t			obj_tis;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_message;
+	mapi_id_t			fid;
+	uint32_t			olFolder = 0;
+	struct SRowSet			SRowSet;
+	struct SPropTagArray		*SPropTagArray;
+	struct mapi_SPropValue_array	properties_array;
+	uint32_t			count;
+	uint32_t       			i;
+	char				*id;
+	
+	if (!item) return false;
+
+	mapi_object_init(&obj_tis);
+	mapi_object_init(&obj_folder);
+
+	for (i = 0; defaultFolders[i].olFolder; i++) {
+		if (!strncasecmp(defaultFolders[i].container_class, item, strlen(defaultFolders[i].container_class))) {
+			olFolder = defaultFolders[i].olFolder;
+		}
+	}
+	
+	if (!olFolder) return false;
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_folder, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		if (oclient->folder) {
+			retval = GetDefaultFolder(obj_store, &fid, olFolderTopInformationStore);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+			retval = OpenFolder(obj_store, fid, &obj_tis);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+			retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder);
+			MAPI_RETVAL_IF(retval, retval, mem_ctx);
+		} else {
+			retval = GetDefaultFolder(obj_store, &fid, olFolder);
+			if (retval != MAPI_E_SUCCESS) return false;
+
+			/* We now open the folder */
+			retval = OpenFolder(obj_store, fid, &obj_folder);
+			if (retval != MAPI_E_SUCCESS) return false;
+		}
+	}
+
+	/* Operations on the  folder */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_folder, &obj_table, 0, &count);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	printf("MAILBOX (%u messages)\n", count);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
+					  PR_FID,
+					  PR_MID,
+					  PR_INST_ID,
+					  PR_INSTANCE_NUM,
+					  PR_SUBJECT,
+					  PR_MESSAGE_CLASS,
+					  PR_RULE_MSG_PROVIDER,
+					  PR_RULE_MSG_NAME);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) {
+		count -= SRowSet.cRows;
+		for (i = 0; i < SRowSet.cRows; i++) {
+			mapi_object_init(&obj_message);
+			retval = OpenMessage(&obj_folder, 
+					     SRowSet.aRow[i].lpProps[0].value.d,
+					     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;
+					}
+					talloc_free(id);
+					mapi_object_release(&obj_message);
+				}
+			}
+		}
+	}
+	
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_tis);
+
+	return true;
+}
+
+/**
+ * Update Item
+ *
+ * Edit the existing item specified on command line.
+ * The function first loops over the mailbox, looking for the folder
+ * ID, then it looks for the particular message ID. It finally opens
+ * it, set properties and save the message.
+ *
+ */
+static enum MAPISTATUS folder_lookup(TALLOC_CTX *mem_ctx,
+				     uint64_t sfid,
+				     mapi_object_t *obj_parent,
+				     mapi_id_t folder_id,
+				     mapi_object_t *obj_ret)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		i;
+	const uint64_t		*fid;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(obj_parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_FID);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows)) {
+		for (i = 0; i < SRowSet.cRows; i++) {
+			fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID);
+			if (fid && *fid == sfid) {
+				retval = OpenFolder(&obj_folder, *fid, obj_ret);
+				mapi_object_release(&obj_htable);
+				mapi_object_release(&obj_folder);
+				return MAPI_E_SUCCESS;
+			} else {
+				retval = folder_lookup(mem_ctx, sfid, &obj_folder, *fid, obj_ret);
+				if (retval == MAPI_E_SUCCESS) {
+					mapi_object_release(&obj_htable);
+					mapi_object_release(&obj_folder);
+					return MAPI_E_SUCCESS;
+				}
+			}
+		}
+	}
+
+	mapi_object_release(&obj_htable);
+	mapi_object_release(&obj_folder);
+
+	errno = MAPI_E_NOT_FOUND;
+	return MAPI_E_NOT_FOUND;
+}
+
+static enum MAPISTATUS message_lookup(TALLOC_CTX *mem_ctx, 
+				      uint64_t smid,
+				      mapi_object_t *obj_folder, 
+				      mapi_object_t *obj_message)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		SRowSet;
+	uint32_t		i;
+	const uint64_t		*fid;
+	const uint64_t		*mid;
+
+	mapi_object_init(&obj_htable);
+	retval = GetContentsTable(obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2, PR_FID, PR_MID);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return retval;
+
+	while (((retval = QueryRows(&obj_htable, 0x32, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) && SRowSet.cRows) {
+		for (i = 0; i < SRowSet.cRows; i++) {
+			fid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_FID);
+			mid = (const uint64_t *)find_SPropValue_data(&SRowSet.aRow[i], PR_MID);
+			if (mid && *mid == smid) {
+				retval = OpenMessage(obj_folder, *fid, *mid, obj_message, MAPI_MODIFY);
+				mapi_object_release(&obj_htable);
+				return retval;
+			}
+		}
+	}
+
+	mapi_object_release(&obj_htable);
+
+	errno = MAPI_E_NOT_FOUND;
+	return MAPI_E_NOT_FOUND;
+}
+
+static bool openchangeclient_updateitem(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store,
+					struct oclient *oclient, const char *container_class)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_tis;
+	char			*fid_str;
+	uint64_t		fid;
+	uint64_t		mid;
+	const char		*item = NULL;
+
+	item = oclient->update;
+
+	if (!item) {
+		DEBUG(0, ("Missing ID\n"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	if (!container_class) {
+		DEBUG(0, ("Missing container class\n"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	fid_str = strsep((char **)&item, "/");
+	if (!fid_str || !item) {
+		DEBUG(0, ("    Invalid ID: %s\n", fid_str ? fid_str : "null"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	fid = strtoull(fid_str, NULL, 16);
+	mid = strtoull(item, NULL, 16);
+
+	/* Step 1: search the folder from Top Information Store */
+	mapi_object_init(&obj_folder);
+	retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 2: search the message */
+	mapi_object_init(&obj_message);
+	retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 3: edit the message */
+	if (!strcmp(container_class, IPF_APPOINTMENT)) {
+		retval = appointment_SetProps(mem_ctx, &obj_folder, &obj_message, oclient);
+	} else if (!strcmp(container_class, IPF_CONTACT)) {
+		retval = contact_SetProps(mem_ctx, &obj_folder, &obj_message, oclient);
+	} else if (!strcmp(container_class, IPF_TASK)) {
+		retval = task_SetProps(mem_ctx, &obj_message, oclient);
+	} else if (!strcmp(container_class, IPF_STICKYNOTE)) {
+		retval = note_SetProps(mem_ctx, &obj_message, oclient);
+	}
+
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 4: save the message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+
+	return true;
+}
+
+/**
+ * Delete an item given its unique ID
+ */
+static bool openchangeclient_deleteitems(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, 
+					 struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	mapi_id_t		id_tis;
+	char			*fid_str;
+	uint64_t		fid;
+	uint64_t		mid;
+	const char		*item = NULL;
+
+	item = oclient->delete;
+
+	if (!item) {
+		DEBUG(0, ("Missing ID\n"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+	
+	fid_str = strsep((char **)&item, "/");
+	if (!fid_str || !item) {
+		DEBUG(0, ("    Invalid ID: %s\n", fid_str ? fid_str : "null"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	fid = strtoull(fid_str, NULL, 16);
+	mid = strtoull(item, NULL, 16);
+
+	/* Step 1: search the folder from Top Information Store */
+	mapi_object_init(&obj_folder);
+	retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	/* Step 2: search the message within returned folder */
+	mapi_object_init(&obj_message);
+	retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 3: delete the message */
+	retval = DeleteMessage(&obj_folder, &mid, 1);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+
+	return true;
+}
+
+
+/**
+ * Dump email
+ * 
+ * Assume msg is received in Inbox folder since we only register
+ * notifications for this folder.
+ *
+ */
+
+static enum MAPISTATUS openchangeclient_findmail(mapi_object_t *obj_store, 
+						   mapi_id_t msgid)
+{
+	enum MAPISTATUS			retval;
+	TALLOC_CTX			*mem_ctx;
+	struct SRowSet			SRowSet;
+	struct SPropValue		*lpProp;
+	struct mapi_SPropValue_array	properties_array;
+	mapi_id_t			fid;
+	const mapi_id_t			*mid;
+	mapi_object_t			obj_inbox;
+	mapi_object_t			obj_table;
+	mapi_object_t			obj_message;
+	struct SPropTagArray		*SPropTagArray = NULL;
+	uint32_t			count;
+	uint32_t			i;
+	char				*id;
+
+	mem_ctx = talloc_named(NULL, 0, "openchangeclient_findmail");
+
+	/* Get Inbox folder */
+	retval = GetDefaultFolder(obj_store, &fid, olFolderInbox);
+	MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
+
+	/* Open Inbox */
+	mapi_object_init(&obj_inbox);
+	retval = OpenFolder(obj_store, fid, &obj_inbox);
+	MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
+
+	/* Retrieve contents table */
+	mapi_object_init(&obj_table);
+	retval = GetContentsTable(&obj_inbox, &obj_table, 0, &count);
+	MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
+					  PR_FID,
+					  PR_MID);
+	retval = SetColumns(&obj_table, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
+
+	while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) {
+		for (i = 0; i < SRowSet.cRows; i++) {
+			lpProp = get_SPropValue_SRowSet(&SRowSet, PR_MID);
+			if (lpProp != NULL) {
+				mid = (const uint64_t *)get_SPropValue(lpProp, PR_MID);
+				if (*mid == msgid) {
+					mapi_object_init(&obj_message);
+					retval = OpenMessage(obj_store,
+							     SRowSet.aRow[i].lpProps[0].value.d,
+							     SRowSet.aRow[i].lpProps[1].value.d,
+							     &obj_message, 0);
+					if (GetLastError() == MAPI_E_SUCCESS) {
+						retval = GetPropsAll(&obj_message, &properties_array);
+						if (retval != MAPI_E_SUCCESS) return retval;
+						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);
+						mapi_object_release(&obj_message);
+						talloc_free(id);
+
+						goto end;
+					}
+					mapi_object_release(&obj_message);
+				}
+			}
+		}
+	}
+end:
+	mapi_object_release(&obj_table);
+	mapi_object_release(&obj_inbox);
+
+	talloc_free(mem_ctx);
+	return MAPI_E_SUCCESS;
+}
+
+
+static int callback(uint16_t NotificationType, void *NotificationData, void *private_data)
+{
+	struct NewMailNotification	*newmail;
+	struct HierarchyTableChange    	*htable;
+	struct ContentsTableChange     	*ctable;
+	struct ContentsTableChange     	*stable;
+	enum MAPISTATUS			retval;
+
+	switch(NotificationType) {
+	case fnevNewMail:
+	case fnevNewMail|fnevMbit:
+		DEBUG(0, ("[+] New mail Received\n"));
+		newmail = (struct NewMailNotification *) NotificationData;
+		mapidump_newmail(newmail, "\t");
+		retval = openchangeclient_findmail((mapi_object_t *)private_data, newmail->MID);
+		mapi_errstr("openchangeclient_findmail", GetLastError());
+		break;
+	case fnevObjectCreated:
+		DEBUG(0, ("[+] Folder Created\n"));
+		break;
+	case fnevObjectDeleted:
+		DEBUG(0, ("[+] Folder Deleted\n"));
+		break;
+	case fnevObjectModified:
+	case fnevTbit|fnevObjectModified:
+	case fnevUbit|fnevObjectModified:
+	case fnevTbit|fnevUbit|fnevObjectModified:
+		DEBUG(0, ("[+] Folder Modified\n"));
+		break;
+	case fnevObjectMoved:
+		DEBUG(0, ("[+] Folder Moved\n"));
+		break;
+	case fnevObjectCopied:
+		DEBUG(0, ("[+] Folder Copied\n"));
+		break;
+	case fnevSearchComplete:
+		DEBUG(0, ("[+] Search complete in search folder\n"));
+		break;
+	case fnevTableModified:
+		htable = (struct HierarchyTableChange *) NotificationData;
+		DEBUG(0, ("[+] Hierarchy Table: "));
+		switch (htable->TableEvent) {
+		case TABLE_CHANGED:
+			DEBUG(0, (" changed\n"));
+			break;
+		case TABLE_ROW_ADDED:
+			DEBUG(0, ("row added\n"));
+			break;
+		case TABLE_ROW_DELETED:
+			DEBUG(0, ("row deleted\n"));
+			break;
+		case TABLE_ROW_MODIFIED:
+			DEBUG(0, ("row modified\n"));
+			break;
+		case TABLE_RESTRICT_DONE:
+			DEBUG(0, ("restriction done\n"));
+			break;
+		default:
+			DEBUG(0, ("\n"));
+			break;
+		}
+		break;
+	case fnevStatusObjectModified:
+		DEBUG(0, ("[+] ICS Notification\n"));
+		break;
+	case fnevMbit|fnevObjectCreated:
+		DEBUG(0, ("[+] Message created\n"));
+		break;
+	case fnevMbit|fnevObjectDeleted:
+		DEBUG(0, ("[+] Message deleted\n"));
+	case fnevMbit|fnevObjectModified:
+		DEBUG(0, ("[+] Message modified\n"));
+	case fnevMbit|fnevObjectMoved:
+		DEBUG(0, ("[+] Message moved\n"));
+	case fnevMbit|fnevObjectCopied:
+		DEBUG(0, ("[+] Message copied\n"));
+	case fnevMbit|fnevTableModified:
+		ctable = (struct ContentsTableChange *) NotificationData;
+		DEBUG(0, ("[+] Contents Table: "));
+		switch (ctable->TableEvent) {
+		case TABLE_CHANGED:
+			DEBUG(0, (" changed\n"));
+			break;
+		case TABLE_ROW_ADDED:
+			DEBUG(0, ("row added\n"));
+			break;
+		case TABLE_ROW_DELETED:
+			DEBUG(0, ("row deleted\n"));
+			break;
+		case TABLE_ROW_MODIFIED:
+			DEBUG(0, ("row modified\n"));
+			break;
+		case TABLE_RESTRICT_DONE:
+			DEBUG(0, ("restriction done\n"));
+			break;
+		default:
+			DEBUG(0, ("\n"));
+			break;
+		}
+		break;
+	case fnevMbit|fnevSbit|fnevObjectDeleted:
+		DEBUG(0, ("[+] A message is no longer part of a search folder\n"));
+		break;
+	case fnevMbit|fnevSbit|fnevObjectModified:
+		DEBUG(0, ("[+] A property on a message in a search folder has changed\n"));
+	case fnevMbit|fnevSbit|fnevTableModified:
+		stable = (struct ContentsTableChange *) NotificationData;
+		DEBUG(0, ("[+] Search Table: "));
+		switch (stable->TableEvent) {
+		case TABLE_CHANGED:
+			DEBUG(0, (" changed\n"));
+			break;
+		case TABLE_ROW_ADDED:
+			DEBUG(0, ("row added\n"));
+			break;
+		case TABLE_ROW_DELETED:
+			DEBUG(0, ("row deleted\n"));
+			break;
+		case TABLE_ROW_MODIFIED:
+			DEBUG(0, ("row modified\n"));
+			break;
+		case TABLE_RESTRICT_DONE:
+			DEBUG(0, ("restriction done\n"));
+			break;
+		default:
+			DEBUG(0, ("\n"));
+			break;
+		}
+		break;
+	default:
+		printf("[+] Unsupported notification (0x%x)\n", NotificationType);
+		break;
+	}
+
+	return 0;
+}
+
+
+static bool openchangeclient_notifications(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS	retval;
+	mapi_object_t	obj_inbox;
+	mapi_id_t	fid;
+	uint32_t	ulConnection;
+	uint16_t	ulEventMask;
+
+	/* Register notification */
+	retval = RegisterNotification(0);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	if (oclient->pf == true) {
+		retval = openchangeclient_getpfdir(mem_ctx, obj_store, &obj_inbox, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return retval;
+	} else {
+		/* Retrieve Inbox folder ID */
+		retval = GetDefaultFolder(obj_store, &fid, olFolderInbox);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		/* Open Inbox folder */
+		mapi_object_init(&obj_inbox);
+		retval = OpenFolder(obj_store, fid, &obj_inbox);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	/* subscribe Inbox to receive newmail notifications */
+	ulEventMask = fnevNewMail|fnevObjectCreated|fnevObjectDeleted|
+		fnevObjectModified|fnevObjectMoved|fnevObjectCopied|
+		fnevSearchComplete|fnevTableModified|fnevStatusObjectModified;
+	retval = Subscribe(obj_store, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback);
+	retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* wait for notifications: infinite loop */
+	retval = MonitorNotification(mapi_object_get_session(obj_store), (void *)obj_store);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = Unsubscribe(mapi_object_get_session(obj_store), ulConnection);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_inbox);
+
+	return true;
+}
+
+
+static bool openchangeclient_mkdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_child;
+	mapi_object_t		obj_tis;
+	mapi_id_t		id_inbox;
+
+	mapi_object_init(&obj_tis);
+	mapi_object_init(&obj_folder);
+	mapi_object_init(&obj_child);
+
+	if (oclient->folder) {
+		retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_inbox, &obj_tis);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return false;
+	} else {
+		retval = GetDefaultFolder(obj_store, &id_inbox, olFolderInbox);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = OpenFolder(obj_store, id_inbox, &obj_folder);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+
+	retval = CreateFolder(&obj_folder, FOLDER_GENERIC, oclient->folder_name, 
+			      oclient->folder_comment, OPEN_IF_EXISTS, &obj_child);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_child);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_tis);
+
+	return true;
+}
+
+
+static bool openchangeclient_rmdir(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_child;
+	mapi_object_t		obj_tis;
+	mapi_id_t		id_inbox;
+
+	mapi_object_init(&obj_tis);
+	mapi_object_init(&obj_folder);
+	mapi_object_init(&obj_child);
+
+	if (oclient->folder) {
+		printf("Removing folder within %s\n", oclient->folder);
+		retval = GetDefaultFolder(obj_store, &id_inbox, olFolderTopInformationStore);
+		if (retval != MAPI_E_SUCCESS) return false;
+		
+		retval = OpenFolder(obj_store, id_inbox, &obj_tis);
+		if (retval != MAPI_E_SUCCESS) return false;
+
+		retval = openchangeclient_getdir(mem_ctx, &obj_tis, &obj_folder, oclient->folder);
+		if (retval != MAPI_E_SUCCESS) return false;
+	} else {
+		retval = GetDefaultFolder(obj_store, &id_inbox, olFolderInbox);
+		if (retval != MAPI_E_SUCCESS) return false;
+		
+		retval = OpenFolder(obj_store, id_inbox, &obj_folder);
+		if (retval != MAPI_E_SUCCESS) return false;
+	}
+	
+	retval = openchangeclient_getdir(mem_ctx, &obj_folder, &obj_child, oclient->folder_name);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	retval = EmptyFolder(&obj_child);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	printf("obj_child fid = 0x%"PRIx64"\n", mapi_object_get_id(&obj_child));
+
+	retval = DeleteFolder(&obj_folder, mapi_object_get_id(&obj_child),
+			      DEL_FOLDERS, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	mapi_object_release(&obj_child);
+	mapi_object_release(&obj_folder);
+	mapi_object_release(&obj_tis);
+	
+	return true;
+}
+
+static bool openchangeclient_userlist(TALLOC_CTX *mem_ctx, 
+				      struct mapi_session *session)
+{
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		*SRowSet;
+	enum MAPISTATUS		retval;
+	uint32_t		i;
+	uint32_t		count;
+	uint8_t			ulFlags;
+
+	SPropTagArray = set_SPropTagArray(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 = 0x7;
+	ulFlags = TABLE_START;
+	do {
+		count += 0x2;
+		retval = GetGALTable(session, SPropTagArray, &SRowSet, count, ulFlags);
+		if (SRowSet->cRows) {
+			for (i = 0; i < SRowSet->cRows; i++) {
+				mapidump_PAB_entry(&SRowSet->aRow[i]);
+			}
+		}
+		ulFlags = TABLE_CUR;
+		MAPIFreeBuffer(SRowSet);
+	} while (SRowSet->cRows == count);
+	mapi_errstr("GetPABTable", GetLastError());
+
+	MAPIFreeBuffer(SPropTagArray);
+
+	return true;
+}
+
+
+static bool openchangeclient_ocpf_syntax(struct oclient *oclient)
+{
+	int			ret;
+	struct ocpf_file	*element;
+
+	/* Sanity checks */
+	if (!oclient->ocpf_files || !oclient->ocpf_files->next) {
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	/* Step 1. Initialize OCPF context */
+	ret = ocpf_init();
+	if (ret == -1) {
+		errno = MAPI_E_CALL_FAILED;
+		return false;
+	}
+
+	/* Step2. Parse OCPF files */
+	for (element = oclient->ocpf_files; element->next; element = element->next) {
+		ret = ocpf_parse(element->filename);
+		if (ret == -1) {
+			errno = MAPI_E_INVALID_PARAMETER;
+			return false;
+		}
+	}
+
+	/* Step3. Dump OCPF contents */
+	ocpf_dump();
+
+	/* Step4. Release OCPF context */
+	ret = ocpf_release();
+	if (ret == -1) {
+		errno = MAPI_E_CALL_FAILED;
+		return false;
+	}
+
+	return true;
+}
+
+
+static bool openchangeclient_ocpf_sender(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS		retval;
+	int			ret;
+	struct ocpf_file	*element;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_message;
+	uint32_t		cValues = 0;
+	struct SPropValue	*lpProps;
+
+	/* Sanity Check */
+	if (!oclient->ocpf_files || !oclient->ocpf_files->next) {
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	/* Step1. Initialize OCPF context */
+	ret = ocpf_init();
+	if (ret == -1) {
+		errno = MAPI_E_CALL_FAILED;
+		return false;
+	}
+
+	/* Step2. Parse OCPF files */
+	for (element = oclient->ocpf_files; element->next; element = element->next) {
+		ret = ocpf_parse(element->filename);
+		if (ret == -1) {
+			errno = MAPI_E_INVALID_PARAMETER;
+			return false;
+		}
+	}
+
+	/* Step3. Open destination folder using ocpf API */
+	mapi_object_init(&obj_folder);
+	retval = ocpf_OpenFolder(obj_store, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step4. Create the message */
+	mapi_object_init(&obj_message);
+	retval = CreateMessage(&obj_folder, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step5, Set message recipients */
+	retval = ocpf_set_Recipients(mem_ctx, &obj_message);
+	if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false;
+	errno = MAPI_E_SUCCESS;
+
+	/* Step6. Set message properties */
+	retval = ocpf_set_SPropValue(mem_ctx, &obj_folder, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step7. Set message properties */
+	lpProps = ocpf_get_SPropValue(&cValues);
+
+	retval = SetProps(&obj_message, lpProps, cValues);
+	MAPIFreeBuffer(lpProps);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step8. Save message */
+	retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+
+	return true;
+}
+
+
+static bool openchangeclient_ocpf_dump(TALLOC_CTX *mem_ctx, mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS			retval;
+	int				ret;
+	mapi_object_t			obj_folder;
+	mapi_object_t			obj_message;
+	mapi_id_t			id_tis;
+	const char			*fid_str;
+	uint64_t			fid;
+	uint64_t			mid;
+	const char			*item = NULL;
+	char				*filename = NULL;
+	struct mapi_SPropValue_array	lpProps;
+
+
+	/* retrieve the FID/MID for ocpf_dump parameter */
+	item = oclient->ocpf_dump;
+
+	fid_str = strsep((char **)&item, "/");
+	if (!fid_str || !item) {
+		DEBUG(0, ("    Invalid ID: %s\n", fid_str ? fid_str : "null"));
+		errno = MAPI_E_INVALID_PARAMETER;
+		return false;
+	}
+
+	fid = strtoull(fid_str, NULL, 16);
+	mid = strtoull(item, NULL, 16);
+
+	/* Step 1. search the folder from Top Information Store */
+	mapi_object_init(&obj_folder);
+	retval = GetDefaultFolder(obj_store, &id_tis, olFolderTopInformationStore);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	retval = folder_lookup(mem_ctx, fid, obj_store, id_tis, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 2. search the message */
+	mapi_object_init(&obj_message);
+	retval = message_lookup(mem_ctx, mid, &obj_folder, &obj_message);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 3. retrieve all message properties */
+	retval = GetPropsAll(&obj_message, &lpProps);
+
+	/* Step 4. save the message */
+	ret = ocpf_init();
+
+	filename = talloc_asprintf(mem_ctx, "%"PRIx64".ocpf", mid);
+	DEBUG(0, ("OCPF output file: %s\n", filename));
+
+	ret = ocpf_write_init(filename, fid);
+	talloc_free(filename);
+
+	ret = ocpf_write_auto(&obj_message, &lpProps);
+	if (ret == OCPF_SUCCESS) {
+		ret = ocpf_write_commit();
+	} 
+
+	ret = ocpf_release();
+
+	mapi_object_release(&obj_message);
+	mapi_object_release(&obj_folder);
+
+	return true;
+}
+
+
+static bool openchangeclient_freebusy(mapi_object_t *obj_store, struct oclient *oclient)
+{
+	enum MAPISTATUS			retval;
+	struct SRow			aRow;
+	const char     			*message_name;
+	uint32_t			i;
+	const uint32_t			*publish_start;
+	const uint32_t			*publish_end;
+	const struct LongArray_r       	*busy_months;
+	const struct BinaryArray_r	*busy_events;
+	const struct LongArray_r       	*tentative_months;
+	const struct BinaryArray_r	*tentative_events;
+	const struct LongArray_r       	*oof_months;
+	const struct BinaryArray_r	*oof_events;
+	uint32_t			year;
+	uint32_t			event_year;
+
+	/* Step 1. Retrieve FreeBusy data for the given user */
+	retval = GetUserFreeBusyData(obj_store, oclient->freebusy, &aRow);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	/* Step 2. Dump properties */
+	message_name = (const char *) find_SPropValue_data(&aRow, PR_NORMALIZED_SUBJECT);
+	publish_start = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_START_RANGE);
+	publish_end = (const uint32_t *) find_SPropValue_data(&aRow, PR_FREEBUSY_END_RANGE);
+	busy_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_BUSY_MONTHS);
+	busy_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_BUSY_EVENTS);
+	tentative_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_TENTATIVE_MONTHS);
+	tentative_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_TENTATIVE_EVENTS);
+	oof_months = (const struct LongArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_OOF_MONTHS);
+	oof_events = (const struct BinaryArray_r *) find_SPropValue_data(&aRow, PR_FREEBUSY_OOF_EVENTS);
+
+	year = GetFreeBusyYear(publish_start);
+
+	DEBUG(0, ("FreeBusy (%s):\n", message_name));
+	mapidump_date_SPropValue(aRow.lpProps[1], "* FreeBusy Last Modification Time");
+	mapidump_freebusy_date(*publish_start, "\t* FreeBusy Publishing Start:");
+	mapidump_freebusy_date(*publish_end, "\t *FreeBusy Publishing End:  ");
+
+	if (busy_months && ((*(const uint32_t *) busy_months) != MAPI_E_NOT_FOUND) &&
+	    busy_events && ((*(const uint32_t *) busy_events) != MAPI_E_NOT_FOUND)) {
+		DEBUG(0, ("\t* Busy Events:\n"));
+		for (i = 0; i < busy_months->cValues; i++) {
+			event_year = mapidump_freebusy_year(busy_months->lpl[i], year);
+			DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(busy_months->lpl[i], event_year), event_year)); 
+			mapidump_freebusy_event(&busy_events->lpbin[i], busy_months->lpl[i], event_year, "\t\t\t* ");
+		}
+	}
+
+	if (tentative_months && ((*(const uint32_t *) tentative_months) != MAPI_E_NOT_FOUND) &&
+	    tentative_events && ((*(const uint32_t *) tentative_events) != MAPI_E_NOT_FOUND)) {
+		DEBUG(0, ("\t* Tentative Events:\n"));
+		for (i = 0; i < tentative_months->cValues; i++) {
+			event_year = mapidump_freebusy_year(tentative_months->lpl[i], year);
+			DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(tentative_months->lpl[i], event_year), event_year));
+			mapidump_freebusy_event(&tentative_events->lpbin[i], tentative_months->lpl[i], event_year, "\t\t\t* ");
+		}
+	}
+
+	if (oof_months && ((*(const uint32_t *) oof_months) != MAPI_E_NOT_FOUND) &&
+	    oof_events && ((*(const uint32_t *) oof_events) != MAPI_E_NOT_FOUND)) {
+		DEBUG(0, ("\t* Out Of Office Events:\n"));
+		for (i = 0; i < oof_months->cValues; i++) {
+			event_year = mapidump_freebusy_year(oof_months->lpl[i], year);
+			DEBUG(0, ("\t\t* %s %u:\n", mapidump_freebusy_month(oof_months->lpl[i], event_year), event_year));
+			mapidump_freebusy_event(&oof_events->lpbin[i], oof_months->lpl[i], event_year, "\t\t\t* ");
+		}
+	}
+
+	MAPIFreeBuffer(aRow.lpProps);
+
+	return true;
+}
+
+
+static void list_argument(const char *label, struct oc_element *oc_items)
+{
+	uint32_t	i;
+
+	printf("Use one of the following %s values:\n", label);
+	for (i = 0; oc_items[i].status; i++) {
+		printf("%s\n", oc_items[i].status);
+	}
+}
+
+
+static uint32_t oc_get_argument(const char *name, struct oc_element *oc_items, const char *label)
+{
+	uint32_t	i;
+
+	for (i = 0; oc_items[i].status; i++) {
+		if (!strncasecmp(oc_items[i].status, name, strlen(oc_items[i].status))) {
+			return oc_items[i].index;
+		}
+	}
+	list_argument(label, oc_items);
+	exit (1);
+}
+
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session = NULL;
+	mapi_object_t		obj_store;
+	struct oclient		oclient;
+	poptContext		pc;
+	int			opt;
+	bool			opt_sendmail = false;
+	bool			opt_sendappointment = false;
+	bool			opt_sendcontact = false;
+	bool			opt_sendtask = false;
+	bool			opt_sendnote = false;
+	bool			opt_fetchmail = false;
+	bool			opt_deletemail = false;
+	bool			opt_mailbox = false;
+	bool			opt_dumpdata = false;
+	bool			opt_notifications = false;
+	bool			opt_mkdir = false;
+	bool			opt_rmdir = false;
+	bool			opt_userlist = false;
+	bool			opt_ocpf_syntax = false;
+	bool			opt_ocpf_sender = false;
+	const char		*opt_profdb = NULL;
+	char			*opt_profname = NULL;
+	const char		*opt_password = NULL;
+	const char		*opt_attachments = NULL;
+	const char		*opt_fetchitems = NULL;
+	const char		*opt_html_file = NULL;
+	const char		*opt_mapi_to = NULL;
+	const char		*opt_mapi_cc = NULL;
+	const char		*opt_mapi_bcc = NULL;
+	const char		*opt_debug = NULL;
+
+	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_SENDMAIL, OPT_PASSWORD, OPT_SENDAPPOINTMENT, 
+	      OPT_SENDCONTACT, OPT_SENDTASK, OPT_FETCHMAIL, OPT_STOREMAIL,  OPT_DELETEMAIL, 
+	      OPT_ATTACH, OPT_HTML_INLINE, OPT_HTML_FILE, OPT_MAPI_TO, OPT_MAPI_CC, 
+	      OPT_MAPI_BCC, OPT_MAPI_SUBJECT, OPT_MAPI_BODY, OPT_MAILBOX, 
+	      OPT_FETCHITEMS, OPT_MAPI_LOCATION, OPT_MAPI_STARTDATE, OPT_MAPI_ENDDATE, 
+	      OPT_MAPI_BUSYSTATUS, OPT_NOTIFICATIONS, OPT_DEBUG, OPT_DUMPDATA, 
+	      OPT_MAPI_EMAIL, OPT_MAPI_FULLNAME, OPT_MAPI_CARDNAME,
+	      OPT_MAPI_TASKSTATUS, OPT_MAPI_IMPORTANCE, OPT_MAPI_LABEL, OPT_PF, 
+	      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};
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", NULL },
+		{"pf", 0, POPT_ARG_NONE, NULL, OPT_PF, "access public folders instead of mailbox", 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 },
+		{"sendmail", 'S', POPT_ARG_NONE, NULL, OPT_SENDMAIL, "send a mail", NULL },
+		{"sendappointment", 0, POPT_ARG_NONE, NULL, OPT_SENDAPPOINTMENT, "send an appointment", NULL },
+		{"sendcontact", 0, POPT_ARG_NONE, NULL, OPT_SENDCONTACT, "send a contact", NULL },
+		{"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 },
+		{"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 },
+		{"force", 0, POPT_ARG_NONE, NULL, OPT_FORCE, "force openchangeclient behavior in some circumstances", NULL },
+		{"delete", 0, POPT_ARG_STRING, NULL, OPT_DELETEITEMS, "delete a message given its unique ID", NULL },
+		{"update", 'u', POPT_ARG_STRING, NULL, OPT_UPDATE, "update the specified item", NULL },
+		{"mailbox", 'm', POPT_ARG_NONE, NULL, OPT_MAILBOX, "list mailbox folder summary", NULL },
+		{"deletemail", 'D', POPT_ARG_NONE, NULL, OPT_DELETEMAIL, "delete a mail from user INBOX", NULL },
+		{"attachments", 'A', POPT_ARG_STRING, NULL, OPT_ATTACH, "send a list of attachments", NULL },
+		{"html-inline", 'I', POPT_ARG_STRING, NULL, OPT_HTML_INLINE, "send PR_HTML content", NULL },
+		{"html-file", 'W', POPT_ARG_STRING, NULL, OPT_HTML_FILE, "use HTML file as content", NULL },
+		{"to", 't', POPT_ARG_STRING, NULL, OPT_MAPI_TO, "set the To recipients", NULL },
+		{"cc", 'c', POPT_ARG_STRING, NULL, OPT_MAPI_CC, "set the Cc recipients", NULL },
+		{"bcc", 'b', POPT_ARG_STRING, NULL, OPT_MAPI_BCC, "set the Bcc recipients", NULL },
+		{"subject", 's', POPT_ARG_STRING, NULL, OPT_MAPI_SUBJECT, "set the mail subject", NULL },
+		{"body", 'B', POPT_ARG_STRING, NULL, OPT_MAPI_BODY, "set the mail body", NULL },
+		{"location", 0, POPT_ARG_STRING, NULL, OPT_MAPI_LOCATION, "set the item location", NULL },
+		{"label", 0, POPT_ARG_STRING, NULL, OPT_MAPI_LABEL, "set the event label", NULL },
+		{"dtstart", 0, POPT_ARG_STRING, NULL, OPT_MAPI_STARTDATE, "set the event start date", NULL },
+		{"dtend", 0, POPT_ARG_STRING, NULL, OPT_MAPI_ENDDATE, "set the event end date", NULL },
+		{"busystatus", 0, POPT_ARG_STRING, NULL, OPT_MAPI_BUSYSTATUS, "set the item busy status", NULL },
+		{"taskstatus", 0, POPT_ARG_STRING, NULL, OPT_MAPI_TASKSTATUS, "set the task status", NULL },
+		{"importance", 0, POPT_ARG_STRING, NULL, OPT_MAPI_IMPORTANCE, "Set the item importance", NULL },
+		{"email", 0, POPT_ARG_STRING, NULL, OPT_MAPI_EMAIL, "set the email address", NULL },
+		{"fullname", 0, POPT_ARG_STRING, NULL, OPT_MAPI_FULLNAME, "set the full name", NULL },
+		{"cardname", 0, POPT_ARG_STRING, NULL, OPT_MAPI_CARDNAME, "set a contact card name", NULL },
+		{"color", 0, POPT_ARG_STRING, NULL, OPT_MAPI_COLOR, "set the note color", NULL },
+		{"notifications", 0, POPT_ARG_NONE, NULL, OPT_NOTIFICATIONS, "monitor INBOX newmail notifications", NULL },
+		{"folder", 0, POPT_ARG_STRING, NULL, OPT_FOLDER, "set the folder to use instead of inbox", NULL },
+		{"mkdir", 0, POPT_ARG_NONE, NULL, OPT_MKDIR, "create a folder", NULL },
+		{"rmdir", 0, POPT_ARG_NONE, NULL, OPT_RMDIR, "delete a folder", NULL },
+		{"userlist", 0, POPT_ARG_NONE, NULL, OPT_USERLIST, "list Address Book entries", NULL },
+		{"folder-name", 0, POPT_ARG_STRING, NULL, OPT_FOLDER_NAME, "set the folder name", NULL },
+		{"folder-comment", 0, POPT_ARG_STRING, NULL, OPT_FOLDER_COMMENT, "set the folder comment", NULL },
+		{"debuglevel", 'd', POPT_ARG_STRING, NULL, OPT_DEBUG, "set Debug Level", NULL },
+		{"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data", NULL },
+		{"private", 0, POPT_ARG_NONE, NULL, OPT_MAPI_PRIVATE, "set the private flag on messages", NULL },
+		{"ocpf-file", 0, POPT_ARG_STRING, NULL, OPT_OCPF_FILE, "set OCPF file", NULL },
+		{"ocpf-dump", 0, POPT_ARG_STRING, NULL, OPT_OCPF_DUMP, "dump message into OCPF file", NULL },
+		{"ocpf-syntax", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SYNTAX, "check OCPF files syntax", NULL },
+		{"ocpf-sender", 0, POPT_ARG_NONE, NULL, OPT_OCPF_SENDER, "send message using OCPF files contents", NULL },
+		POPT_OPENCHANGE_VERSION
+		{NULL, 0, 0, NULL, 0, NULL, NULL}
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "openchangeclient");
+
+	init_oclient(&oclient);
+
+	pc = poptGetContext("openchangeclient", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_PF:
+			oclient.pf = true;
+			break;
+		case OPT_FOLDER:
+			oclient.folder = poptGetOptArg(pc);
+			break;
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		case OPT_USERLIST:
+			opt_userlist = true;
+			break;
+		case OPT_MKDIR:
+			opt_mkdir = true;
+			break;
+		case OPT_RMDIR:
+			opt_rmdir = true;
+			break;
+		case OPT_FOLDER_NAME:
+			oclient.folder_name = poptGetOptArg(pc);
+			break;
+		case OPT_FOLDER_COMMENT:
+			oclient.folder_comment = poptGetOptArg(pc);
+			break;
+		case OPT_NOTIFICATIONS:
+			opt_notifications = true;
+			break;
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			opt_profname = talloc_strdup(mem_ctx, poptGetOptArg(pc));
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_MAILBOX:
+			opt_mailbox = true;
+			break;
+		case OPT_FETCHITEMS:
+			opt_fetchitems = poptGetOptArg(pc);
+			break;
+		case OPT_DELETEITEMS:
+			oclient.delete = poptGetOptArg(pc);
+			break;
+		case OPT_FREEBUSY:
+			oclient.freebusy = poptGetOptArg(pc);
+			break;
+		case OPT_UPDATE:
+			oclient.update = poptGetOptArg(pc);
+			break;
+		case OPT_SENDMAIL:
+			opt_sendmail = true;
+			break;
+		case OPT_SENDAPPOINTMENT:
+			opt_sendappointment = true;
+			break;
+		case OPT_SENDCONTACT:
+			opt_sendcontact = true;
+			break;
+		case OPT_SENDTASK:
+			opt_sendtask = true;
+			break;
+		case OPT_SENDNOTE:
+			opt_sendnote = true;
+			break;
+		case OPT_FETCHMAIL:
+			opt_fetchmail = true;
+			break;
+		case OPT_STOREMAIL:
+			oclient.store_folder = poptGetOptArg(pc);
+			break;
+		case OPT_DELETEMAIL:
+			opt_deletemail = true;
+			break;
+		case OPT_ATTACH:
+			opt_attachments = poptGetOptArg(pc);
+			break;
+		case OPT_HTML_INLINE:
+			oclient.pr_html_inline = poptGetOptArg(pc);
+			break;
+		case OPT_HTML_FILE:
+			opt_html_file = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_TO:
+			opt_mapi_to = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_CC:
+			opt_mapi_cc = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_BCC:
+			opt_mapi_bcc = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_SUBJECT:
+			oclient.subject = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_BODY:
+			oclient.pr_body = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_LOCATION:
+			oclient.location = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_STARTDATE:
+			oclient.dtstart = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_ENDDATE:
+			oclient.dtend = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_BUSYSTATUS:
+			oclient.busystatus = oc_get_argument(poptGetOptArg(pc),
+							     oc_busystatus,
+							     "busystatus");
+			break;
+		case OPT_MAPI_LABEL:
+			oclient.label = oc_get_argument(poptGetOptArg(pc),
+							oc_label,
+							"label");
+			break;
+		case OPT_MAPI_IMPORTANCE:
+			oclient.importance = oc_get_argument(poptGetOptArg(pc), 
+							     oc_importance, 
+							     "importance");
+			break;
+		case OPT_MAPI_TASKSTATUS:
+			oclient.taskstatus = oc_get_argument(poptGetOptArg(pc),
+							     oc_taskstatus,
+							     "taskstatus");
+			break;
+		case OPT_MAPI_COLOR:
+			oclient.color = oc_get_argument(poptGetOptArg(pc),
+							oc_color,
+							"color");
+			break;
+		case OPT_MAPI_EMAIL:
+			oclient.email = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_FULLNAME:
+			oclient.full_name = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_CARDNAME:
+			oclient.card_name = poptGetOptArg(pc);
+			break;
+		case OPT_MAPI_PRIVATE:
+			oclient.private = true;
+			break;
+		case OPT_OCPF_FILE:
+		{
+			struct ocpf_file	*element;
+			
+			if (!oclient.ocpf_files) {
+				oclient.ocpf_files = talloc_zero(mem_ctx, struct ocpf_file);
+			}
+			
+			element = talloc_zero(mem_ctx, struct ocpf_file);
+			element->filename = talloc_strdup(mem_ctx, poptGetOptArg(pc));
+			DLIST_ADD(oclient.ocpf_files, element);
+			break;
+		}
+		case OPT_OCPF_SYNTAX:
+			opt_ocpf_syntax = true;
+			break;
+		case OPT_OCPF_SENDER:
+			opt_ocpf_sender = true;
+			break;
+		case OPT_OCPF_DUMP:
+			oclient.ocpf_dump = poptGetOptArg(pc);
+			break;
+		case OPT_FORCE:
+			oclient.force = true;
+			break;
+		}
+	}
+
+	/* Sanity check on options */
+
+	if (!opt_profdb) {
+		opt_profdb = talloc_asprintf(mem_ctx, DEFAULT_PROFDB, getenv("HOME"));
+	}
+
+	if (opt_sendmail && !opt_mapi_to && !opt_mapi_cc && !opt_mapi_bcc) {
+		printf("You need to specify at least one recipient\n");
+		exit (1);
+	}
+
+	if (opt_sendmail && (!oclient.pr_body && !oclient.pr_html_inline && !opt_html_file)) {
+		printf("No body specified (body, html-inline or html-file)\n");
+		exit (1);
+	}
+
+	if ((opt_sendmail && oclient.pf == true && !oclient.folder) ||
+	    (oclient.pf == true && !oclient.folder && !opt_mailbox && !oclient.freebusy)) {
+		printf("--folder option is mandatory\n");
+		exit (1);
+	}
+
+	if (opt_html_file && oclient.pr_body) {
+		printf("PR_BODY and PR_HTML can't be set at the same time\n");
+		exit (1);
+	}
+
+	if (oclient.pr_body && oclient.pr_html_inline) {
+		printf("Inline HTML and PR_BODY content can't be set simulteanously\n");
+		exit (1);
+	}
+
+	if (opt_html_file && oclient.pr_html_inline) {
+		printf("PR_HTML from file and stdin can't be specified at the same time\n");
+		exit (1);
+	}
+	
+	if (opt_html_file) {
+		oclient_read_file(mem_ctx, opt_html_file, &oclient, PR_HTML);
+	}
+
+	if (opt_attachments) {
+		if (oclient_parse_attachments(mem_ctx, opt_attachments, &oclient) == false) {
+			printf("Unable to parse one of the specified attachments\n");
+			exit (1);
+		}
+	}
+
+	if (opt_mkdir && !oclient.folder_name) {
+		printf("mkdir requires --folder-name to be defined\n");
+		exit (1);
+	}
+
+	/* One of the rare options which doesn't require MAPI to get
+	 *   initialized 
+	 */
+	if (opt_ocpf_syntax) {
+		bool ret = openchangeclient_ocpf_syntax(&oclient);
+		mapi_errstr("OCPF Syntax", GetLastError());
+		if (ret != true) {
+			exit(1);
+		}
+		exit (0);
+	}
+	
+	/**
+	 * Initialize MAPI subsystem
+	 */
+
+	retval = MAPIInitialize(opt_profdb);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MAPIInitialize", GetLastError());
+		exit (1);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+	
+	/* If no profile is specified try to load the default one from
+	 * the database 
+	 */
+
+	if (!opt_profname) {
+		retval = GetDefaultProfile(&opt_profname);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			exit (1);
+		}
+	}
+
+	retval = MapiLogonEx(&session, opt_profname, opt_password);
+	talloc_free(opt_profname);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		exit (1);
+	}
+
+	if (opt_userlist) {
+		openchangeclient_userlist(mem_ctx, session);
+		exit (0);
+	}
+
+	/**
+	 * Open Default Message Store
+	 */
+
+	mapi_object_init(&obj_store);
+	if (oclient.pf == true) {
+		retval = OpenPublicFolder(session, &obj_store);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("OpenPublicFolder", GetLastError());
+			exit (1);
+		}
+	} else {
+		retval = OpenMsgStore(session, &obj_store);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("OpenMsgStore", GetLastError());
+			exit (1);
+		}
+	}
+
+	/**
+	 * OCPF sending command
+	 */
+	if (opt_ocpf_sender) {
+		bool ret = openchangeclient_ocpf_sender(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("OCPF Sender", GetLastError());
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	if (oclient.ocpf_dump) {
+		bool ret = openchangeclient_ocpf_dump(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("OCPF Dump", GetLastError());
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	if (opt_fetchitems) {
+		bool ret = openchangeclient_fetchitems(mem_ctx, &obj_store, opt_fetchitems, &oclient);
+		mapi_errstr("fetchitems", GetLastError());
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	if (oclient.delete) {
+		bool ret = openchangeclient_deleteitems(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("deleteitems", GetLastError());
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	if (opt_mailbox) {
+		if (oclient.pf == true) {
+			bool ret = openchangeclient_pf(mem_ctx, &obj_store);
+			mapi_errstr("public folder", GetLastError());
+			if (ret != true) {
+				goto end;
+			}
+		} else {
+			bool ret = openchangeclient_mailbox(mem_ctx, &obj_store);
+			mapi_errstr("mailbox", GetLastError());
+			if (ret != true) {
+				goto end;
+			}
+		}
+	}
+
+	/* MAPI email operations */
+	if (opt_sendmail) {
+		/* recipients management */
+		oclient.mapi_to = get_cmdline_recipients(mem_ctx, opt_mapi_to);
+		oclient.mapi_cc = get_cmdline_recipients(mem_ctx, opt_mapi_cc);
+		oclient.mapi_bcc = get_cmdline_recipients(mem_ctx, opt_mapi_bcc);
+
+		retval = openchangeclient_sendmail(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("sendmail", GetLastError());
+		if (retval != true) {
+			goto end;
+		}
+	}
+
+	if (opt_fetchmail) {
+		retval = openchangeclient_fetchmail(&obj_store, &oclient);
+		mapi_errstr("fetchmail", GetLastError());
+		if (retval != true) {
+			goto end;
+		}
+	}
+
+	if (opt_deletemail) {
+		bool ret = openchangeclient_deletemail(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("deletemail", GetLastError());
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	/* MAPI calendar operations */
+	if (opt_sendappointment) {
+		bool ret;
+		if (!oclient.dtstart && !oclient.update) {
+			printf("You need to specify a start date (e.g: 2007-06-01 22:30:00)\n");
+			goto end;
+		}
+		
+		if (!oclient.dtend && !oclient.update) {
+			printf("Setting default end date\n");
+			oclient.dtend = oclient.dtstart;
+		}
+
+		if (!oclient.update) {
+			ret = openchangeclient_sendappointment(mem_ctx, &obj_store, &oclient);
+			mapi_errstr("sendappointment", GetLastError());
+		} else {
+			ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_APPOINTMENT);
+			mapi_errstr("update appointment", GetLastError());
+		}
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	if (oclient.freebusy) {
+		bool ret = openchangeclient_freebusy(&obj_store, &oclient);
+		mapi_errstr("freebusy", GetLastError());
+
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	/* MAPI contact operations */
+	if (opt_sendcontact) {
+		bool ret;
+		if (!oclient.update) {
+			ret = openchangeclient_sendcontact(mem_ctx, &obj_store, &oclient);
+			mapi_errstr("sendcontact", GetLastError());
+		} else {
+			ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_CONTACT);
+			mapi_errstr("update contact", GetLastError());
+		}
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	/* MAPI task operations */
+	if (opt_sendtask) {
+		bool ret;
+		if (!oclient.dtstart && !oclient.update) {
+			printf("You need to specify a start date (e.g: 2007-06-01 22:30:00)\n");
+			goto end;
+		}
+		
+		if (!oclient.dtend && !oclient.update) {
+			printf("Setting default end date\n");
+			oclient.dtend = oclient.dtstart;
+		}
+
+		if (!oclient.update) {
+			ret = openchangeclient_sendtask(mem_ctx, &obj_store, &oclient);
+			mapi_errstr("sendtask", GetLastError());
+		} else {
+			ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_TASK);
+			mapi_errstr("update task", GetLastError());
+		}
+		if (ret != true) {
+			goto end;
+		}
+	}
+
+	/* MAPI note operations */
+	if (opt_sendnote) {
+		bool ret;
+		if (!oclient.update) {
+			ret = openchangeclient_sendnote(mem_ctx, &obj_store, &oclient);
+			mapi_errstr("sendnote", GetLastError());
+		} else {
+			ret = openchangeclient_updateitem(mem_ctx, &obj_store, &oclient, IPF_STICKYNOTE);
+			mapi_errstr("update note", GetLastError());
+		}
+		if (ret != true) {
+			goto end;
+		}
+	}
+	
+	/* Monitor newmail notifications */
+	if (opt_notifications) {
+		openchangeclient_notifications(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("notifications", GetLastError());
+		if (retval != true) {
+			goto end;
+		}
+	}
+
+	/* Folder operations */
+	if (opt_mkdir) {
+		openchangeclient_mkdir(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("mkdir", GetLastError());
+		if (retval != true) {
+			goto end;
+		}
+	}
+
+	if (opt_rmdir) {
+		openchangeclient_rmdir(mem_ctx, &obj_store, &oclient);
+		mapi_errstr("rmdir", GetLastError());
+		if (retval != true) {
+			goto end;
+		}
+	}
+
+	/* Uninitialize MAPI subsystem */
+end:
+	mapi_object_release(&obj_store);
+
+	MAPIUninitialize();
+
+	talloc_free(mem_ctx);
+
+	return 0;
+}

Added: trunk/openchange/utils/openchangeclient.h
===================================================================
--- trunk/openchange/utils/openchangeclient.h	                        (rev 0)
+++ trunk/openchange/utils/openchangeclient.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,155 @@
+/*
+   Stand-alone MAPI application
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#ifndef __OPENCHANGECLIENT_H__
+#define	__OPENCHANGECLIENT_H__
+
+struct oc_property {
+	struct oc_property	*prev;
+	struct oc_property	*next;
+	uint32_t		ulPropTag;
+	const void		*data;
+	bool			named;
+};
+
+struct ocpf_file {
+	struct ocpf_file	*prev;
+	struct ocpf_file	*next;
+	const char		*filename;
+};
+
+struct attach {
+	const char		*filename;
+	struct Binary_r		bin;
+	int			fd;
+};
+
+struct oclient {
+	struct oc_property	*props;
+	const char     		*update;
+	const char		*delete;
+	const char		*subject;
+	const char		*pr_body;
+	const char		*pr_html_inline;
+	char			**usernames;
+	char			**mapi_to;
+	char			**mapi_cc;
+	char			**mapi_bcc;
+	struct Binary_r		pr_html;
+	struct attach		*attach;
+	uint32_t		attach_num;
+	const char		*store_folder;
+	const char		*location;
+	const char		*dtstart;
+	const char		*dtend;
+	int			busystatus;
+	int			taskstatus;
+	int			label;
+	bool			private;
+	int			importance;
+	int			color;
+	int			width;
+	int			height;
+	const char		*email;
+	const char		*full_name;
+	const char		*card_name;
+	const char		*folder_name;
+	const char		*folder_comment;
+	const char		*freebusy;
+	bool			force;
+	/* PF related options */
+	bool			pf;
+	const char		*folder;
+	/* OCPF related options */
+	struct ocpf_file	*ocpf_files;
+	const char		*ocpf_dump;
+};
+
+struct itemfolder {
+	const uint32_t		olFolder;
+	const char		*container_class;
+};
+
+struct itemfolder	defaultFolders[] = {
+	{olFolderInbox,		"Mail"},
+	{olFolderCalendar,	"Appointment"},
+	{olFolderContacts,	"Contact"},
+	{olFolderTasks,		"Task"},
+	{olFolderNotes,		"Note"},
+	{0 , NULL}
+};
+
+struct oc_element {
+	uint8_t			index;
+	const char		*status;
+};
+
+struct oc_element	oc_busystatus[] = {
+	{BUSY_STATUS_FREE,		"FREE"},
+	{BUSY_STATUS_TENTATIVE,		"TENTATIVE"},
+	{BUSY_STATUS_BUSY,		"BUSY"},
+	{BUSY_STATUS_OUTOFOFFICE,	"OUTOFOFFICE"},
+	{0 , NULL}
+};
+
+struct oc_element	oc_importance[] = {
+	{IMPORTANCE_LOW,	"LOW"},
+	{IMPORTANCE_NORMAL,	"NORMAL"},
+	{IMPORTANCE_HIGH,	"HIGH"},
+	{0, NULL}
+};
+
+struct oc_element	oc_taskstatus[] = {
+	{olTaskNotStarted,	"NOTSTARTED"},
+	{olTaskInProgress,	"PROGRESS"},
+	{olTaskComplete,	"COMPLETED"},
+	{olTaskWaiting,		"WAITING"},
+	{olTaskDeferred,	"DEFERRED"},
+	{0, NULL}
+};
+
+struct oc_element	oc_label[] = {
+	{0,			"NONE"},
+	{1,			"IMPORTANT"},
+	{2,			"BUSINESS"},
+	{3,			"PERSONAL"},
+	{4,			"VACATION"},
+	{5,			"MUST_ATTEND"},
+	{6,			"TRAVEL_REQUIRED"},
+	{7,			"NEEDS_PREPARATION"},
+	{8,			"BIRTHDAY"},
+	{9,			"ANNIVERSARY"},
+	{10,			"PHONE_CALL"},
+	{0, NULL}
+};
+
+struct oc_element	oc_color[] = {
+	{olBlue,		"Blue"},
+	{olGreen,		"Green"},
+	{olPink,		"Pink"},
+	{olYellow,		"Yellow"},
+	{olWhite,		"White"},
+	{0, NULL}
+};
+
+#define	DATE_FORMAT	"%Y-%m-%d %H:%M:%S"
+
+#endif /* !__OPENCHANGECLIENT_H__ */

Added: trunk/openchange/utils/openchangepfadmin.c
===================================================================
--- trunk/openchange/utils/openchangepfadmin.c	                        (rev 0)
+++ trunk/openchange/utils/openchangepfadmin.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,595 @@
+/*
+   Public Folders Administration Tool
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#include <libmapi/libmapi.h>
+#include <libmapiadmin/libmapiadmin.h>
+#include <samba/popt.h>
+#include <param.h>
+
+#include "openchangepfadmin.h"
+#include "openchange-tools.h"
+
+static int32_t get_aclrights(const char *permission)
+{
+	uint32_t	i;
+
+	if (!permission) return -1;
+
+	for (i = 0; aclrights[i].name != NULL; i++) {
+		if (!strcmp(permission, aclrights[i].name)) {
+			return aclrights[i].value;
+		}
+	}
+	return -1;
+}
+
+static void list_aclrights(void)
+{
+	uint32_t	i;
+
+	printf("Valid permissions:\n");
+	for (i = 0; aclrights[i].name != NULL; i++) {
+		printf("\t%s\n", aclrights[i].name);
+	}
+}
+
+static int32_t check_IPF_class(const char *dirclass)
+{
+	uint32_t	i;
+
+	if (!dirclass) return -1;
+
+	for (i = 0; IPF_class[i]; i++) {
+		if (!strcmp(dirclass, IPF_class[i])) {
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static void list_IPF_class(void)
+{
+	uint32_t	i;
+
+	printf("Valid IPF Classes:\n");
+	for (i = 0; IPF_class[i] != NULL; i++) {
+		printf("\t%s\n", IPF_class[i]);
+	}
+}
+
+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;
+	bool			ret;
+	mapi_object_t		obj_folder;
+	mapi_object_t		obj_htable;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		rowset;
+	const char	       	*name;
+	char			*newname;
+	const uint32_t		*child;
+	uint32_t		index;
+	const uint64_t		*fid;
+	int			i;
+
+	mapi_object_init(&obj_folder);
+	retval = OpenFolder(parent, folder_id, &obj_folder);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(&obj_folder, &obj_htable, 0, NULL);
+	if (retval != MAPI_E_SUCCESS) return false;
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x3,
+					  PR_DISPLAY_NAME,
+					  PR_FID,
+					  PR_FOLDER_CHILD_COUNT);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return false;
+	
+	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);
+			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);
+			if (*child) {
+				ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
+				if (ret == false) return ret;
+			}
+			
+		}
+	}
+	return true;
+}
+
+static enum MAPISTATUS openchangepfadmin_getdir(TALLOC_CTX *mem_ctx, 
+						mapi_object_t *obj_container,
+						mapi_object_t *obj_child,
+						const char *folder)
+{
+	enum MAPISTATUS		retval;
+	struct SPropTagArray	*SPropTagArray;
+	struct SRowSet		rowset;
+	mapi_object_t		obj_htable;
+	char			*newname;
+	const char		*name;
+	const uint64_t		*fid;
+	uint32_t		index;
+
+	mapi_object_init(&obj_htable);
+	retval = GetHierarchyTable(obj_container, &obj_htable, 0, NULL);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
+					  PR_DISPLAY_NAME,
+					  PR_FID);
+	retval = SetColumns(&obj_htable, SPropTagArray);
+	MAPIFreeBuffer(SPropTagArray);
+	if (retval != MAPI_E_SUCCESS) return MAPI_E_NOT_FOUND;
+	
+	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);
+
+			newname = utf8tolinux(mem_ctx, name);
+			if (newname && fid && !strcmp(newname, folder)) {
+				retval = OpenFolder(obj_container, *fid, obj_child);
+				MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+				return MAPI_E_SUCCESS;
+			}
+			MAPIFreeBuffer(newname);
+		}
+	}
+
+	errno = MAPI_E_NOT_FOUND;
+	return MAPI_E_NOT_FOUND;
+}
+
+static enum MAPISTATUS openchangepfadmin_mkdir(mapi_object_t *obj_container, 
+					       const char *name, 
+					       const char *comment, 
+					       const char *type)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+	struct SPropValue	props[1];
+	uint32_t		prop_count = 0;
+
+	mapi_object_init(&obj_folder);
+	retval = CreateFolder(obj_container, FOLDER_GENERIC, name, comment, OPEN_IF_EXISTS, &obj_folder);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	if (type) {
+		set_SPropValue_proptag(&props[0], PR_CONTAINER_CLASS, (const void *) type);
+		prop_count++;
+
+		retval = SetProps(&obj_folder, props, prop_count);
+		mapi_object_release(&obj_folder);
+		MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+	}
+	
+	return MAPI_E_SUCCESS;
+}
+
+static enum MAPISTATUS openchangepfadmin_rmdir(TALLOC_CTX *mem_ctx,
+					       mapi_object_t *obj_container,
+					       const char *name)
+{
+	enum MAPISTATUS		retval;
+	mapi_object_t		obj_folder;
+
+	mapi_object_init(&obj_folder);
+
+	retval = openchangepfadmin_getdir(mem_ctx, obj_container, &obj_folder, name);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	retval = EmptyFolder(&obj_folder);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	retval = DeleteFolder(obj_container, mapi_object_get_id(&obj_folder),
+			      DEL_FOLDERS, NULL);
+	MAPI_RETVAL_IF(retval, GetLastError(), NULL);
+
+	mapi_object_release(&obj_folder);
+
+	return MAPI_E_SUCCESS;
+}
+
+int main(int argc, const char *argv[])
+{
+	TALLOC_CTX		*mem_ctx;
+	enum MAPISTATUS		retval;
+	struct mapi_session	*session = NULL;
+	mapi_object_t		obj_store;
+	mapi_object_t		obj_ipm_subtree;
+	mapi_object_t		obj_folder;
+	mapi_id_t		id_pf;
+	poptContext		pc;
+	int			opt;
+	const char		*opt_profdb = NULL;
+	char			*opt_profname = NULL;
+	const char		*opt_password = NULL;
+	const char		*opt_comment = NULL;
+	const char		*opt_dirclass = NULL;
+	const char		*opt_adduser = NULL;
+	const char		*opt_rmuser = NULL;
+	const char		*opt_apassword = NULL;
+	const char		*opt_adesc = NULL;
+	const char		*opt_acomment = NULL;
+	const char		*opt_afullname = NULL;
+	const char		*opt_addright = NULL;
+	bool			opt_rmright = false;
+	const char		*opt_modright = NULL;
+	const char		*opt_folder = NULL;
+	const char		*opt_debug = NULL;
+	const char		*opt_username = NULL;	
+	int32_t			opt_permission = -1;
+	bool			opt_ipm_list = false;
+	bool			opt_mkdir = false;
+	bool			opt_rmdir = false;
+	bool			opt_dumpdata = false;
+
+	enum {OPT_PROFILE_DB=1000, OPT_PROFILE, OPT_PASSWORD, OPT_IPM_LIST, 
+	      OPT_MKDIR, OPT_RMDIR, OPT_COMMENT, OPT_DIRCLASS, OPT_ACL, 
+	      OPT_ADDUSER, OPT_RMUSER, OPT_DEBUG, OPT_APASSWORD, OPT_ADESC, 
+	      OPT_ACOMMENT, OPT_AFULLNAME, OPT_ADDRIGHT, OPT_RMRIGHT, 
+	      OPT_MODRIGHT, OPT_USERNAME, OPT_FOLDER, OPT_DUMPDATA};
+
+	struct poptOption long_options[] = {
+		POPT_AUTOHELP
+		{"database", 'f', POPT_ARG_STRING, NULL, OPT_PROFILE_DB, "set the profile database path", "PATH"},
+		{"profile", 'p', POPT_ARG_STRING, NULL, OPT_PROFILE, "set the profile name", "PROFILE"},
+		{"password", 'P', POPT_ARG_STRING, NULL, OPT_PASSWORD, "set the profile password", "PASSWORD"},
+		{"apassword", 0, POPT_ARG_STRING, NULL, OPT_APASSWORD, "set the account password", "PASSWORD"},
+		{"adesc", 0, POPT_ARG_STRING, NULL, OPT_ADESC, "set the account description", "DESCRIPTION"},
+		{"acomment", 0, POPT_ARG_STRING, NULL, OPT_ACOMMENT, "set the account comment", "COMMENT"},
+		{"afullname", 0, POPT_ARG_STRING, NULL, OPT_AFULLNAME, "set the account full name", "NAME"},
+		{"list",0, POPT_ARG_NONE, NULL, OPT_IPM_LIST, "list IPM subtree directories", NULL},
+		{"mkdir", 0, POPT_ARG_NONE, NULL, OPT_MKDIR, "create a Public Folder directory", NULL},
+		{"rmdir", 0, POPT_ARG_NONE, NULL, OPT_RMDIR, "delete a Public Folder directory", NULL},
+		{"comment", 0, POPT_ARG_STRING, NULL, OPT_COMMENT, "set the folder comment", "COMMENT"},
+		{"dirclass", 0, POPT_ARG_STRING, NULL, OPT_DIRCLASS, "set the folder class", "CLASS"},
+		{"adduser", 0, POPT_ARG_STRING, NULL, OPT_ADDUSER, "add Exchange user", "USERNAME"},
+		{"rmuser", 0, POPT_ARG_STRING, NULL, OPT_RMUSER, "delete Exchange user", "USERNAME"},
+		{"addright", 0, POPT_ARG_STRING, NULL, OPT_ADDRIGHT, "add MAPI permissions to PF folder", "RIGHT"},
+		{"rmright", 0, POPT_ARG_NONE, NULL, OPT_RMRIGHT, "remove MAPI permissions to PF folder", NULL},
+		{"modright", 0, POPT_ARG_STRING, NULL, OPT_MODRIGHT, "modify MAPI permissions to PF folder", "RIGHT"},
+		{"debuglevel", 0, POPT_ARG_STRING, NULL, OPT_DEBUG, "set debug level", "LEVEL"},
+		{"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "Dump the hex data", NULL},
+		{"folder", 0, POPT_ARG_STRING, NULL, OPT_FOLDER, "specify the Public Folder directory", "FOLDER"},
+		{"username", 0, POPT_ARG_STRING, NULL, OPT_USERNAME, "specify the username to use", "USERNAME"},
+		POPT_OPENCHANGE_VERSION
+		{ NULL, 0, POPT_ARG_NONE, NULL, 0, NULL, NULL }
+	};
+
+	mem_ctx = talloc_named(NULL, 0, "openchangepfadmin");
+
+	pc = poptGetContext("openchangepfadmin", argc, argv, long_options, 0);
+
+	while ((opt = poptGetNextOpt(pc)) != -1) {
+		switch (opt) {
+		case OPT_DEBUG:
+			opt_debug = poptGetOptArg(pc);
+			break;
+		case OPT_DUMPDATA:
+			opt_dumpdata = true;
+			break;
+		case OPT_PROFILE_DB:
+			opt_profdb = poptGetOptArg(pc);
+			break;
+		case OPT_PROFILE:
+			opt_profname = talloc_strdup(mem_ctx, poptGetOptArg(pc));
+			break;
+		case OPT_PASSWORD:
+			opt_password = poptGetOptArg(pc);
+			break;
+		case OPT_IPM_LIST:
+			opt_ipm_list = true;
+			break;
+		case OPT_MKDIR:
+			opt_mkdir = true;
+			break;
+		case OPT_RMDIR:
+			opt_rmdir = true;
+			break;
+		case OPT_COMMENT:
+			opt_comment = poptGetOptArg(pc);
+			break;
+		case OPT_DIRCLASS:
+			opt_dirclass = poptGetOptArg(pc);
+			break;
+		case OPT_ADDUSER:
+			opt_adduser = poptGetOptArg(pc);
+			break;
+		case OPT_RMUSER:
+			opt_rmuser = poptGetOptArg(pc);
+			break;
+		case OPT_APASSWORD:
+			opt_apassword = poptGetOptArg(pc);
+			break;
+		case OPT_ADESC:
+			opt_adesc = poptGetOptArg(pc);
+			break;
+		case OPT_ACOMMENT:
+			opt_acomment = poptGetOptArg(pc);
+			break;
+		case OPT_AFULLNAME:
+			opt_afullname = poptGetOptArg(pc);
+			break;
+		case OPT_ADDRIGHT:
+			opt_addright = poptGetOptArg(pc);
+			break;
+		case OPT_RMRIGHT:
+			opt_rmright = true;
+			break;
+		case OPT_MODRIGHT:
+			opt_modright = poptGetOptArg(pc);
+			break;
+		case OPT_FOLDER:
+			opt_folder = poptGetOptArg(pc);
+			break;
+		case OPT_USERNAME:
+			opt_username = poptGetOptArg(pc);
+			break;
+		default:
+			break;
+		};
+	}
+
+	/* Sanity check on options */
+
+	if ((opt_mkdir == true && !opt_folder) || (opt_rmdir == true && !opt_folder) ||
+	    (opt_addright && !opt_folder) || (opt_rmright == true && !opt_folder) || 
+	    (opt_modright && !opt_folder)) {
+		printf("You need to specify a directory with --folder option\n");
+		return (-1);
+	}
+
+	if ((opt_addright && !opt_username) || (opt_rmright == true && !opt_username) ||
+	    (opt_modright && !opt_username)) {
+		printf("You need to specify a username with --username option\n");
+		return (-1);
+	}
+
+	/* dirclass sanity check */
+	if (opt_dirclass) {
+		if (check_IPF_class(opt_dirclass) == -1) {
+			list_IPF_class();
+			return (-1);
+		}
+	}
+
+	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());
+		exit (1);
+	}
+
+	/* debug options */
+	SetMAPIDumpData(opt_dumpdata);
+
+	if (opt_debug) {
+		SetMAPIDebugLevel(atoi(opt_debug));
+	}
+
+	/**
+	 * If no profile is specified, try to load the default one
+	 * from the database
+	 */
+	if (!opt_profname) {
+		retval = GetDefaultProfile(&opt_profname);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("GetDefaultProfile", GetLastError());
+			exit (1);
+		}
+	}
+
+	retval = MapiLogonEx(&session, opt_profname, opt_password);
+	talloc_free(opt_profname);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("MapiLogonEx", GetLastError());
+		exit (1);
+	}
+
+	/**
+	 * User management operations
+	 */
+
+	if (opt_adduser) {
+		struct mapiadmin_ctx	*mapiadmin_ctx;
+
+		mapiadmin_ctx = mapiadmin_init(session);
+		mapiadmin_ctx->username = opt_adduser;
+		mapiadmin_ctx->password = opt_apassword;
+		mapiadmin_ctx->description = opt_adesc;
+		mapiadmin_ctx->comment = opt_acomment;
+		mapiadmin_ctx->fullname = opt_afullname;
+
+		retval = mapiadmin_user_add(mapiadmin_ctx);
+		mapi_errstr("mapiadmin_user_add", GetLastError());
+		if (retval != MAPI_E_SUCCESS) {
+			exit (1);
+		}
+		printf("username: %s\n", mapiadmin_ctx->username);
+		printf("password: %s\n", mapiadmin_ctx->password);
+	}
+
+	if (opt_rmuser) {
+		struct mapiadmin_ctx *mapiadmin_ctx;
+		
+		mapiadmin_ctx = mapiadmin_init(session);
+		mapiadmin_ctx->username = opt_rmuser;
+
+		retval = mapiadmin_user_del(mapiadmin_ctx);
+		mapi_errstr("mapiadmin_user_del", GetLastError());
+	}
+
+	/**
+	 * Open Public Folder Store
+	 */
+
+	mapi_object_init(&obj_store);
+	retval = OpenPublicFolder(session, &obj_store);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenPublicFolder", GetLastError());
+		goto end;
+	}
+
+	/* Open IPM Subtree (All Public Folders) */
+	retval = GetDefaultPublicFolder(&obj_store, &id_pf, olFolderPublicIPMSubtree);
+	if (retval != MAPI_E_SUCCESS) {
+		goto end;
+	}
+
+	mapi_object_init(&obj_ipm_subtree);
+	retval = OpenFolder(&obj_store, id_pf, &obj_ipm_subtree);
+	if (retval != MAPI_E_SUCCESS) {
+		mapi_errstr("OpenFolder", GetLastError());
+		goto end;
+	}
+
+	/* create directory */
+	if (opt_mkdir == true) {
+		retval = openchangepfadmin_mkdir(&obj_ipm_subtree, opt_folder, opt_comment, opt_dirclass);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("mkdir", GetLastError());
+			goto end;
+		}
+	}
+
+	/* remove directory */
+	if (opt_rmdir == true) {
+		retval = openchangepfadmin_rmdir(mem_ctx, &obj_ipm_subtree, opt_folder);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("rmdir", GetLastError());
+			goto end;
+		}
+		
+	}
+
+	/* add permissions */
+	if (opt_addright) {
+		if ((opt_permission = get_aclrights(opt_addright)) == -1) {
+			printf("Invalid permission\n");
+			list_aclrights();
+			goto end;
+		} else {
+			mapi_object_init(&obj_folder);
+			retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder);
+			if (retval != MAPI_E_SUCCESS) {
+				printf("Invalid directory\n");
+				goto end;
+			}
+			retval = AddUserPermission(&obj_folder, opt_username, opt_permission);
+			if (retval != MAPI_E_SUCCESS) {
+				mapi_errstr("AddUserPermission", GetLastError());
+				mapi_object_release(&obj_folder);
+				goto end;
+			}
+			mapi_object_release(&obj_folder);
+		}
+		printf("Permission %s added for %s on folder %s\n", opt_addright, opt_username, opt_folder);
+	}
+
+	/* remove permissions */
+	if (opt_rmright == true) {
+		mapi_object_init(&obj_folder);
+		retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder);
+		if (retval != MAPI_E_SUCCESS) {
+			printf("Invalid directory\n");
+			goto end;
+		}
+		retval = RemoveUserPermission(&obj_folder, opt_username);
+		if (retval != MAPI_E_SUCCESS) {
+			mapi_errstr("RemoveUserPermission", GetLastError());
+			mapi_object_release(&obj_folder);
+			goto end;
+		}
+		mapi_object_release(&obj_folder);
+		printf("Permission removed for %s on folder %s\n", opt_username, opt_folder);
+	}
+
+	/* modify permissions */
+	if (opt_modright) {
+		opt_permission = get_aclrights(opt_modright);
+		if (opt_permission == -1) {
+			printf("Invalid permission\n");
+			list_aclrights();
+			goto end;
+		} else {
+			mapi_object_init(&obj_folder);
+			retval = openchangepfadmin_getdir(mem_ctx, &obj_ipm_subtree, &obj_folder, opt_folder);
+			if (retval != MAPI_E_SUCCESS) {
+				printf("Invalid directory\n");
+				goto end;
+			}
+			retval = ModifyUserPermission(&obj_folder, opt_username, opt_permission);
+			if (retval != MAPI_E_SUCCESS) {
+				mapi_errstr("ModifyUserPermission", GetLastError());
+				mapi_object_release(&obj_folder);
+				goto end;
+			}
+			mapi_object_release(&obj_folder);
+		}
+		printf("Permission changed to %s for %s on folder %s\n", opt_modright, opt_username, opt_folder);
+	}
+
+	/* list directories */
+	if (opt_ipm_list == true) {
+		printf("+ All Public Folders\n");
+		get_child_folders_pf(mem_ctx, &obj_ipm_subtree, id_pf, 0);
+	}
+
+	/**
+	 * Uninitialize MAPI subsystem
+	 */
+end:
+	mapi_object_release(&obj_store);
+
+	MAPIUninitialize();
+	talloc_free(mem_ctx);
+	return 0;
+}

Added: trunk/openchange/utils/openchangepfadmin.h
===================================================================
--- trunk/openchange/utils/openchangepfadmin.h	                        (rev 0)
+++ trunk/openchange/utils/openchangepfadmin.h	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,65 @@
+/*
+   Public Folders Administration Tool
+
+   OpenChange Project
+
+   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/>.
+*/
+
+#ifndef __OPENCHANGEPFADMIN_H__
+#define	__OPENCHANGEPFADMIN_H__
+
+#define	DEFAULT_PROFDB	"%s/.openchange/profiles.ldb"
+
+struct aclrights {
+	const char	*name;
+	uint32_t	value;
+};
+
+const struct aclrights	aclrights[] = {
+	{"RightsNone",			0x00000000},
+        {"RightsReadItems",		0x00000001},
+        {"RightsCreateItems",		0x00000002},
+        {"RightsEditOwn",		0x00000008},
+        {"RightsDeleteOwn",		0x00000010},
+        {"RightsEditAll",		0x00000020},
+        {"RightsDeleteAll",		0x00000040},
+        {"RightsCreateSubfolders",	0x00000080},
+        {"RightsFolderOwner",		0x00000100},
+        {"RightsFolderContact",		0x00000200},
+        {"RoleNone",			0x00000400},
+        {"RoleReviewer",		0x00000401},
+        {"RoleContributor",		0x00000402},
+        {"RoleNoneditingAuthor",	0x00000413},
+        {"RoleAuthor",			0x0000041B},
+        {"RoleEditor",			0x0000047B},
+        {"RolePublishAuthor",		0x0000049B},
+        {"RolePublishEditor",		0x000004FB},
+        {"RightsAll",			0x000005FB},
+        {"RoleOwner",			0x000007FB},
+	{NULL, 0}
+};
+
+const char * IPF_class[] = { IPF_APPOINTMENT, 
+			     IPF_CONTACT, 
+			     IPF_JOURNAL, 
+			     IPF_NOTE, 
+			     IPF_STICKYNOTE, 
+			     IPF_TASK, 
+			     IPF_POST, 
+			     NULL};
+
+#endif /* __OPENCHANGEPFADMIN_H__ */

Added: trunk/openchange/utils/schemaIDGUID.c
===================================================================
--- trunk/openchange/utils/schemaIDGUID.c	                        (rev 0)
+++ trunk/openchange/utils/schemaIDGUID.c	2009-04-14 14:39:21 UTC (rev 2698)
@@ -0,0 +1,50 @@
+/*
+   MAPI Implementation
+
+   OpenChange Project
+
+   Copyright (C) Julien Kerihuel 2006
+
+   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 <ldb.h>
+
+static void usage(void)
+{
+	printf("schemaIDGUID <base64 string>\n");
+	exit(0);
+}
+
+int main(int argc, char *argv[])
+{
+	TALLOC_CTX	*mem_ctx;
+	DATA_BLOB	blob;
+	struct GUID	*guid;
+	char		*schemaIDGUID;
+
+	if (argc != 2) {
+		usage();
+	}
+
+	mem_ctx = talloc_named(NULL, 0, "SchemaIDGUID");
+
+	blob = data_blob_talloc(mem_ctx, argv[1], strlen(argv[1])+1);
+	blob.length = ldb_base64_decode((char *)blob.data);
+	guid = (struct GUID *) blob.data;
+	schemaIDGUID = GUID_string(mem_ctx, guid);
+	printf("%s\n", schemaIDGUID);
+	return (0);
+}




More information about the Pkg-samba-maint mailing list